【问题标题】:Socket.io emit on Express RouteSocket.io 在 Express Route 上发出
【发布时间】:2016-09-30 06:53:39
【问题描述】:

我想在调用某些 API 路由时向客户端发送一些数据。 我必须遵循 server.js 上的代码

var app  = express();
var http = require('http').Server(app);

var io   = require('socket.io')(http);

io.on('connection', function(socket){
  console.log('a user connected');

  socket.emit('tx', 'msg');

  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

现在我有这条路线 /test:

var bsg   = require('./routes/test');

还有那个文件:

var express      = require('express');
var passport     = require('passport');
var router       = express.Router();

router.get('/test',  function(req, res) {
  //work here
});

module.exports = router;

在客户端:

<script type="text/javascript">
   var socket = io();

   socket.on('tx', function(data) {
     console.log(data);
   });
</script>

什么是最好的解决方案?

谢谢!

Express 4 / socket.io 1.4.5

【问题讨论】:

  • 我正在使用 module.exports = router;我不能做 export = function(app,io)
  • 好吧,除非您将其设为全局变量,否则您必须传递 io 实例才能让您的路线使用它
  • 不知道如何使用我当前的设置来做到这一点
  • 刚刚更新了路由文件以显示我的设置

标签: node.js express socket.io


【解决方案1】:

io 实例附加到您的应用。

app.io = io;

然后就可以通过请求访问了。

router.get('/test',  function(req, res) {
  req.app.io.emit('tx', {key:"value"});
});

我应该注意,将数据附加到 express 更“正确”的方法是使用 app.set('io', io)app.get('io') 来检索它,以防 express 开始使用 io 属性。

如果您希望向单个客户端发送数据,则需要保留某种会话映射以将独立的 http 请求链接到套接字。会话 ID 可能不是一对一的映射,因为您可以为一个会话打开多个套接字。你最好直接使用 socket.io 回调处理请求/响应模式。

【讨论】:

  • 服务器没有错误,但 req.app.io.emit 没有向客户端发送数据:(
  • 如果我在 /test 路由上执行此操作: req.app.io.on('connection', function(socket) { socket.emit('tx', 'some data'); }) ;客户端将接收数据,但仅在 F5(刷新)页面上,
  • 得到它的工作,只需要做:req.app.io.emit('tx', data);
  • 我个人更喜欢将 .io 附加到 req 作为中间件 ... // 让我们的路由器可以访问 io app.use(function(req, res, next) { 'use strict'; req.io = io; next(); });所以我所要做的就是 req.io.emit() ,这没有什么不同,但它保存了 .app
  • 不能让它工作。获取TypeError: Cannot read property 'emit' of undefined。在这种情况下,应用程序是什么? express-instance 对吗?
【解决方案2】:

您也可以将实例附加到 req 对象:

app.use(function(req,res,next){
req.io = io;
next();
})

并发射到单个客户端

req.io.to(<socketId of cient>).emit(data);

【讨论】:

  • 有没有办法使用req.io.to“发送给除发件人以外的所有人”?我知道通常执行此操作的方法是socket.broadcast.emit,但我找不到从路由内访问socket 的方法,只能访问io
  • 我也面临同样的问题:(
  • @user1063287 您正在混合 http 请求和 socketio 连接。您必须编写一些将您的 http 会话管理器映射到 socketid 的内容,然后排除来自该 http 会话的所有 socketid。
  • @Matt 请举例说明您所说的内容。它将帮助我们更好地理解。谢谢。
  • @YulePale 作为一个关于你正在尝试的细节的问题,将快速路由映射到 socketio 套接字需要一些关于如何进行映射的上下文
猜你喜欢
  • 2018-07-13
  • 2016-09-20
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 2020-10-22
  • 2020-05-10
相关资源
最近更新 更多