Nodejs and Socket.Io, Is It Pure JavaScript

How to import socket.io from client-side in vanilla javascript?

You can do this:

Putting this in your index.html :

<body>

<script src="/socket.io/socket.io.js"></script>

<script src="main.js">

// some code here...

</body>

Connecting to socket.io from pure js

socket.io provides various transport layers. If you are happy to experiment and are sure that your client supports WebSocket in all cases, then you might be successful in reproducing the WebSocket-based part of the socket.io protocol on the client side. This, however, seems to be a tedious task compared to just using the code that you would re-invent (partly) anyway.

Use socket.io on the client side, or take an entirely different approach, also on the server side.

Separating socket IO calls for cleaner code in Node and Express

The only thing is that the io variable doesn't seem sharable across multiple files...

This is not true. You can pass the io variable into functions and out of modules just like any other variable. Also like any other variable it is automatically privately scoped to a single file.

There are several ways to share objects across files and if you've gotten this far I'm sure you've used most of them. Only maybe you may not have realized what you have been doing.

Method 1: pass io into functions.

One way to split your logic is to split it across several modules. Since you can pass objects into functions your modules should export functions. For example:

  • file1: type1.js

    function init (io) {
    io.of('/type1').on
    ( 'connection', socket =>
    { socket.on
    ( 'call1', () =>
    { doSomething1();
    }
    );
    }
    );
    }

    module.exports = init;
  • file2: type2.js

    function init (io) {
    io.of('/type2').on
    ( 'connection', socket =>
    { socket.on
    ( 'call2', () =>
    { doSomething2();
    }
    );
    }
    );
    }

    module.exports = init;
  • main.js

    const type1 = require('./path/to/type1.js');
    const type2 = require('./path/to/type2.js');

    // some code to init your app ...

    type1.init(io); // pass io to type1 module
    type2.init(io); // pass io to type2 module

This works because io is just a regular variable. And just like any variable you can pass it as a function argument. Nothing here is fancy, this is all basic features of programming languages.

Method2: share io as a module.

Another technique is specific to how modules work in node.js. Modules are singletons in node. What that means is that a module represents exactly one object. If 3 different files require()s the module they will all get the same object.

We can use this to share the io object between modules:

  • file1: server-init.js

    let app = require('express')();
    let http = require('http').Server(app);
    let io = require('socket.io')(http);

    module.exports = {
    app: app,
    http: http,
    io: io
    }
  • file2: type1.js

    const io = require('./path/to/server-init').io;
    // Alternatively you can use the syntax:
    // const { io } = require('./path/to/server-init');

    function init () {
    io.of('/type1').on
    ( 'connection', socket =>
    { socket.on
    ( 'call1', () =>
    { doSomething1();
    }
    );
    }
    );
    }

    module.exports = init;
  • file3: type2.js

    const io = require('./path/to/server-init').io;

    function init () {
    io.of('/type2').on
    ( 'connection', socket =>
    { socket.on
    ( 'call2', () =>
    { doSomething2();
    }
    );
    }
    );
    }

    module.exports = init;
  • main.js

    const type1 = require('./path/to/type1.js');
    const type2 = require('./path/to/type2.js');
    const { http, app } = require('./path/to/server-init');

    // some init code

    type1.init();
    type2.init();
    http.listen(PORT);

Node.js architecture and app structure

In Node.js ecosystem there is no preferred way of structuring project components, especially for different business cases.

I've implemented a similar web application that needs socket.io instance in express controllers and had the same question: 'How should I access socket object in controllers?'.

What I did was replacing my express controllers with socket events. So, your codebase can turn into these:

io.on('connection', function(socket){

socket.on('join', function(user) {
userStore.join(user)
emitOnlineCount()
})

function emitOnlineCount() {
io.sockets.emit("onlines", userStore.getUsers().length)
}

})

It's in your hand to keep your code clean and simple.



Related Topics



Leave a reply



Submit