Getting socket.io namespace from anywhere in the p

2019-05-22 20:32发布

问题:

After my REST call and some database inserts I want to emit a new notification to the frontend via socket.io like this:

socket.broadcast.emit('send notification', notification);

Since the function I'm doing this in was triggered via REST and not via socket.io I don't have the variable 'socket'.

I thought at first I can just get 'io' like:

var io = require('socket.io') // or like: require('socket.io')(3000)

from here I thought I can get the namespace like:

var nsp = io.of('/notification-list');
nsp.on('connection', function (socket) { ... }

But io seems to be undefined (or if I use it with port 3000 I get EADDRINUSE, because obviously socket.io is connected to 127.0.0.1:3000

This might be a very silly question, but since I can't figure it out on my own: How can I get the socket ready to use in this function? Any help would be much appreciated!


edit:

I tried friend00's solution, but I still can't figure out on how to do this.

in my server.js I create the server & import my socketIO stuff like this:

var server =
http.createServer(app).listen(app.get('port'), function () {
});
require('./socketio_listener/socketIoListener')(server);

then my socketIoListener.js

var sockio = require("socket.io");
var io;

function initIO(server) {
    if (!server) { throw new Error("ERR"); }
    if (!io) {
        io = sockio.listen(server);
    }
    return io;
 }

module.exports.getIO = function () {
    if (!io) {  throw new Error("ERR"); }
    return io;
};

module.exports = function (server) {
io = initIO(server);

var nspNotification = io.of('/notification-list');
nspNotification.on('connection', function (socket) {
    socket.on('get notificationList', function (data) {
        notification.findNotifications(socket, data);
    });
    // ...
});

now I tried in the function I wanted to emit something via socket.io:

var io = require("socket.io").getIO();

I also tried:

var ioServer = require('../socketio_listener/socketIoListener');
ioServer.getIO();

But I still always get:

TypeError: undefined is not a function

SOLUTION

I found the solution, although I'm not quite sure why it was a problem before: I moved module.exports.getIO = function () to the bottom and now it works just fine. Although I thought the placement within the socketIoListener.js didn't matter it appearently did.

回答1:

You will have to share the single server-side io variable to your other modules via some combination of export or module method calls.

Once you have the socket.io listener initialized like this:

var io = require('socket.io').listen(server);

You will need to share specific io instance with other modules that want to use socket.io. How exactly you share it depends upon the structure of your code and where you're trying to share it to.


For example, you could have a module that just managed the initialization of io:

var sockio = require("socket.io");
var io;

// mysocketio.js
// constructor function - should only be called once and passed the http server
module.exports = function(server) {
    if (!server) {
        throw new Error("Must pass http server instance to mysocketio module constructor");
    }
    if (!io) {
        io = sockio.listen(server);
    }
    return io;
};

module.exports.getIO = function() {
    if (!io) {
        throw new Error("Must call constructor of mysocketio module before getIO()");
    }
    return io;
};

Then, in the one place you initialize it up with a specific http server, you could do this:

var io = require("mysocketio")(server);

In the other modules where you just want to use the "already initialized" io, you could do this:

var io = require("mysocketio").getIO();