socket-mansion
v1.0.3
Published
Helps you keep track of your sockets and users in multiple rooms
Downloads
6
Readme
Socket-Mansion
Socket-Mansion helps you connect your sockets to rooms, while also keeping check on where your users are.
This lets you focus on the actual function of the room instead of worrying about connections.
You should see your socket-mansion as a container for all rooms, while the modules you inject are rooms, you decide the states of the rooms.
npm install socket-mansion --save
How to use (in 4 steps)
Step 1. Create room
Constructor: Your room modules need to have, io and id as parameters.
function room(io, id) {
this.io = io
this.id = id
}
User joins:
When a user joins the room, room.setup(socket, userObj)
will be called. An example
how your setup function can look like.
room.prototype.setup = function (socket, userObj) {
const user = {name: userObj.user.name, id: socket.id}
socket.emit("hello mansion", "Hey all! I joined a room.");
}
User leaves:
When a user leaves the room, room.off(socket)
will be called. This is a good
time to maybe update your rooms state, or remove events for the socket. Example:
room.prototype.off = function (socket) {
socket.off(`my event`)
}
Step 2. Add your room module to the mansion before server.listen()
var http = require('http')
var app = require('../app')
const {socketMansion} = require('socket-mansion')
const chat = require('../src/chat').chat
const game = require('../src/game').game
const modules = [
{
module: chat,
name: "chat"
},
{
module: game,
name: "game"
},
]
var server = http.createServer(app)
socketMansion(server, modules)
Step 3. Client side
The mansion has some events already created for you, so you can easily connect to your room-events. Before I show you, make sure you setup your user before using any emits.
Setup user:
socket.emit(`setup user`, userObj) // Client emits
{id: socket.id, user: userObj} // Server saves
Events:
Here are the events, as you can see on the create room
we have a third argument
which is the modules name you want to use.
socket.on('get users', (users) => {
//receive users from mansion
})
socket.on('get rooms', (rooms) => {
//receive rooms, which contains the users and the id of room
})
socket.emit('get users') // Triggers above
socket.emit('get rooms') // Triggers above
socket.emit('create room', 'name', 'chat')
socket.emit('join room', 'name')
socket.emit('leave room', 'name')
socket.emit('remove room', 'name') // does not trigger .off, you should leave aswell
Step 4. Wait.. won't my room events be the same if I create a new room with the same module?
Yes you are correct, to fix this we can use the id
that we get in our room
constructor. Then we can do something like this
// "room chat" function on server-side
chat.prototype.message = function (socket) {
socket.on(`message ${this.id}`, (text) => {
// All clients in room gets this message
this.io.sockets.in(this.id).emit(`new ${this.id}`, text)
})
}
// client
socket.on(`new ${roomId}`, (text) => {
console.log(text)
})
socket.emit(`new ${roomId}`, "hello!")
// hello!
Example with React
Instead of me posting lots of code, then please checkout
Test your room modules easily with mocha
A test with mocha and sockets can look like this,
it('Should create room1 with chat module and have player1 and player2', (done) => {
var client1 = io(socketURL, options);
client1.on('connect', () => {
var client2 = io(socketURL, options);
client2.on('connect', () => {
client1.emit('setup user', {name: "player1"});
client2.emit('setup user', {name: "player2"});
client1.emit(`create room`, `room1`, module);
client1.emit('join room', `room1`);
client2.emit('join room', `room1`);
client2.on('message room1', (messages) => {
assert.equal(messages[0].text, 'Room room1 has been created');
assert.equal(messages[1].text, 'player1 has joined the server, welcome!');
assert.equal(messages[2].text, 'player2 has joined the server, welcome!');
client1.disconnect();
client2.disconnect();
done();
});
});
});
});
Wouldn't it be great if you could remove the following,
// var client1 = io(socketURL, options);
// client1.on('connect', () => {
//
// var client2 = io(socketURL, options);
// client2.on('connect', () => {
//
// client1.emit('setup user', {name: "player1"});
// client2.emit('setup user', {name: "player2"});
//
// client1.emit(`create room`, `room1`, module);
//
// client1.emit('join room', `room1`);
// client2.emit('join room', `room1`);
client2.on('message room1', (messages) => {
assert.equal(messages[0].text, 'Room room1 has been created');
assert.equal(messages[1].text, 'player1 has joined the server, welcome!');
assert.equal(messages[2].text, 'player2 has joined the server, welcome!');
client1.disconnect();
client2.disconnect();
done();
});
// });
// });
You can use the setupRoomTest()
to achieve something like this,
it('Should create room1 with chat module and have player1 and player2', (done) => {
const testFunc = (client1, client2) => (done) => {
client2.on('message room1', (messages) => {
assert.equal(messages[0].text, 'Room room1 has been created');
assert.equal(messages[1].text, 'player1 has joined the server, welcome!');
assert.equal(messages[2].text, 'player2 has joined the server, welcome!');
client1.disconnect();
client2.disconnect();
done();
});
};
setupRoomTest({
socketURL: socketURL,
options: options,
func: testFunc,
done: done,
room: 'room1',
module: 'chat'
});
});