本文介绍了从项目中的任何位置获取socket.io命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

我一开始觉得我可以像'io'一样:

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) { ... }

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

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!

编辑

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

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

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

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

然后我的 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发出一些东西的函数:

now I tried in the function I wanted to emit something via 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 中的位置并不重要,但显然是这样。

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.

推荐答案

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

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

一旦你的socket.io监听器初始化如下:

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

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

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

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例如,你可以有一个只管理io初始化的模块:

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

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

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

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

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

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

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

这篇关于从项目中的任何位置获取socket.io命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 05:55