Socket.IO 和 HapiJS 之间的连接

Posted

技术标签:

【中文标题】Socket.IO 和 HapiJS 之间的连接【英文标题】:Connection between Socket.IO and HapiJS 【发布时间】:2015-12-22 00:24:26 【问题描述】:

我们有一个用 HapiJS 实现的 REST 服务器和一个用 Socket.IO 实现的 Websockets 服务器(它们都在单个服务器上运行,但在不同的端口上)。我想从 HapiJS 服务器通知 Websockets 服务器向特定客户端发送带有一些数据的事件。

套接字服务器在 8081 端口上运行,而 REST 在 8080 上。

这个想法是客户端进行操作(POST 请求),该操作记录在“操作历史记录”表中。该操作涉及其他用户,因此应在发生这种情况时实时通知他们。这就是其他用户监听 websocket 连接的原因。

如何告诉套接字服务器向特定客户端发出事件并且应该从 REST 服务器完成?

我当时想了三个办法:

    使用 RabbitMQ 为套接字和休息和通信分离服务器

    我尝试实现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 服务器中不执行刷新。我只是没有看到显示的日志。

    创建一个特殊事件并使用普通 socket.io 客户端从 hapijs 连接到 websockets 并在那里发出新事件。

一个样本GIST。

你有想过这样的事情吗?我感谢每一个帮助!

【问题讨论】:

听起来你有点把事情复杂化了。如果这一切都在一台服务器上,为什么不直接调用一个函数或发出一个 EventEmitter 事件呢?在这种情况下不需要引入消息队列之类的东西。 你是对的。很好的解决方案! :) 非常感谢! 嗨@NMP,你最后用的是哪一个?马特方法或使用@hapi/nes 作为西蒙​​的答案? 【参考方案1】:

您可以只使用普通的旧 EventEmitter 在 socket.io 和代码库的 hapi 部分之间进行通信。这是一个有效的示例,并说明了如何执行此操作:

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并打开你的控制台,你就可以用你的浏览器或cURL(curlhttp://localhost:4000/action)向http://localhost:4000/action发出请求,你会看到事件出现在网络上控制台:

【讨论】:

嗨,马特,我可以将 EventEmitter 设为单例,其他模块可能需要它吗?目前,hapi api 的套接字连接和处理程序位于两个不同的模块中,我无法使事件发射器成为两个不同地方所需的单个实例。 我想通了。这是我的错。感谢您的快速回答和帮助! 当然只是从模块中导出它exports.emitter = new EventEmitter(); 没问题。 我们如何从浏览器向服务器发射? @jeff 相同但相反。在客户端调用 socket.emit() 并在服务器上使用 socket.on() 监听。【参考方案2】:

您可以尝试使用https://github.com/hapijs/nes,它通过插件将 websockets 集成到 hapi 中。免责声明我之前没有尝试过或使用过 websockets,但它似乎很好地融入了 hapi .

【讨论】:

很好,我不知道他的。谢谢!

以上是关于Socket.IO 和 HapiJS 之间的连接的主要内容,如果未能解决你的问题,请参考以下文章

socket io客户端和服务器之间的连接问题

无法在 Node.JS 和 React-Native (Socket.IO) 之间建立连接

客户端和服务器端(React/Node.js)之间的 Socket.io 连接失败

使用node.js实现多人聊天室(socket.ioB/S)

Socket.io 分布在不同的服务器上

Socket.io 中的身份验证