egg-socket.io 请问如何在其他控制器中访问到socket对象?

Created on 12 Jan 2018  ·  30Comments  ·  Source: eggjs/egg

想实现推送功能,但是不知道怎么访问到socket对象?

need-more-information not follow template

Most helpful comment

@Mrlilili socket对象是连接后才会创建的,每个连接对应一个。而 io 是服务器的全局对象,在服务器一启动,就存在了。他们是两个不同的概念。可以参考下 https://github.com/eggjs/egg-socket.io/blob/master/test/fixtures/apps/socket.io-async/app/io/controller/chatAsyncClass.js#L10 ,socket 对象在 egg-socket.io 里面被封装在了 ctx 里面,因为 ctx 是对请求的封装。

仔细又看了一下,发现是要拿 sockets 对象。通过阅读发现 https://github.com/eggjs/egg-socket.io/blob/master/index.d.ts#L17,Socket.IO 的原始对象定义,都是从 @type/socket.io 包继承来的,但是 @type/socket.io 包在 devDependencies https://github.com/eggjs/egg-socket.io/blob/master/package.json#L28 ,所以你的项目里面估计缺少了这个包,你手动加上试试。

All 30 comments

什么是『其他控制器』,请按照模板提问,不然信息不全,无法解答的。

@ngot 您好!请问第三方调用链接,如何推送信息到客户端?通过route.js定义的get路由并不能访问到socket对象。麻烦了,这个困扰我两天了。谢谢

get 是 http, http 和 socket 完全是两个东西。不太明白你要做啥?

这个 issue 感觉漫无目的,也没有提供任何可判断信息,先关了。

应该是我描述不清楚,确实想实现推送功能,通过对外链接,推送信息到客户端,可是发现通过get路由的控制器不能访问到socket对象,也就没有推送信息给客户端

@xianglong111
https://github.com/eggjs/egg-socket.io#controller
这个估计是你想要的

tim 20180115090132
tim 20180115090207
您好!是这样的,上面的图就是我这边想实现在route中配置一个GET,然后想通过HTTP访问到socket对象,推送相应的信息给客户端,但是确实是访问不到this.ctx.socket,这个问题确实一直困扰我,麻烦您了!

@xianglong111 http 和 socket 这两个概念搞混了。 这两个是完全不同的东西,这样可以使用『风马牛不相及』来形容。

建议,先补一下网络基础知识,然后再看看 socket.io 的文档,就知道怎么做了。

您好!这个是我使用express和socket.io搭建的一个小程序,就是按照这种方式实现的。我刚才也仔细看了所有的 Issues 发现很多人也都存在这个问题,指定客户端发送推送信息。

Express框架中路由使用Socket.io,以下三个步骤:
1、app.js文件添加
var io = require('socket.io')();
//事件监听
app.io = io;
io.on('connection', function (socket) {
console.log(socket.id);
socket.emit('news', { hello: 'world',id:socket.id });
socket.on('notifyNum', function (data) {
console.log(data.msg_count);
});
});
2、\binwww文件中添加
var io = app.io;
io.attach( server );

3、路由中使用
var pushRouter = function(io) {
router.get('/:socketid', function(req, res, next) {
//req.params.socketid 客户端socket唯一ID
io.sockets.sockets[req.params.socketid].emit('message', {
msg:'for your eyes only',
id:req.params.socketid
});
res.end('success');
});
return router;
};

@xianglong111 我这样理解对不对?
你希望暴露一个http接口,这个接口实现的是向指定socket.io客户端发起一次emit?

是的

那你的 /chat/:id的路由不要指向app.io.controller,你需要指向到app.controller下的控制器。
然后你看一下,io不出意外应该是挂载在app上了,看看能不能获取到socket.io对象。
如果获取到了,我想你知道怎么emit吧?

好的,谢谢

@xianglong111 最终结果如何?

