为了账号安全,请及时绑定邮箱和手机立即绑定

netty如何实现向客户端主动发送消息

netty如何实现向客户端主动发送消息

湖上湖 2019-01-16 19:27:46
需求场景:智能家居网关(以下简称gateway),需要和netty服务器通讯(以下简称netty),netty和gateway之间需要保持长连接(换句话说,netty和gateway之间都会主动给对方发送消息) 碰到的问题:netty作为服务器端如何主动的向gateway发送消息,我尝试当每个gateway连接到netty(TCP/IP)时使用一个map把该channelSocket的id和该channelSocket绑定在一起 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String uuid = ctx.channel().id().asLongText(); GatewayService.addGatewayChannel(uuid, (SocketChannel)ctx.channel()); System.out.println("a new connect come in: " + uuid); } GatewayService其实就是一个ConcurrentHashMap public class GatewayService { private static Map<String, SocketChannel> map = new ConcurrentHashMap<>(); public static void addGatewayChannel(String id, SocketChannel gateway_channel){ map.put(id, gateway_channel); } public static Map<String, SocketChannel> getChannels(){ return map; } public static SocketChannel getGatewayChannel(String id){ return map.get(id); } public static void removeGatewayChannel(String id){ map.remove(id); } } 我在服务器端尝试每间隔一段时间loop这个ConcurrentHashMap如果里面已经有绑定的channelSocket,就使用write方法向客户端发送消息 Runnable sendTask = new Runnable() { @Override public void run() { sendTaskLoop: for(;;){ System.out.println("task is beginning..."); try{ Map<String, SocketChannel> map = GatewayService.getChannels(); Iterator<String> it = map.keySet().iterator(); while (it.hasNext()) { String key = it.next(); SocketChannel obj = map.get(key); System.out.println("channel id is: " + key); System.out.println("channel: " + obj.isActive()); obj.writeAndFlush("hello, it is Server test header ping"); } }catch(Exception e){break sendTaskLoop;} try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; new Thread(sendTask).start(); 理论上客户端应该是可以接受到我发送的消息,但是我观察了一下源代码,发现writeAndFlush这个方法最终会被handler触发,于是我又在handler中覆写了write方法 @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { System.out.println("write handler"); ctx.writeAndFlush(msg); } 可是最终结果客户端并没有收到任何消息,请问netty如何主动向客户端发送消息?
查看完整描述

6 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

可以大概猜测到是服务端没有编码器,因此根本发不出去
从贴出的代码里可以看到代码里往客户端发消息时有两种方式:

obj.writeAndFlush("hello, it is Server test header ping");

ctx.writeAndFlush(msg);//Object

在netty里,进出的都是ByteBuf,楼主应确定服务端是否有对应的编码器,将字符串转化为ByteBuf

查看完整回答
反对 回复 2019-02-12
?
MYYA

TA贡献1868条经验 获得超4个赞

推荐使用ChannelGroup管理客户端。领导服务器端推送不出去可能是因为没有编码器的原因,ctx.writeAndFlush是不能直接写串类型的。

查看完整回答
反对 回复 2019-02-12
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

您好我照着您这么做为什么一个客户端会出现多个map呢

查看完整回答
反对 回复 2019-02-12
  • 6 回答
  • 0 关注
  • 3982 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号