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.