王雄兵在路上 2017-01-11 04:36 采纳率: 29.6%
浏览 4522

netty中怎么实现无限循环给每个客户端发数据?

正在做一个netty服务端,业务是这样的:客户端发数据给服务端,服务端收到之后发一条反馈数据回去;另外服务端需要实时查询数据库,如果有数据就发送给对应客户端,5秒循环一次,我把这两个业务写在同一个channelRead中,结果后者经常出现多次发送数据的情况,好像是多个线程都在执行这个循环,执行的周期不是5秒,5秒内执行了多次,也就是一条数据发了多次且次数不定,不知道是哪里的问题,感觉是自定义线程runnable和netty线程组之间没有协调工作,不知道怎么解决

 public class MyHandler extends ChannelHandlerAdapter {


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception 
            {
            01接收客户端数据,并给予反馈,代码略


            //02每五秒钟自动遍历一次数据库,将策略数据发送至指定客户端
        Runnable send = new Runnable() {
            @Override
            public void run() {
                Mysend:
                    //for无限循环
                    for(;;)
                    {
                        try{                
                            Convertion con=new Convertion();
                            gettacticsdata data=new gettacticsdata();
                            //读取存储在Map中已登录用户ID
                            Map<String, SocketChannel> map = Mymap.getChannels();

                            Iterator<String> it = map.keySet().iterator();
                            //for(int m=0;m<map.size();m++)
                            while (it.hasNext()) 
                            {
                                System.out.println("Map集合大小为:"+map.size());
                                String key = it.next();
                                System.out.println("key:"+key);
                                SocketChannel obj = map.get(key);
                                //判断当前客户是否在线,如果在线就传数据,不在就删除存储在Map中的登录信息
                                if(obj.isActive()==true)
                                {
                                    data.updatelwzt(key);
                                    //查询需要下发的策略B数据
                                    ArrayList Bal=data.GetBdata(key);
                                    //判断是否有需要下发的策略
                                    if(Bal.size()>0)
                                    {
                                        for(int i=0;i<Bal.size();i++)
                                        {
                                            tacticsBdata Bl=(tacticsBdata) Bal.get(i);
                                            byte[] Bdata=con.GetBdata(Bl);
                                            //SocketChannel obj = map.get(key);
                                            if(Bdata.length==32){
                                                ByteBuf Bsend =Unpooled.copiedBuffer(Bdata);
                                                obj.writeAndFlush(Bsend);
                                            }
                                        }       
                                    }
                                }else
                                {
                                    System.out.println("此ChannelID已掉线: " + obj);
                                    String resultdk=data.updatelwztdk(key);
                                    map.remove(key);
                                    obj.close();
                                }
                            }
                        }
                        catch(Exception e)
                        {
                            break Mysend;
                        }
                        try {
                            //线程休眠5秒钟后再次启动
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            //e.printStackTrace();
                        }
                    }
            }
        };
        new Thread(send).start();

            }
            @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
    }
  • 写回答

1条回答

  • 强化脑细胞 2017-01-11 07:12
    关注

    我也正在做这个类似的通信,你的问题出现在,你从数据库获取的部分,你是一下把数据库中所有需要推送回客户端的数据都获取出来,然后遍历。因为你每次都是这样的操作,还有间隔几秒就会再次执行,但是当你数据库数据多的时候可能间隔的时间的处理不完所有的数据库命令,然后会再次获取执行,所以会重复。 解决方式:每次从数据库中获取一条,操作完,清除,下次也就几秒的时间,完全不影响大局,然后在获取一条,再操作

    评论

报告相同问题?

悬赏问题

  • ¥15 MATLAB动图的问题
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名