我最近在我们的测试环境中从Azure应用服务Windows切换到了Linux。除了我们的套接字连接之外,一切都像以前一样工作。关于Linux应用程序服务似乎有很多过时的信息,文档也很平淡。然而,根据these release notes的说法,Azure App Service Linux上提供了对web套接字的支持。
在一些Azure App Service for Linux documentation中,它规定您必须禁用perMessageDeflate才能使Web与Linux App Service和NodeJS一起工作。我相信我已经在下面的HapiJS服务器代码中做到了这一点。我已经通过console.log(io)验证了设置perMessageDeflate似乎正确地设置为false。
import Server from 'socket.io';
import socketioJwt from 'socketio-jwt';
const myHapiJSPlugin = {
name: 'myPluginName',
version: '2.0.0',
register: function (server, options) {
const io = new Server(server.listener, {
perMessageDeflate: false,
transports: ['websocket'],
origins: '*:*'
});
io.use(socketioJwt.authorize({
secret: JWT_SECRET_KEY,
handshake: true
}));
io.on('connection', socket => {
console.log(io);
// more code here
};
};
};当我使用web客户端打开Chrome控制台的网络页面时,我从服务器得到一个101响应码。I console.log与Socket.IO的客户端回调连接/断开连接。尽管收到了来自服务器的确认(101响应),我仍然可以看到它不断地连接/断开。控制台中的连接状态显示为“已停止”。当回调触发时,我似乎订阅了一条特定的路由。
自从从Azure App Services Windows切换以来,我没有进行任何其他代码更改,尽管进行了以下配置,以添加用于测试socket.io docs的perMessageDeflate和origins。我认为在握手或身份验证过程中出现了一些问题。
Status Code: 101 Switching Protocols
Access-Control-Allow-Origin: *
Connection: Upgrade
Date: Tue, 01 Oct 2019 18:04:57 GMT
Sec-WebSocket-Accept: <HASH>
Server: Kestrel
Upgrade: websocket我还在客户端代码中添加了perMessageDeflate。这并没有什么不同。
const client = new io(URL, {
query: 'token=' + jwt,
perMessageDeflate: false,
transports: ['websocket'],
upgrade: false
});我还漏掉了什么?如何在Azure App Service Linux上启用web套接字?我检查了Windows的配置设置。似乎没有这样的设置-因为似乎默认情况下web套接字是启用的。我已在日志中验证web服务器未持续重新启动,从而导致连接/断开。
发布于 2019-10-05 00:42:17
tl;dr
通过Linux应用程序服务上的门户禁用CORS和身份验证。
通过转到您的应用程序服务来禁用CORS,选择API下左侧菜单栏上的CORS,删除其中的所有条目。通过删除所有条目,您将禁用Azure的应用程序服务的CORS实现。
通过转到左侧菜单栏的Settings标题下的Authentication/Authorization禁用AUTH。单击切换到“off”。
这将允许Web套接字在Linux应用程序服务中按预期工作。但是,您现在需要使用您的web服务器框架配置CORS和AUTH。
长格式
在听到我的MS支持代表的反馈后,她确认当CORS或AUTH被启用时,它会破坏Linux应用程序服务的套接字实现。Linux应用程序服务CORS和身份验证功能尚未由Microsoft实现。
为了使用Linux应用程序服务并利用CORS或AUTH特性,您根本不能使用它,因为它没有实现。官方推荐的解决方案是切换到Windows App Service。
不管Azure文档说明了什么,WebSockets与socket.io一起工作并不需要perMessageDeflate。我让它在没有它的情况下正常工作。要从门户为App Service配置CORS,与为Windows配置CORS相同。您可以在门户中进入您的App Service,在API下的左侧菜单中选择CORS。删除其中的所有条目以禁用App Service的CORS功能。我在测试期间只使用了一个条目(*),因为在切换到Linux之前,我已经用我的Windows App Service正确配置了CORS。
如果你删除了所有的条目,你应该可以在没有CORS的情况下运行Web Socket。但是,请记住,出于安全原因,您应该使用web服务器框架配置CORS。如果它是用socket.io表示的,那么您必须执行类似this的操作。大多数web框架都遵循类似的范例,在服务器对象上将其指定为一个选项。
在GitHub上的this thread中有更多关于这方面的信息。
发布于 2019-10-04 11:27:44
如果身份验证已关闭,您的WebSockets是否正常工作?
当我启用身份验证功能时,只有在使用Linux应用程序时才会遇到WebSockets的问题。
我认为这是由于EasyAuth代理的糟糕实现造成的,这被认为是MS很难解决的问题。
发布于 2019-12-12 17:20:52
我在Node上也遇到过类似的问题。在azure cdn托管域上运行的应用程序服务上,socket.io出现故障。我通过使用自定义域和TLS/SSL设置将我的域链接到应用服务url,而不是在应用服务上设置azure cdn,从而缓解了这一问题。
https://stackoverflow.com/questions/58190387
复制相似问题