从项目中的任何位置获取socket.io命名空间

时间:2015-04-23 16:55:14

标签: javascript node.js socket.io

在我的REST调用和一些数据库插入之后,我想通过socket.io向前端发出一个新的通知,如下所示:

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

由于我执行此操作的功能是通过REST而不是通过socket.io触发的。我没有变量' socket'。

我起初认为我可以得到这样的事情。像:

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

从这里我想我可以获得名称空间:

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

但是io似乎未定义(或者如果我在端口3000上使用它,我会得到EADDRINUSE,因为很明显socket.io连接到127.0.0.1:3000

这可能是一个非常愚蠢的问题,但由于我无法自己解决这个问题:如何让socket准备好在这个功能中使用?任何帮助将不胜感激!

修改

我尝试过friend00的解决方案,但我仍然无法弄清楚如何做到这一点。

在我的server.js我创建了服务器&导入我的socketIO这样的东西:

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

然后我的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);
    });
    // ...
});

现在我尝试了我想通过socket.io发出一些东西的函数:

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

我也尝试过:

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

但我仍然总是得到:

TypeError: undefined is not a function

解决方案

我找到了解决方案,虽然我之前不太确定为什么会出现问题:我将module.exports.getIO = function ()移到了底部,现在它运行得很好。虽然我认为socketIoListener.js中的位置显然不重要。

1 个答案:

答案 0 :(得分:2)

您必须通过导出或模块方法调用的某种组合将单个服务器端io变量共享给其他模块。

一旦你将socket.io监听器初始化为:

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

您需要与要使用io的其他模块共享特定的socket.io实例。您如何分享它取决于您的代码结构以及您尝试共享它的位置。

例如,您可以拥有一个只管理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;
};

然后,在一个地方用特定的http服务器初始化它,你可以这样做:

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

在您只想使用“已经初始化”的io的其他模块中,您可以这样做:

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