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 之间的连接的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Node.JS 和 React-Native (Socket.IO) 之间建立连接
客户端和服务器端(React/Node.js)之间的 Socket.io 连接失败