Azure App Service Blocking WebSocket Requests

Đào Hùng 5 Reputation points
2024-11-03T13:46:41.7666667+00:00

I am trying to deploy a WebSocket for my application on Azure App Service.

My application uses Next.js 14 with the App Router, and I have built a separate server to handle upgrade requests.

// server.ts
// run server by
// `tsx server.ts`

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

async function startServer() {
  try {
    await app.prepare();

    const server = createServer((req, res) => {
      const parsedUrl = parse(req.url!, true);
      handle(req, res, parsedUrl);
    });

    wsHandler.createWebSocketServer();

    if (!wsHandler.wss) {
      throw new Error('Can not create WebSocket server');
    }

    // Xử lý WebSocket
    server.on('upgrade', (request, socket, head) => {
      console.log('Upgrade request received:', {
        url: request.url,
        time: new Date().toISOString(),
      });
      const parsedUrl = parse(request.url!, true);

      if (
        ['/_next/webpack-hmr', '/api/xxx'].includes(parsedUrl.pathname || '')
      ) {
        if (parsedUrl.pathname === '/api/xxx') {
          wsHandler.wss?.handleUpgrade(request, socket, head, (ws) => {
            wsHandler.wss?.emit('connection', ws, request);
          });
        }
      } else {
        socket.destroy();
      }
    });

    const PORT = process.env.PORT || 3000;
    server.listen(PORT, () => {
      console.log(`> Server running at http://localhost:${PORT}`);
    });
  } catch (err) {
    console.error('Error init server:', err);
    process.exit(1);
  }
}

startServer();

Everything worked fine locally, but it crashes when deploying to Azure App Service. Debugging concluded that the request did not reach the server running in Azure App Service, indicating that the request was blocked somewhere.

Here is the information about my Azure App Service settings:

  • Operating System: Linux
  • Node.js Version: 20
  • Service Plan: Premium v3 (P0v3)
  • Inbound Traffic Configuration: Public network access enabled with no access restrictions
  • App Assigned Address: Not configured
  • Private Endpoints: 0 private endpoints
  • Optional Inbound Services: Azure Front Door: View details (it seems not set because clicking redirects to the create page)

The website still works fine with the server.ts file, only the websocket request is not received and fails

Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
8,096 questions
Azure Startups
Azure Startups
Azure: A cloud computing platform and infrastructure for building, deploying and managing applications and services through a worldwide network of Microsoft-managed datacenters.Startups: Companies that are in their initial stages of business and typically developing a business model and seeking financing.
484 questions
{count} votes

2 answers

Sort by: Most helpful
  1. ajkuma 27,851 Reputation points Microsoft Employee
    2024-11-04T05:41:21.6433333+00:00

    ARR (Application Request Routing) affinity is a feature within Azure App Service that enables "sticky sessions" by ensuring that subsequent requests from a client are consistently routed to the same instance of a web application. While this can be advantageous in certain scenarios where session consistency is critical, it's important to carefully weigh the potential drawbacks before implementing ARR affinity. Article by one of our colleague.

    As a test, for web sockets in Node.js application, disable perMessageDeflate in your server-side Node.js code.nExample, if you are using socket.io, use the following code:

    const io = require('socket.io')(server,{  
      perMessageDeflate :false  
    });  
    
    
    

    If you haven't done, enable and review logs to fetch more details about the issue: #enable-application-logging-linuxcontainer. Checkout the log directory/location information - Access log files.


  2. Đào Hùng 5 Reputation points
    2024-12-26T07:04:35.4866667+00:00

    After a long time of support and discussion, I and Azure support staff have come to a conclusion for this issue.

    To use websocket, you need to use a custom domain, websocket will not work on the default domain of the app service


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.