WebSocket Transport layer that (currently) works with the HTTP transport to handle websocket connections. Internally, it uses socket.io@1.4.x to handle web sockets. The transport is under active development and changes might occur over time.
The transport was specialized to work with rooms and namespaces in stead of individual sockets. However, this might change over time and additional functionality will be added to address individual socket event sending.
npm i --save thorin-transport-ws@1.x
'use strict'; // app.js entry file const thorin = require('thorin'); thorin.addTransport(require('thorin-transport-ws')); // <-- add this line thorin.run((err) => {});
# run once to allow the transport to set itself up node app.js --setup=transport.ws
A web-based client example can be found here. A list of default events a client can send:
action
sent when the socket wants to trigger an action
room.join
sent when the socket wants to join a room
room.leave
sent when the socket wants to leave a room he is in.
room.clear
sent when the socket wants to leave all the rooms he is in.
A list of server actions that can (and should) be treated on the server side:
ws#socket.connect
triggered when a new socket connects to the server. This is where authorization logic should be placed
ws#room.join
triggered when a socket wants to join a room
ws#room.leave
triggered when a socket wants to leave a room he is in
ws#room.clear
triggered when a socket wants to leave all the rooms he is in
ws#socket.disconnect
triggered when an authorized client disconnects.
ws#room
event to a room name pattern 'use strict';
thorin.dispatcher
.addAction('ws#room.join')
.roomName('/myroom/:room_id')
.input({
room_id: dispatcher.validate('NUMBER')
})
.use((intentObj, next) => {
// Check if user can join room. If not, return next(thorin.error());
log.info(`User joined room ${intentObj.input('room_id')}`);
next();
})
socket
property is added to an intent, containing the raw client websocket object.
When the server is sending events, it uses an instance of the Event
class that it exposes.
The instance is supposed to contain the payload, target action and rooms that will be sent to. Websocket events
also work with target actions and events.
'use strict';
const wsObj = thorin.transport('ws');
const myEvent = new wsObj.Event('target.action.name', {
"with": "some",
"payload": {
"right": "here"
}
});
myEvent
.addRoom('room_1') // send the action to room 1 and 2
.addRoom('room_2');
wsObj.send(myEvent);
'use strict'; // File: config/app.js module.exports = { "transport.http": { // use http as base transport "port": 3500 }, "transport.ws": { // use websockets attached to the http one "authorization": { "cookie": "logapi" // use the Set-Cookie: logapi as authorization source }, "adapter": { // use the redis instance to work as an adapter. "store": "redis", "name": "store:ws" } }, "plugin.session": { // use the session plugin "cookieName": "logapi", "store": "redis" }, "store.redis": { // additional redis connection configuration } };
'use strict'; // File: app.js const thorin = require('thorin'); thorin .addTransport(require('thorin-transport-http')) .addTransport(require('thorin-transport-ws')) .addStore(require('thorin-store-redis')) .addPlugin(require('thorin-plugin-session')); thorin.run((err) => { log.info('Running'); });
'use strict'; // File: app/actions/stream.js const dispatcher = thorin.dispatcher; // Listen to socket connect events dispatcher .addAction('ws#socket.connect') .use((intentObj, next) => { if (intentObj.session.isNew() || !intentObj.session.account) { return next(thorin.error('AUTH.REQUIRED', 'Session expired', 403)) } intentObj.socketData('account', intentObj.session.account); log.info('Socket connected'); next(); }); // Listen to socket disconnect events dispatcher .addAction('ws#socket.disconnect') .use((intentObj, next) => { log.info(`User ${intentObj.socketData('account')} disconnected.`); }); // Listen if somebody wants to join a room dispatcher .addAction('ws#room.join') .use((intentObj, next) => { const socketObj = intentObj.socket, roomName = intentObj.room; log.info(`Socket ${socketObj.id} wants to join room ${roomName}`); intentObj.result({ welcome: 'to the new room!' }); next(); });
A more in-detail example can be found here
You can always create a new issue on GitHub or contact one of the core founders by chat.