Android网络编程selector模式

前几天编写一个App客户端,是一个长连接,我需要在app里开启一个服务,不断地接收服务器传来的消息,进行处理。我在Android Service里开启了一个线程,不断地轮询服务端传给我的消息。这时出现了一个问题,因为服务端大多时候不给我发消息,我肯定要在读服务器消息里的线程sleep一段时间在读。这时我问了我们领导,领导说用selector模式,不用等。
selector模式主要就是linux内核帮你监听端口,如果此端口有消息进来,马上就通知你,所以不用等。(不知道理解对不对,如果有误请指点,谢谢)。

下面上代码。

 SocketChannel ch = null;
 SocketAddress addr = new InetSocketAddress(172.16.3.194, 11904);
 ch = SocketChannel.open(addr);
 Selector selector=Selector.open();
 ch.configureBlocking(false);
 ch.register(selector, SelectionKey.OP_READ| SelectionKey.OP_CONNECT);
 MyApplication.instance.selector=selector;
 ApiSktChannel bfch = new ApiSktChannel(ch);
 bfch.writeMsg(RssMap.toXml("login_req", new RssMap().push("userid", loginEntity.getUserName()).push("passwd", loginEntity.getMD5_PWD()), false));
                    MyApplication.instance.apiSktChannel=bfch;
                    MyApplication.instance.socketChannel=ch;   

这些步骤主要是先创建一个Socket通道,然后把这个通道注册到Selector上,并把此通道和Selector保存到MyApplication中,方便service中直接获取。
注册时有四个参数 accept read write connect 我这里其实只关注读,所以我就注册了读。读的意思就是当有可读的消息,内核就会通知你去读。
在开始注册之前一定要先把socket设置成非阻塞模式,因为会在selector中阻塞。

下面只需要调用阻塞方法

selector.select()

此方法在没有发生你注册时的事件(accept write read connect)发生时,一直阻塞,但当有您注册的事件发生后就会执行下面的代码。所以我们只要在service中的while(true)中加上这行代码,就消除了延时。而且selector上可以注册多个socket通道哈。

猜你喜欢

转载自blog.csdn.net/qq_34557284/article/details/60319896
今日推荐