提问者:小点点

Socket.io/Hapi无法正常工作的Azure应用服务(Linux)


我最近在我们的测试环境中从Azure App Services Windows切换到了Linux。除了我们的套接字连接之外,一切都像以前一样工作。关于Linux应用程序服务,似乎有很多过时的信息,而且文档也乏善可陈。然而,根据这些发行说明,Azure App Service Linux上的web套接字支持。

在某些适用于 Linux 的 Azure 应用服务文档中,它指出必须禁用 perMessageDeflate 才能使 Web 套接字与 Linux 应用服务和 NodeJS 配合使用。我相信我已经在下面的HapiJS服务器代码中做到了这一点。我已经通过控制台.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
    };
  };
};

当我使用我的网络客户端打开Chrome控制台的网络页面时,我从服务器获得了101响应代码。I console.log连接/断开socket.io的客户端回调。我可以看到它不断地连接/断开,尽管得到了服务器的确认(101响应)。控制台中的连接状态显示为“已停止”。当回调触发时,我似乎订阅了一个特定的路由。

自从从Azure App Services Windows切换以来,我没有做过其他代码更改,尽管下面的配置是为测试socket.io文档添加perMessageDeflateorigins。我想在握手或身份验证过程中出现了问题。

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服务器没有持续重新启动导致连接/断开连接。


共3个答案

匿名用户

如果身份验证关闭,您的WebSockets还能工作吗?

我只有在启用身份验证功能时才会遇到使用Linux应用程序的WebSocket问题。

我认为这是由于EasyAuth代理的实现很差,并且它被认为是MS很难解决的问题。

匿名用户

通过应用服务上的门户禁用LinuxCORS和AUTH。

通过转到应用服务来禁用 CORS,在左侧菜单栏的“API”下选择“CORS”,删除其中的任何条目。通过删除所有条目,你将禁用 Azure 的应用服务的 CORS 实现。

通过转到左侧菜单栏上“设置”标题下的“身份验证/授权”来禁用身份验证。单击开关以“关闭”。

这将允许 Web 套接字在 Linux 应用服务中按预期工作。但是,您现在需要使用 Web 服务器框架配置 CORS 和 AUTH。

在收到我的 MS 支持代表的回复后,她确认启用 CORS 或 AUTH 会破坏 Linux 应用服务的套接字实现。Linux App Service CORS 和 AUTH 功能尚未由 Microsoft 实现。

为了使用Linux应用服务和利用CORS或认证功能,你根本不能,因为它没有实现。官方推荐的解决方案是切换到Windows App服务。

无论Azure留档状态如何,WebSocket都不需要使用perMessageDeflatesocket.io.我让它在没有它的情况下正常工作。要从门户为应用服务配置CORS,它与Windows相同。您可以在门户中转到您的应用服务,在API下的左侧菜单中选择CORS。删除其中的任何条目以禁用应用服务的CORS功能。我在测试期间只使用了一个条目(*),因为在切换到Linux之前,我的Windows应用服务正确配置了CORS。

如果删除了所有条目,则应该可以使用没有CORS的Web套接字。但是,请记住,出于安全原因,您应该使用web服务器框架配置CORS。如果它是用socket.io表达的,你就必须这样做。大多数web框架都遵循类似的范例,将其指定在服务器对象上作为选项。

在 GitHub 上的此线程中有更多关于此内容的信息。

匿名用户

我在 Node 上遇到了类似的问题。socket.io 在 Azure CDN 托管域上的 Linux 上运行的应用服务上失败。能够通过使用自定义域和 TLS/SSL 设置将我的域链接到应用服务 URL,而不是在应用服务上设置 Azure CDN,来缓解此问题。