@duncup 谢谢了,结果是能通过挂载io访问sockets, 这种方式 this.app.io.sockets.sockets[this.ctx.params.id].emit可以推送给指定id的客户端,但是还是访问不到socket对象,如果想做广播的话还是不行,我还没有找到方法。

你已经拿到io对象的话已经可以解决广播问题了啊,你可以去参考下socket.io的文档部分。
https://socket.io/docs/rooms-and-namespaces/#rooms

@duncup 好的,非常感谢!

ts中直接调用app上的io会报错,app上面没有声明io,有什么解决方案可以解决?
image

@Mrlilili 看官方文档中的 ts 章节底部常见问题

@whxaxes 项目中是有启用 egg-ts-helper ,但是还是会有这个报错的。

@Mrlilili 都说了让你看常见问题( https://eggjs.org/zh-cn/tutorials/typescript.html#%E4%BD%BF%E7%94%A8%E4%BA%86-egg-%E6%8F%92%E4%BB%B6%E5%90%8E%E5%8F%91%E7%8E%B0%E6%B2%A1%E6%9C%89%E5%AF%B9%E5%BA%94%E6%8F%92%E4%BB%B6%E6%8C%82%E8%BD%BD%E7%9A%84%E5%AF%B9%E8%B1%A1 )...

@whxaxes 这个常见问题说明有看的。
egg-socket.io是有定义 d.ts 文件的。
ts常见说明问题文档中的说明是:

egg 插件定义了 d.ts ,但是没有引入。 如果使用了 egg-ts-helper ,egg-ts-helper 会自动根据应用中开启了什么插件从而生成显式 import 插件的声明。

我的项目中就是开了egg-ts-helper还是会报错

@Mrlilili 给个能稳定复现的 repo 提 issue 吧

@Mrlilili 你现在这个截图就是另一个问题了 .... 不是已经有 io 这个属性了么 ...

@whxaxes 原先没有io属性的问题是没有声明app类型的原因造成的,改正了下,就报了这个错误

@Mrlilili 你现在这个截图就是另一个问题了 .... 不是已经有 io 这个属性了么 ...

io上好像是没有这个sockets属性

@Mrlilili socket对象是连接后才会创建的,每个连接对应一个。而 io 是服务器的全局对象,在服务器一启动,就存在了。他们是两个不同的概念。可以参考下 https://github.com/eggjs/egg-socket.io/blob/master/test/fixtures/apps/socket.io-async/app/io/controller/chatAsyncClass.js#L10 ,socket 对象在 egg-socket.io 里面被封装在了 ctx 里面,因为 ctx 是对请求的封装。

@Mrlilili socket对象是连接后才会创建的,每个连接对应一个。而 io 是服务器的全局对象,在服务器一启动,就存在了。他们是两个不同的概念。可以参考下 https://github.com/eggjs/egg-socket.io/blob/master/test/fixtures/apps/socket.io-async/app/io/controller/chatAsyncClass.js#L10 ,socket 对象在 egg-socket.io 里面被封装在了 ctx 里面,因为 ctx 是对请求的封装。

仔细又看了一下,发现是要拿 sockets 对象。通过阅读发现 https://github.com/eggjs/egg-socket.io/blob/master/index.d.ts#L17,Socket.IO 的原始对象定义,都是从 @type/socket.io 包继承来的,但是 @type/socket.io 包在 devDependencies https://github.com/eggjs/egg-socket.io/blob/master/package.json#L28 ,所以你的项目里面估计缺少了这个包,你手动加上试试。

@ngot 已解决。 egg-socket.io项目你们会发个版本更新下把依赖挪到dependencies中么?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wujianling picture wujianling  ·  3Comments

weijiatan456 picture weijiatan456  ·  3Comments

Webjiacheng picture Webjiacheng  ·  3Comments

lvgg3271 picture lvgg3271  ·  3Comments

bupafengyu picture bupafengyu  ·  3Comments