netty4 采用DefaultChannelGroup管理所有的channel 怎么找到其中特定一个?

预兆师 发布于 2014/03/05 17:14
阅读 19K+
收藏 1

@石头哥哥 你好,想跟你请教个问题:

我正在使用netty4.0.17做一个im项目,但我刚接触netty,对于如何管理channel毫无头绪。netty4提供DefaultChannelGroup来管理所有channel,但是4.0.17版本把channel.id()去掉了,也把DefaultChannelGroup.find()去掉了,因此我不知道在DefaultChannelGroup如何找到特定的channel。

我目前采用的方法,是自己用一个Map<String,Channel>来保存channel的信息,但不知道这种方法好不好。请问4.0.17版本有什么方法可以用来标记channel吗?

PS:我的问题其实就是A向B发送一条消息,服务器在接收到A的消息包后,怎么找到B并把消息发送过去。其实对于业务逻辑方面如何设计,我仍然理不清,如果你有思路,请告诉我。感激万分!

加载中
0
石头哥哥
石头哥哥

嗯 channel实际就是一个客户端和server的一个抽象的管道  ,netty封装了网络的底层  所以 你不必太多去掀开一些它封装的东西来处理 对于还不熟悉的开发者来讲的 话;你可以这样处理  在连接上来的时候 你创建一个session会话来持有这个channel  ,每一个session有一个ID ,那么 你在业务层就可以通过这个ID拿到session  从而将这个数据发送出去,你这里 其实在服务器端就是sessionA  sessionB ,A,B两个客户端连接服务器了 ,那么 就创建sessionA  sessionB ,并产生一个ID  (ID 保持唯一就可以了),A向B发送,那么实际就是通过服务器来转发A的消息到B,那么你必然拿到B的ID,几在A的消息中发送B的ID,这样就可以拿到sessionB ,然后channel.write();  消息的转发  与消息的推送 关键就在与知道sessionID,顺利得到相应的session  这样就可以解决问题了;

创建session的位置在channelActive(ChannelHandlerContext ctx);标记channel的方式很多 ,上面的和你描述的一样  只是 封装了一个session来持有channel罢了;

0
预兆师
预兆师

引用来自“石头哥哥”的答案

嗯 channel实际就是一个客户端和server的一个抽象的管道  ,netty封装了网络的底层  所以 你不必太多去掀开一些它封装的东西来处理 对于还不熟悉的开发者来讲的 话;你可以这样处理  在连接上来的时候 你创建一个session会话来持有这个channel  ,每一个session有一个ID ,那么 你在业务层就可以通过这个ID拿到session  从而将这个数据发送出去,你这里 其实在服务器端就是sessionA  sessionB ,A,B两个客户端连接服务器了 ,那么 就创建sessionA  sessionB ,并产生一个ID  (ID 保持唯一就可以了),A向B发送,那么实际就是通过服务器来转发A的消息到B,那么你必然拿到B的ID,几在A的消息中发送B的ID,这样就可以拿到sessionB ,然后channel.write();  消息的转发  与消息的推送 关键就在与知道sessionID,顺利得到相应的session  这样就可以解决问题了;

创建session的位置在channelActive(ChannelHandlerContext ctx);标记channel的方式很多 ,上面的和你描述的一样  只是 封装了一个session来持有channel罢了;

谢谢你的回复。

你的回复里面没有提到如何绑定用户和channel的对应关系。我对此的大致想法是这样的:客户端与服务端建立连接的时候,也就是在channelActive(ChannelHandlerContext ctx),服务端用RSA算法生成一对公私钥,并把公钥返回给客户端;客户端使用公钥加密登录信息发送到服务器,服务器解密后,将用户信息与channel对应起来,记录在链表里面。然后当A发送信息给B的时候,服务器从链表里面找到B的信息,并通过B对应的channel传送信息给B。

不知我这样的连接流程有没有问题,请指教。

0
石头哥哥
石头哥哥

引用来自“预兆师”的答案

引用来自“石头哥哥”的答案

嗯 channel实际就是一个客户端和server的一个抽象的管道  ,netty封装了网络的底层  所以 你不必太多去掀开一些它封装的东西来处理 对于还不熟悉的开发者来讲的 话;你可以这样处理  在连接上来的时候 你创建一个session会话来持有这个channel  ,每一个session有一个ID ,那么 你在业务层就可以通过这个ID拿到session  从而将这个数据发送出去,你这里 其实在服务器端就是sessionA  sessionB ,A,B两个客户端连接服务器了 ,那么 就创建sessionA  sessionB ,并产生一个ID  (ID 保持唯一就可以了),A向B发送,那么实际就是通过服务器来转发A的消息到B,那么你必然拿到B的ID,几在A的消息中发送B的ID,这样就可以拿到sessionB ,然后channel.write();  消息的转发  与消息的推送 关键就在与知道sessionID,顺利得到相应的session  这样就可以解决问题了;

创建session的位置在channelActive(ChannelHandlerContext ctx);标记channel的方式很多 ,上面的和你描述的一样  只是 封装了一个session来持有channel罢了;

谢谢你的回复。

你的回复里面没有提到如何绑定用户和channel的对应关系。我对此的大致想法是这样的:客户端与服务端建立连接的时候,也就是在channelActive(ChannelHandlerContext ctx),服务端用RSA算法生成一对公私钥,并把公钥返回给客户端;客户端使用公钥加密登录信息发送到服务器,服务器解密后,将用户信息与channel对应起来,记录在链表里面。然后当A发送信息给B的时候,服务器从链表里面找到B的信息,并通过B对应的channel传送信息给B。

不知我这样的连接流程有没有问题,请指教。

ID--session--channel 它们是一一对应的,  map<ID,session>;
class session{
   ID;//session持有ID 
   channel;//session持有channel
}
任何一个客户端链接上来,你就把服务器现在在线的ID同步给链接上来的客户端,这样就好像是qq,向谁发送? 只需 ID(目标)+message; 额 你这个是可以的  变相的其实本质一样 ,ID 就是一个纽带;  
0
月光小南
月光小南
我自己是用的Map处理的,如果你有好的方法,不放告诉我一下。。。
0
杨子江
杨子江

这样算是比较优雅的处理方式?或者说是最佳实践? 

如果同时在线的客户端超多的时候,就需要维护一个较大session的map?

0
jack_ygy
jack_ygy
请问,最终是怎样获得一个特定的channel的,我用hashmap保存所有的channel,拿出来的时候,发送信息,客户端收不到
0
开源X
开源X
楼主知道怎么弄了么……教教我吧
0
cnlinjie
cnlinjie
就是自己管理吧。
0
别以而过
别以而过

目前用ConcurrentHashMap。可以不?

采蘑菇的大叔
采蘑菇的大叔
我也用的这个~
0
谭子政
谭子政

@石头哥哥   如果有两个服务器,这个channel怎么管理,比如a服务器要发送到b服务器channel

K
Kevin_YK
有好的方案吗?只能用MQ了?
返回顶部
顶部