Ad

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

I recently made a switch in our test environment from an Azure App Services Windows to Linux. Everything is working as it was previously except our socket connections. There seems to be a lot of outdated information regarding the Linux App Service, and the documentation is lackluster. However, according to these release notes, support is available for web sockets on Azure App Service Linux.

In some of Azure App Service for Linux documentation, it states that you must disable perMessageDeflate in order to get Web Sockets to work with Linux App Service and NodeJS. I believe I have done that in my HapiJS server code below. I have verified with a console.log(io) that the setting perMessageDeflate seems to be set to false correctly.

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
    };
  };
};

When I open the network page of Chrome's console while using my web client, I get a 101 response code from the server. I console.log connects/disconnects from the socket.io's client's callbacks. I can see it continually connects/disconnects despite getting an acknowledgement from the server (101 response). The state of the connections says 'stalled' in the console. I seem to be subscribing to a particular route okay as the callback fires.

I have made no other code changes since switching from Azure App Services Windows despite the configuration below to add perMessageDeflate and origins for testing socket.io docs. I'm thinking something is going wrong during the handshake or authentication.

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

I also added perMessageDeflate to my client side code. It didn't make a difference.

const client = new io(URL, {
  query: 'token=' + jwt,
  perMessageDeflate: false,
  transports: ['websocket'],
  upgrade: false
});

What else am I missing? How do I enable web sockets on Azure App Service Linux? I checked for a configuration setting like with Windows. There does not appear to be a setting for that - as it seems web sockets are enabled by default. I have verified in the logs that the web server is not continually restarting causing the connect/disconnects.

Ad

Answer

tl;dr

Disable CORS and AUTH through the portal on Linux App Service.

Disable CORS by going to your App Service, select CORS on the left side menu bar under API, remove any entries in there. By removing all entries, you are disabling Azure's CORS implementation for App Service.

Disable AUTH by going to Authentication/Authorization under the Settings heading on the left side menu bar. Click the switch to 'off'.

This will allow Web Sockets to work as expected with Linux App Service. However, you need to configure CORS and AUTH with your web server framework now.

Long Form

After hearing back from my MS support rep, she confirmed that when CORS or AUTH is enabled it breaks Linux App Service's sockets implementations. The Linux App Service CORS and AUTH features are not implemented yet by Microsoft.

In order to use Linux App Service and utilize the CORS or AUTH features, you simply can't because it's not implemented. The official recommended solution is to switch to Windows App Service.

Despite what the Azure documentation states, perMessageDeflate is not required for WebSockets to work with socket.io. I have it working without it correctly. To configure CORS for the App Service from the portal, it's the same as you would for Windows. You can go to your App Service in the portal, select CORS on the left side menu under API. Delete any entries in there to disable App Service's CORS feature. I had only one entry (*) that I was using during testing since I had CORS configured correctly with my Windows App Service before switching to Linux.

If you remove all entries, you should have functioning Web Sockets without CORS. However, keep in mind, you should configure CORS with your web server framework for security reasons. If it's express with socket.io, you'll have to do something like this. Most web frameworks follow a similar paradigm by specifying it on your server object as an option.

There some more information regarding this in this thread on GitHub.

Ad
source: stackoverflow.com
Ad