轮询:比较简单的,最容易理解和实现的就是客户端去服务器上拉信息,信息的及时性要求越高则拉信息的频率越高。客户端拉信息的触发可以是一些事件,也可以是一个定时器,不断地去查询服务器。所以这个方案的弊端也是显而易见的,在轮询的频率较高时,服务器端的压力很大,通讯的流量也很大,并且大部分时间都是做的无用功。
长连接:客户端和服务端维持一个长连接,服务端在有信息推送的时候,借助这个连接把信息发送到客户端。这个方案的优点是信息推送的及时性很高,基本是实时的,并且除了维持连接的心跳,不会产生额外的流量,但服务端需要维持连接,当客户端数量庞大的时候,服务器的资源消耗也会很大。本文后面提到的几个框架,都借助Java的NIO特性,缓解了服务端的压力和资源消耗,但毕竟是有连接,在性能上还是无法跟传统的HTTP无连接服务端比较。
没想到一个消息推送可以有这么多“内涵”啊。本质上,不就是维持一个连接,服务端需要推送消息的时候就通过这些连接往客户端传信息嘛。仔细想来,要想灵活和可控,最好的方式还是自己基于TCP/IP协议来实现消息推送。再往上一点,就是在HTTP协议上来实现,这样的话既可以穿越防火墙,也可以通过AJAX实现网页上的消息推送。Servlet 3.0的异步请求支持,其实也是可以用来做消息推送的。XMPP和MQTT协议要复杂些,最好选一个开源框架来搭建。
Netty是一个异步的,事件驱动的网络编程框架和工具,是一个基于NIO的客户,服务器端编程框架,使用Netty可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
在Eclipse中新建java工程,将netty.jar包放入lib目录下,然后build path -->add to build path,目录结构如下
客户端代码如下
public class HelloClient { public static void main(String args[]) { // Client服务启动器 ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // 设置一个处理服务端消息和各种消息事件的类(Handler) bootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new HelloClientHandler()); } }); // 连接到本地的8000端口的服务端 bootstrap.connect(new InetSocketAddress("127.0.0.1", 8000)); } private static class HelloClientHandler extends SimpleChannelHandler { @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { System.out.println("Hello world, I'm client."); } } }服务端代码如下
public class HelloServer { public static void main(String[] args) { // Server服务启动器 ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // 设置一个处理客户端消息和各种消息事件的类(Handler) bootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new HelloServerHandler()); } }); // 开放8000端口供客户端访问。 bootstrap.bind(new InetSocketAddress(8000)); } private static class HelloServerHandler extends SimpleChannelHandler { @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { System.out.println("Hello world, I'm server."); } } }首先运行服务端,然后运行客户端,效果如下
下面我会进一步讲解Netty的使用。
原文地址:http://blog.csdn.net/wuchuang127/article/details/39577583