在 Express.js 项目中使用 Socket.io

Posted

技术标签:

【中文标题】在 Express.js 项目中使用 Socket.io【英文标题】:Using Socket.io in Express.js Project 【发布时间】:2016-04-08 09:25:22 【问题描述】:

我正在使用 Node.js、Express 和 Socket.io 制作一些单页 Web 应用程序。 我想在浏览器中显示工作情况。 在 IDE 中,有控制台,所以我可以在控制台窗口中检查程序进程。就像,我想向浏览器展示这些过程。我想要的只是“发射”。

当我在app.js 文件中使用socket.io 时,没有问题。但这对我来说是有限的。我想在运行时实时显示许多句子。如何在 app.js 和 controller.js 中使用 socket.io?我红了Use socket.io in controllers这篇文章,但是看不懂。请帮我一个简单的解决方案。

app.js

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

module.exports.io = io;
...

controller.js

var io = require('./app').io;
// some task
console.log('Task is done!'); // it would be seen in console window
io.sockets.emit('Task is done!'); // Also I want to display it to broswer

结果(错误)

TypeError: Cannot read property 'sockets' of undefined

编辑 2---

跟随 Ashley B 的 cmets,我是这样编码的。

controller.js

module.exports.respond = function(socket_io) 
    socket_io.emit('news', 'This is message from controller');
 ;

app.js

var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var controller = require('./controller');
io.sockets.on('connection', controller.respond );

它运作良好,但我想知道的是......当我想要几个socket_emit时,我应该怎么做?我应该每次都打电话吗?如果你不明白。见下文:

//first task is done 
module.exports.respond = function(socket_io) 
    socket_io.emit('news', 'First task is done!');
 ;

//second task is done 
module.exports.respond = function(socket_io) 
    socket_io.emit('news', 'Second task is done!');
 ;

//third task is done 
module.exports.respond = function(socket_io) 
    socket_io.emit('news', 'Third task is done!');
 ;

但这是错误的方式,对吧?只有最后一个 api 在app.js 中实现。我的控制器中有很多console.log,我想将其转换为socket.emit,我该怎么做?

【问题讨论】:

类似的东西应该可以工作 - app.js: require('./controller.js)(io) 然后在 controller.js 上你会这样做:module.exports = function(io) // socket stuff here// @Ashley B 我不明白....我需要调用 module.exports 每个日志吗?我无法猜测“套接字的东西”我必须输入什么。 您可以在其中添加io.sockets.emit('Task is done!');,就像您在示例中使用的那样。 @AshleyB 你能检查一下添加吗?我需要调用 module.exports 每个日志吗? 你会这样做:module.exports.respond = function(socket_io) socket_io.emit('news', 'First task is done!'); socket_io.emit('news', 'Second task is done!'); ; 我建议你阅读如何在 node.js 中进行导出 【参考方案1】:

我已经使用 socket.ionodejs 事件 解决了这个问题。这个想法是只处理来自app.js的socket的发射,并从控制器发出nodejs事件,这些事件将在app.js中捕获,然后由socket发出。

app.js

const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);
const events = require('events');

io.on('connection', function(socket) 
    console.log("Someone has connected");
    var eventEmitter = new events.EventEmitter();
    eventEmitter.on("newEvent", (msg) =>  // occurs when an event is thrown
        socket.emit("news", msg);
    );

    exports.emitter = eventEmitter; // to use the same instance
);

myController.js

const app = require('../app');    
.....

if (app.emitter) // Checking that the event is being received, it is only received if there is someone connected to the socket
    app.emitter.emit("newEvent", "First task is done!");    
.....

if (app.emitter)
    app.emitter.emit("newEvent", "Second task is done!");

【讨论】:

以上是关于在 Express.js 项目中使用 Socket.io的主要内容,如果未能解决你的问题,请参考以下文章

使用 Express.js v4 和 Socket.io v1 的会话

Express.js 'socket.io/socket.io.js 404'

使用 Express JS 路由中的 Socket.io

如何结合 Express.JS 使用 Socket.io(使用 Express 应用程序生成器)

为啥我不能在 Socket.io http 服务器上使用 express.js 获取方法

使用 express.js 和 socket.io 构建推送通知系统的最佳方法