Socket.io/Hapi 无法运行 Azure 应用服务 (Linux)

Socket.io/Hapi Not Working Azure App Service (Linux)

我最近在我们的测试环境中从 Azure App Services Windows 切换到 Linux。除了我们的套接字连接外,一切都像以前一样工作。似乎有很多关于 Linux App Service 的过时信息,而且文档也很乏味。但是,根据 these release notes,Azure 应用服务 Linux.

支持 Web 套接字

在某些 Azure App Service for Linux documentation 中,它指出您必须禁用 perMessageDeflate 才能使 Web 套接字与 Linux 应用服务和 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
    };
  };
};

当我在使用网络客户端时打开 Chrome 控制台的网络页面时,我从服务器收到 101 响应代码。我 console.log connects/disconnects 来自 socket.io 的客户回调。尽管得到了服务器的确认(101 响应),我仍然可以持续 connects/disconnects 看到它。连接状态在控制台中显示 'stalled'。当回调触发时,我似乎订阅了一条特定的路线。

自从从 Azure 应用服务 Windows 切换后,我没有进行任何其他代码更改,尽管下面的配置添加了 perMessageDeflateorigins 用于测试 socket.io docs。我认为握手或身份验证过程中出现问题。

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 应用服务 Linux 上启用 Web 套接字?我检查了与 Windows 类似的配置设置。似乎没有为此设置 - 因为默认情况下似乎启用了网络套接字。我已在日志中验证 Web 服务器没有持续重启导致 connect/disconnects.

如果身份验证关闭,您的 WebSockets 是否工作?

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

我认为这是由于 EasyAuth 代理实施不当造成的,MS 认为这是一个很难解决的问题。

tl;博士

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

通过转到您的应用程序服务禁用 CORS,select API 下左侧菜单栏中的 CORS,删除其中的所有条目。通过删除所有条目,您将禁用应用服务的 Azure CORS 实现。

转到左侧菜单栏“设置”标题下的 Authentication/Authorization 以禁用 AUTH。点击切换到'off'.

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

长格式

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

要使用 Linux 应用服务并利用 CORS 或 AUTH 功能,您根本做不到,因为它没有实现。官方推荐的解决方案是切换到WindowsApp Service。

尽管 Azure 文档指出,perMessageDeflate 并不是 WebSockets 与 socket.io 一起工作所必需的。我让它在没有它的情况下正常工作。要从门户为应用服务配置 CORS,与 Windows 相同。您可以在 API 下左侧菜单中的 select CORS 门户中转到您的应用服务。删除其中的任何条目以禁用应用服务的 CORS 功能。我只有一个条目 (*) 在测试期间使用,因为在切换到 Linux.

之前,我已使用我的 Windows 应用服务正确配置了 CORS

如果您删除所有条目,您应该拥有没有 CORS 的正常运行的 Web 套接字。但是,请记住,出于安全原因,您应该使用 Web 服务器框架配置 CORS。如果它用 socket.io 表达,你将不得不做类似 this 的事情。大多数 Web 框架都遵循类似的范例,在您的服务器上指定它 object 作为一个选项。

在 GitHub 上的 this thread 中有一些关于此的更多信息。

我在 Node.js 上遇到了类似的问题。 socket.io 在 azure cdn 托管域上 Linux 上的应用程序服务 运行 失败。 能够通过使用自定义域和 TLS/SSL 设置 link 我的域到应用程序服务 url 而不是在应用程序服务上设置 azure cdn 来缓解这种情况。