2

我正在尝试将 socket.io 与 koa.js 一起使用,并且我能够在我的应用程序的最底部添加server = require('http').createServer(koa.callback()).listen(port);和连接,但现在我想发出并在可能的情况下监听来自我的控制器/路由的事件。io = require('socket.io')(server);实现这一点的最佳方法是什么?

我已经尝试io在我的 koa 上下文中添加类似的内容koa.context.io = ioio.on('connection', function(socket){ koa.context.socket = socket });但没有任何效果。

提前谢谢各位。

4

2 回答 2

1

在您的 koa 路由中访问 socket.io 实例应该不起作用。

创建 socket.io 实例取决于应用程序创建一个可供 http 服务器使用的回调函数。

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

此回调是在 co 的帮助下生成的,并且要求您的应用程序已经设置了所有中间件/路由。(参见koa 源代码)。因此,您不能在这些路由中使用 socket.io 实例(随后创建)。

此外,我认为它不打算在您的控制器中发出 socket.io 事件。如果要将数据发送回调用控制器的客户端,则应在该控制器生成的响应中执行此操作。如果您想在服务器上发出更多事件,您可以通过发出服务器将接收的事件从客户端触发它们。这样,您可以在传递给的函数中处理来自客户端的数据,socket.on(...)而无需在 koa 的控制器/路由中实现它。

这是第二种情况的示例,没有任何 koa 控制器/路由。

应用程序.js:

var http = require('http');
var koa = require('koa');
var app = koa();
var send = require('koa-send');

app.use(function* (next) {
  if (this.path !== '/') return yield next;
  yield send(this, __dirname + '/index.html');
});

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

io.on('connection', function (socket) {
  socket.on('click', function (data) {
    //process the data here
    console.log('client clicked! data:');
    console.log(data);

    // emit an event
    console.log('responding with news');
    socket.emit('news', { hello: 'world' });
  });
});

var port = process.env.PORT || 3000;
server.listen(port);
console.log ('Listening at port ' + port + ' ...');

索引.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>koa-socket.io</title>
</head>
<body>

  <script src="/socket.io/socket.io.js"></script>
  <script>
    var socket = io('http://localhost:3000');
    socket.on('news', function (data) {
      console.log('received news with data: ');
      console.log(data);
    });

    function myclick () {
      console.log("click");
      socket.emit('click', { clickdata: 'i clicked the button' });
    }

  </script>

  <button type="button" onclick="myclick();">Click Me and watch console at server and in browser.</button>
</body>
</html>
于 2014-09-16T00:12:07.627 回答
1

我意识到这有点晚了,并且可能被认为有点自私,因为我将建议我自己的模块之一,但是,通过 Koa 将它附加到应用程序中,你走在了正确的轨道上v2 这更容易,因为上下文是直接传递的,但是使用 v1 你可以将它附加到this,因为 koa 中间件绑定到应用程序实例。

或者,我编写了一个模块来帮助解决这个确切的用例,https://github.com/mattstyles/koa-socket,它目前(并且可能永远)只做两件事:它将 socket.io 服务器实例附加到上下文,它允许您为套接字侦听器编写 koa 风格的中间件。

于 2015-11-21T13:37:24.740 回答