访问koa路线中的socket.io

时间:2014-09-12 06:50:29

标签: socket.io socket.io-1.0 koa

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

我尝试在我的koa上下文中添加io,例如koa.context.io = io甚至io.on('connection', function(socket){ koa.context.socket = socket });,但没有任何效果。

先谢谢你们。

2 个答案:

答案 0 :(得分:1)

我意识到这有点晚了,并且可以被认为是稍微自我服务,因为我将建议我自己的一个模块,但是,你正在将它附加到应用程序的正确轨道上使用Koa v2时,这更容易,因为上下文正好传递,但是使用v1,你可以将它添加到this,因为koa中间件被绑定到app实例。

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

答案 1 :(得分:0)

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

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

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

此回调是在co的帮助下生成的,并且要求您的应用已经设置了所有中间件/路由。 (见koa source)。因此,您无法在这些路由中使用socket.io实例(之后创建)。

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

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

app.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 + ' ...');

的index.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>