npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

socket-mansion

v1.0.3

Published

Helps you keep track of your sockets and users in multiple rooms

Downloads

6

Readme

Socket-Mansion

Build Status Code Coverage Build Status Maintainability

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

Chat (server)

Choose room (client)

Chat room (client)

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'
    });
});