zoukankan      html  css  js  c++  java
  • Android 基于Netty的消息推送方案之Hello World(一)

    消息推送方案(轮询、长连接)

    轮询

    轮询:比较简单的,最容易理解和实现的就是客户端去服务器上拉信息,信息的及时性要求越高则拉信息的频率越高。客户端拉信息的触发可以是一些事件,也可以是一个定时器,不断地去查询服务器。所以这个方案的弊端也是显而易见的,在轮询的频率较高时,服务器端的压力很大,通讯的流量也很大,并且大部分时间都是做的无用功。

    长连接

    长连接:客户端和服务端维持一个长连接,服务端在有信息推送的时候,借助这个连接把信息发送到客户端。这个方案的优点是信息推送的及时性很高,基本是实时的,并且除了维持连接的心跳,不会产生额外的流量,但服务端需要维持连接,当客户端数量庞大的时候,服务器的资源消耗也会很大。本文后面提到的几个框架,都借助Java的NIO特性,缓解了服务端的压力和资源消耗,但毕竟是有连接,在性能上还是无法跟传统的HTTP无连接服务端比较。

    其他

    其他:在手机端,其实还可以有短信、邮件等方式,来进行信息推送。这些方式由于牵涉到运营商和手机操作系统的内置服务框架,限制较多,何况微信都要被收费,所以就不去考虑了。

    开源框架(Androidpn  Openfire  MINA  Netty)

    Android手机应用,信息推送的资料大多都是关于androidpn的,这是一个基于XMPP协议的Java开源信息推送方案,包括完整的服务端和客户端。服务端有Tomcat和Jetty两个版本,下载下来后配置一下数据库连接参数和IP端口就可以跑起来了。客户端则可以参考它的示例,把Android代码拿过来用即可。所以这是一个针对android应用的高度定制版,如果要对服务端进行修改调整,动的地方比较多。
    Openfire则适用的范围更广,是基于XMPP协议的开源实时协作服务器,可以通过它简单地搭建一个IM平台。Androidpn是在Openfire上做了简化,只针对Android的消息推送。从这里也可看出,就消息推送来说,用XMPP协议有点杀鸡用牛刀了。
    MINA和Netty是Socket框架,是同一个作者的,架构差别不大。MINA归Apache管,Openfire和Androidpn都是用的MINA;Netty则归JBOSS管,从我检索到的资料来看,更多偏向于Netty,大致是认为Netty的性能稍优,文档与例子更完整。

    消息推送服务(GCM  C2DM  百度云推送)

    其实也有一些现存的云推送服务可供选择,并不一定要自己来搭建一个平台。谷歌的GCM,Google Cloud Messaging,是C2DM的升级版,Android终端用的话,本来是最合适不过了,但在国内大家都懂的,玩的是《墙来了》游戏,有时你可以钻过去,有时会被撞落水,所以不靠谱啊。百度和其他的一些公司,也提供云推送服务,好像没有免费的。谷歌应该比较郁闷吧,Android上的搜索、地图、邮件、推送等等,在国内都是为他人作嫁衣裳。

    回归本质-协议(TCP/IP  HTTP   XMPP   MQTT)

    没想到一个消息推送可以有这么多“内涵”啊。本质上,不就是维持一个连接,服务端需要推送消息的时候就通过这些连接往客户端传信息嘛。仔细想来,要想灵活和可控,最好的方式还是自己基于TCP/IP协议来实现消息推送。再往上一点,就是在HTTP协议上来实现,这样的话既可以穿越防火墙,也可以通过AJAX实现网页上的消息推送。Servlet 3.0的异步请求支持,其实也是可以用来做消息推送的。XMPP和MQTT协议要复杂些,最好选一个开源框架来搭建。

    Netty简介

    Netty是一个异步的,事件驱动的网络编程框架和工具,是一个基于NIO的客户,服务器端编程框架,使用Netty可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

    Netty下载

    官网下载或者CSDN下载

    Netty入门(Hello World)

    在Eclipse中新建java工程,将netty.jar包放入lib目录下,然后build path -->add to build path,目录结构如下

    客户端代码如下

    [java] view plaincopy
     
    1. public class HelloClient {  
    2.     public static void main(String args[]) {  
    3.         // Client服务启动器  
    4.         ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));  
    5.         // 设置一个处理服务端消息和各种消息事件的类(Handler)  
    6.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
    7.             @Override  
    8.             public ChannelPipeline getPipeline() throws Exception {  
    9.                 return Channels.pipeline(new HelloClientHandler());  
    10.             }  
    11.         });  
    12.         // 连接到本地的8000端口的服务端  
    13.         bootstrap.connect(new InetSocketAddress("127.0.0.1", 8000));  
    14.     }  
    15.   
    16.     private static class HelloClientHandler extends SimpleChannelHandler {  
    17.         @Override  
    18.         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {  
    19.             System.out.println("Hello world, I'm client.");  
    20.         }  
    21.     }  
    22. }  

    服务端代码如下

    [java] view plaincopy
     
    1. public class HelloServer {  
    2.     public static void main(String[] args) {  
    3.         // Server服务启动器  
    4.         ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));  
    5.         // 设置一个处理客户端消息和各种消息事件的类(Handler)  
    6.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
    7.             @Override  
    8.             public ChannelPipeline getPipeline() throws Exception {  
    9.                 return Channels.pipeline(new HelloServerHandler());  
    10.             }  
    11.         });  
    12.         // 开放8000端口供客户端访问。  
    13.         bootstrap.bind(new InetSocketAddress(8000));  
    14.     }  
    15.   
    16.     private static class HelloServerHandler extends SimpleChannelHandler {  
    17.         @Override  
    18.         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {  
    19.             System.out.println("Hello world, I'm server.");  
    20.         }  
    21.     }  
    22. }  

    首先运行服务端,然后运行客户端,效果如下


    下面我会进一步讲解Netty的使用。

  • 相关阅读:
    java web环境搭建
    java动手动脑异常处理
    java动手动脑多态
    python全栈开发day67--字段类型、字段属性、ORM回顾
    python全栈开发day66-视图系统、路由系统
    python全栈开发day65-templates:tags、母版和继承、组件、静态文件相关、simple_tag和inclusion_tag
    python全栈开发day64-模板-变量和(.)的使用,filters和自定义filter
    Django Models的数据类型汇总
    nginx反向代理uwsgi django服务器搭建总结
    Centos更新yum源
  • 原文地址:https://www.cnblogs.com/dongweiq/p/4019433.html
Copyright © 2011-2022 走看看