在快速路由文件中使用socket.io

时间:2022-08-22 16:28:11

I'm trying to use Socket.io with Node.js and emit to a socket within the logic of a route.

我正在尝试将Socket.io与Node.js一起使用并发送到路由逻辑中的套接字。

I have a fairly standard Express 3 setup with a server.js file that sits in the route, and then I have an index.js which sits in a routes folders that exports all the pages/publically accessible functions of the site. So they look like:

我有一个相当标准的Express 3设置和一个位于路由中的server.js文件,然后我有一个index.js,它位于路径文件夹中,用于导出站点的所有页面/可公开访问的功能。所以他们看起来像:

exports.index = function (req, res) {
    res.render('index', {
        title: "Awesome page"
    });
}; 

with the routing defined in server.js like:

与server.js中定义的路由类似:

app.get('/',routes.index);

I'm assuming I have to create the socket.io object in the server.js, since it needs the server object, but how can I access that object and emit to it from the index.js export functions?

我假设我必须在server.js中创建socket.io对象,因为它需要服务器对象,但是如何访问该对象并从index.js导出函数向它发出?

5 个解决方案

#1


11  

You can set up your routes file as a function, and pass the Socket.IO object when requiring the file.

您可以将路由文件设置为函数,并在需要该文件时传递Socket.IO对象。

module.exports = function(io) {
  var routes = {};
  routes.index = function (req, res) {
    io.sockets.emit('payload');
    res.render('index', {
      title: "Awesome page"
    });
  };
  return routes;
};

Then require routes like this:

然后需要这样的路线:

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

#2


44  

There is a better way to do this now with Express 4.0, using app.set() to store a reference to the io object.

现在有一种更好的方法可以使用Express 4.0,使用app.set()来存储对io对象的引用。

Base configuration:

基本配置:

var app = require('express')();
var server = app.listen(process.env.PORT || 3000);
var io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);

Inside route or middleware:

内部路线或中间件:

exports.foo = function(req,res){
    // now use socket.io in your routes file
    var io = req.app.get('socketio');
    io.emit('hi!');
}

#3


5  

aarosil's answer was great, but I ran into the same problem as Victor with managing client connections using this approach. For every reload on the client, you'd get as many duplicate messages on the server (2nd reload = 2 duplicates, 3rd = 3 duplicates, etc).

aarosil的答案很棒,但我遇到了与Victor一样的问题,使用这种方法管理客户端连接。对于客户端上的每次重新加载,您将在服务器上获得尽可能多的重复消息(第二次重新加载= 2次重复,第三次= 3次重复等)。

Expanding on aarosil's answer, I used this approach to use the socket object in my routes file, and manage the connections/control duplicate messages:

扩展了aarosil的答案,我使用这种方法在我的路由文件中使用套接字对象,并管理连接/控制重复消息:

Inside Server File

内部服务器文件

// same as aarosil (LIFESAVER)
const app = require('express')();
const server = app.listen(process.env.PORT || 3000);
const io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);

Inside routes file

内部路线文件

exports.foo = (req,res) => {

   let socket_id = [];
   const io = req.app.get('socketio');

   io.on('connection', socket => {
      socket_id.push(socket.id);
      if (socket_id[0] === socket.id) {
        // remove the connection listener for any subsequent 
        // connections with the same ID
        io.removeAllListeners('connection'); 
      }

      socket.on('hello message', msg => {
        console.log('just got: ', msg);
        socket.emit('chat message', 'hi from server');

      })

   });
}

#4


1  

Whats wrong with just using

只是使用有什么不对

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

#5


0  

module.parent.exports.server would also work if you exported server in the parent module.

如果您在父模块中导出服务器,module.parent.exports.server也可以工作。

#1


11  

You can set up your routes file as a function, and pass the Socket.IO object when requiring the file.

您可以将路由文件设置为函数,并在需要该文件时传递Socket.IO对象。

module.exports = function(io) {
  var routes = {};
  routes.index = function (req, res) {
    io.sockets.emit('payload');
    res.render('index', {
      title: "Awesome page"
    });
  };
  return routes;
};

Then require routes like this:

然后需要这样的路线:

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

#2


44  

There is a better way to do this now with Express 4.0, using app.set() to store a reference to the io object.

现在有一种更好的方法可以使用Express 4.0,使用app.set()来存储对io对象的引用。

Base configuration:

基本配置:

var app = require('express')();
var server = app.listen(process.env.PORT || 3000);
var io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);

Inside route or middleware:

内部路线或中间件:

exports.foo = function(req,res){
    // now use socket.io in your routes file
    var io = req.app.get('socketio');
    io.emit('hi!');
}

#3


5  

aarosil's answer was great, but I ran into the same problem as Victor with managing client connections using this approach. For every reload on the client, you'd get as many duplicate messages on the server (2nd reload = 2 duplicates, 3rd = 3 duplicates, etc).

aarosil的答案很棒,但我遇到了与Victor一样的问题,使用这种方法管理客户端连接。对于客户端上的每次重新加载,您将在服务器上获得尽可能多的重复消息(第二次重新加载= 2次重复,第三次= 3次重复等)。

Expanding on aarosil's answer, I used this approach to use the socket object in my routes file, and manage the connections/control duplicate messages:

扩展了aarosil的答案,我使用这种方法在我的路由文件中使用套接字对象,并管理连接/控制重复消息:

Inside Server File

内部服务器文件

// same as aarosil (LIFESAVER)
const app = require('express')();
const server = app.listen(process.env.PORT || 3000);
const io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);

Inside routes file

内部路线文件

exports.foo = (req,res) => {

   let socket_id = [];
   const io = req.app.get('socketio');

   io.on('connection', socket => {
      socket_id.push(socket.id);
      if (socket_id[0] === socket.id) {
        // remove the connection listener for any subsequent 
        // connections with the same ID
        io.removeAllListeners('connection'); 
      }

      socket.on('hello message', msg => {
        console.log('just got: ', msg);
        socket.emit('chat message', 'hi from server');

      })

   });
}

#4


1  

Whats wrong with just using

只是使用有什么不对

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

#5


0  

module.parent.exports.server would also work if you exported server in the parent module.

如果您在父模块中导出服务器,module.parent.exports.server也可以工作。