账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    netty如何实现向客户端主动发送消息
    18
    0

    需求场景:
    智能家居网关(以下简称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如何主动向客户端发送消息?

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 孤单哑剧 普通会员 1楼
      502 Bad Gateway

      502 Bad Gateway


      nginx
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部