如何将 socket.io 导出到 nodejs 中的其他module?

IT技术 javascript node.js socket.io
2021-01-14 08:22:25

我有socket.io工作,app.js但是当我尝试从其他module调用它时,它io.connection不确定吗?

应用程序.js

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var ditconsumer = require('./app/consumers/ditconsumer');
ditconsumer.start(io);
server.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});

消费者.js

module.exports = {
    start: function (io) {
        consumer.on('message', function (message) {
            logger.log('info', message.value);
            io.on('connection', function (socket) {
                socket.on('message', function(message) {
                    socket.emit('ditConsumer',message.value);
                    console.log('from console',message.value);
                });
            });
        });
}
}
6个回答

由于 app.js 通常是您的应用程序中的主要初始化module,它通常会同时初始化 Web 服务器和 socket.io,并将加载应用程序所需的其他内容。

因此,io与其他module共享的典型方法是将它们传递给该module构造函数中的其他module。这会像这样工作:

var server = require('http').createServer(app);
var io = require('socket.io')(server);

// load consumer.js and pass it the socket.io object
require('./consumer.js')(io);

// other app.js code follows

然后,在 consumer.js 中:

// define constructor function that gets `io` send to it
module.exports = function(io) {
    io.on('connection', function(socket) {
        socket.on('message', function(message) {
            logger.log('info',message.value);
            socket.emit('ditConsumer',message.value);
            console.log('from console',message.value);
        });
    });
};

或者,如果你想使用一种.start()方法来初始化事物,你可以用它做同样的事情(细微差别):

// app.js
var server = require('http').createServer(app);
var io = require('socket.io')(server);

// load consumer.js and pass it the socket.io object
var consumer = require('./consumer.js');
consumer.start(io);

// other app.js code follows

还有consumer.js中的start方法

// consumer.js
// define start method that gets `io` send to it
module.exports = {
    start: function(io) {
        io.on('connection', function(socket) {
            socket.on('message', function(message) {
                logger.log('info',message.value);
                socket.emit('ditConsumer',message.value);
                console.log('from console',message.value);
            });
        });
    };
}

这就是所谓的资源共享的“推送”module。正在加载您的module通过在构造函数中传递一些共享信息给您。

还有“拉”模型,其中module本身调用其他module中的方法来检索共享信息(在这种情况下是io对象)。

通常,任一模型都可以工作,但考虑到module是如何加载的、谁拥有所需的信息以及您打算如何在其他情况下重用module,通常其中一个模型会感觉更自然。

所以如果我需要io对象,我是否需要io.on像你所做的那样在每个module中创建连接consumer.js
2021-03-16 08:22:25
是的..我忘记了这种方法。我实际上比我更喜欢这个建议。
2021-03-22 08:22:25
@hussain - 您对消费者的修改与此通用方案完全兼容。如果您想保留start导出的方法,则只需传递io给该start方法并从那里获取它。关键是您让appmodule将io对象consumer作为module启动/初始化的一部分传递给您consumermodule。但是,您显示的内容看起来就像您可以用我建议的内容替换您拥有的内容并使用构造函数而不是start()方法 - 尽管两者都可以正常工作。
2021-04-07 08:22:25
@hussain - 如果您尝试侦听来自已连接套接字的传入消息,则需要io.on('connection, ...)访问已连接的套接字。当然还有其他方法来架构事物,其中您有一个中央io.on('connection, ...)module,其他module可以提供消息侦听器,但这是代码中的一个更大的更改,我们必须更多地了解您在做什么才能知道最好的推荐. 但是,拥有多个io.on('connection, ...)听众也没什么大不了的io是一个eventEmitter并且是为了拥有大量的听众而构建的。
2021-04-11 08:22:25
实际上,我为消费者更新了我的问题代码,我已经将消费者导出到 app.js 中,是否可以添加 module.export 函数 inisde Consumer 对象?
2021-04-13 08:22:25

如果您想避免全局范围,请将您的io存在于一个单独的文件中,如下所示:

var sio = require('socket.io');
var io = null;

exports.io = function () {
  return io;
};

exports.initialize = function(server) {
  return io = sio(server);
};

然后在app.js

var server = require('http').createServer(app);
var io = require('./io').initialize(server);
require('./app/consumers/ditconsumer'); // loading module will cause desired side-effect
server.listen(...);

并在consumer.js

require('../io').io().on('connection', function(socket) {
  logger.log('info', message.value);
  socket.on('message', function(message) {
    socket.emit('ditConsumer',message.value);
    console.log('from console',message.value);
  });
});
我添加var socket = require('../index').io()到consumer.js但它的抛出错误TypeError: require(...).io is not a function
2021-03-14 08:22:25
您添加的新文件是否称为index.js
2021-03-17 08:22:25
这家伙,这家伙他妈的。#piedPiperReference。与这个小module伙伴的出色工作,通过我正在做的练习帮助了我很多。
2021-03-17 08:22:25
您确定该文件位于相对于 的正确位置consumer.js吗?
2021-03-26 08:22:25
是否index.js有代码exports.io = function () { return io; };
2021-03-30 08:22:25

我找到了一个简单的解决方案在 app.js 中使用全局变量并从其他文件访问它。

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

这很棒。但是有人知道这有任何安全问题吗?
2021-03-22 08:22:25

您只需 4 行即可创建一个单例实例。

在 websocket.js 中编写您的服务器配置代码。

const socketIO = require('socket.io');
const server = require('http').createServer();
server.listen(8000);

module.exports = socketIO(server);

然后在您的 consumer.js 中只需要该文件

const socket = require('./websocket');

/* API logic here */

socket.emit('userRegistered', `${user.name} has registered.`);

对我来说最有效的是使用一个回调函数来导出 socket.io 实例。应用程序.js:

var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
    socket.on('message', function(message) {
        logger.log('info',message.value);
        socket.emit('ditConsumer',message.value);
        console.log('from console',message.value);
    });
});
function getSocketIo(){
    return io;
}
module.exports.getSocketIo=getSocketIo

在consumer.js中

const app=require('./app.js')
const io=app.getSocketIo()