Как масштабировать клиенты websocket с помощью очередей

#node.js #websocket #azure-web-app-service #message-queue

#node.js #websocket #azure-web-app-service #очередь сообщений

Вопрос:

Я работаю со сторонним API, который предоставляет информацию об отеле; одним из вариантов, который он предоставляет, является уведомление websocket, когда кто-то бронирует, поэтому, создавая клиента и получая широковещательное сообщение, я знаю, когда перейти к конечным точкам API и получить всю информацию о бронировании. На данный момент я просто хочу записывать сообщения в очередь. Я написал простой node.js веб-приложение, использующее библиотеку ‘ws’, которая принимает сообщения websocket и записывает их в очередь хранилища Azure:

 // Import the libraries I need for websockets, Azure storage queues and some config files
const env = require('dotenv').config();
const WebSocket = require('ws');
const config = require('./config');
const { QueueClient } = require('@azure/storage-queue');

var queueName, createQueueResponse, fullUrl, sendMessageResponse;

let connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING;

// Get wss://clientsite URL and query string parameters from a config file
const { url: { site, myToken, hotelToken } } = config;

// Create a name for the queue. 
queueName = process.env.HOTEL_ID;

// Instantiate a QueueClient which will be used to create and manipulate a queue
var queueClient = new QueueClient(connectionString, queueName);

// Create the queue
(async () => {
     createQueueResponse = await queueClient.createIfNotExists();
     if (createQueueResponse.requestId) {
         console.log("Queue created, requestId =", createQueueResponse.requestId);
     }
     else {
         console.log("Queue not created");
     }
 })();

//Create the websocket
 fullUrl = `${site}?ClientToken=${myToken}amp;AccessToken=${hotelToken}`;
 var ws = new WebSocket(fullUrl);

//Write the received messages to the queue   
ws.on('message', async function incoming(data) {
     if (data) {
         sendMessageResponse = await queueClient.sendMessage(data);
         console.log("Messages added, requestId:", sendMessageResponse.requestId);
     }
});

ws.on('error', function error(error) {
     console.log("Error: "   error.message);
});
  

Но я хочу иметь возможность прослушивать сообщения от потенциально сотен веб-сокетов и отслеживать, какой источник был каким, возможно, путем привязки каждого веб-сокета к другой очереди. Но когда я пытаюсь это сделать, перебирая список URL-адресов websocket, создавая очередь для каждого из них, все они в конечном итоге используют конечную очередь, которую я создал.

Каков правильный способ масштабируемой привязки клиента websocket к очереди? Я изучал использование SignalR, но все примеры предназначены для создания чата!

Ответ №1:

Веб-приложения Azure установили ограничения на обслуживание для каждого SKU, которые включают ограничения на количество websocket и памяти. Вы можете увидеть их здесь. Несмотря на то, что SKU стандартного уровня имеют неограниченное количество веб-сокетов, в определенный момент вы столкнетесь с ограничениями памяти. Потенциально вы можете масштабироваться дальше, предоставляя несколько экземпляров веб-приложений, до 10 для стандартного уровня.

Поиграв с этой проблемой в течение четырех лет или около того, мы отказались от самостоятельного размещения websocket и перешли на службу SignalR. Вы можете подключать сотни тысяч клиентов с помощью службы SignalR. Я настоятельно рекомендую использовать его, чтобы избавить себя от кучи головной боли.

Комментарии:

1. Спасибо, Роб, но как мне использовать SignalR в качестве клиента websocket, можете ли вы указать мне на какие-либо примеры? Мне нужно работать с третьей стороной, которая публикует сообщения с использованием websockets. Это важнее, чем то, используем ли мы Azure или нет.