We have a REST server implemented with HapiJS and a Websockets server implemented with Socket.IO (they are both running on a single server but on different ports). I want to notify the Websockets server from the HapiJS server to send an event with some data to a particular client.
The socket server is running on port 8081 and the REST is on 8080.
The idea is that a client makes an action (POST request), that is logged in an "Actions History" table. That action concerns other users, so they should be notified when this happens in real time. That is why the other users are listening on the websocket connection.
How can I tell the sockets server to emit an event to a particular client and that should be done from the REST server?
I thought for 3 ways at the moment:
I tried to implement Socket.IO-Emitter but it requires Redis database (I still don't know why). When I try to connect using the emitter from the HapiJS route handler to the socket I get:
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.
at RedisClient.on_info_cmd
Refresh is not executed in the Socket server. I just don't see the log displayed.
A sample GIST.
Have you figured out something like this? I appreciate every help!
You could try using https://github.com/hapijs/nes which intergrates websockets into hapi via a plugin. Disclaimer I have not tried it or used websockets before but it seems integrate into hapi well .
You can just use a plain old EventEmitter to communicate between the socket.io and the hapi parts of your codebase. Here's an example that works and illustrates how you can do this:
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');
});
Here's a basic index.html for the client side:
<!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>
If you run this and browse to http://localhost:4000
and open your console, you can then make requests to http://localhost:4000/action
with your browser or with cURL (curl http://localhost:4000/action) and you'll see the events appear in the web console:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With