Связь между Socket.IO и HapiJS

У нас есть сервер REST с HapiJS и сервер Websockets с Socket.IO (оба работают на одном сервере, но на разных портах). Я хочу уведомить сервер Websockets с сервера HapiJS на отправку события с некоторыми данными конкретному клиенту.

Сервер сокетов работает на порту 8081, а REST - на 8080.

Идея заключается в том, что клиент выполняет действие (запрос POST), которое регистрируется в таблице "История действий". Это действие касается других пользователей, поэтому они должны быть уведомлены, когда это происходит в режиме реального времени. Вот почему другие пользователи прослушивают соединение через веб-сокет.

Как я могу сказать серверу сокетов отправить событие определенному клиенту, и это должно быть сделано с сервера REST?

Я думал на 3 пути на данный момент:

  1. Отдельные серверы для сокетов и отдыха и общения с использованием RabbitMQ
  2. Я пытался реализовать Socket.IO-Emitter, но для этого требуется база данных Redis (я до сих пор не знаю, почему). Когда я пытаюсь подключиться с помощью эмиттера из обработчика маршрута HapiJS к сокету, я получаю:

      export function* postRefreshEvent(userId) {
        var connection = require('socket.io-emitter')({ host: '127.0.0.1', port: 8081 });
        connection.in('UserHistory').emit('refresh', userId); 
        return {statusCode: OK}
    
      }        
    
    Error: Ready check failed: Redis connection gone from end event.
    

    на RedisClient.on_info_cmd

Обновление не выполняется на сервере Socket. Я просто не вижу журнал.

  1. Создайте специальное событие и используйте обычный клиент socket.io для подключения от hapijs к websockets и создания нового события.

Образец ГИСТ.

Вы выяснили что-то подобное? Я ценю любую помощь!

2 ответа

Решение

Вы можете просто использовать обычный старый EventEmitter для связи между socket.io и хапи-частями вашей кодовой базы. Вот пример, который работает и иллюстрирует, как вы можете сделать это:

var Hapi = require('hapi');

// Make an event emitter for managing communication
// between hapi and socket.io code

var EventEmitter = require('events');
var notifier = new EventEmitter();

// Setup API + WS server with hapi

var server = new Hapi.Server();
server.register(require('inert'), function () {});

server.connection({ port: 4000, labels: ['api'] });
server.connection({ port: 4001, labels: ['ws'] });

var apiServer = server.select('api');
var wsServer = server.select('ws');

apiServer.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        reply.file('index.html');
    }
});

apiServer.route({
    method: 'GET',
    path: '/action',
    handler: function (request, reply) {

        notifier.emit('action', { time: Date.now() });
        reply('ok');
    }
});

// Setup websocket stuff

var io = require('socket.io')(wsServer.listener);

io.on('connection', function (socket) {

    // Subscribe this socket to `action` events

    notifier.on('action', function (action) {
        socket.emit('action', action);
    });
});

server.start(function () {
    console.log('Server started');
});

Вот основной index.html для клиентской стороны:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://localhost:4001/socket.io/socket.io.js"></script>
</head>
<body>
    <script>
    var socket = io('http://localhost:4001');
    socket.on('action', function (action) {
        console.log(action);
    });
    </script>
</body>
</html>

Если вы запустите это и перейдите к http://localhost:4000 и откройте консоль, вы можете сделать запрос http://localhost:4000/action с вашим браузером или с помощью cURL (curl http://localhost:4000/action), и вы увидите, что события появляются в веб-консоли:

Вы можете попробовать использовать https://github.com/hapijs/nes который интегрирует веб-сокеты в хапи через плагин. Отказ от ответственности Я не пробовал и не использовал веб-сокеты раньше, но, кажется, хорошо интегрируется в хапи.

Другие вопросы по тегам