在WEB项目中,服务器向WEB页面推送消息是一种常见的业务需求。PC端的推送技术可以使用socket建立一个长连接来实现。传统的web服务都是客户端发出请求,服务端给出响应。但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推送消息到客户端。最近的预警系统中,需要服务端向预警系统推送商品行情和K线相关的数据,所以对常用的WEB端推送方式进行调研。常见的手段主要包括以下几种:
- 轮询(俗称“拉”,polling):Ajax 隔一段时间向服务器发送请求,询问数据是否发生改变,从而进行增量式的更新。轮询的时间间隔成了一个问题:间隔太短,会有大量的请求发送到服务器,会对服务器负载造成影响;间隔太长业务数据的实时性得不到保证。连。使用轮询的优点是实现逻辑简单,缺点是无效请求的数量多,在用户量较大的情况下,服务器负载较高。因此轮询的方式通常在并发数量较少、并且对消息实时性要求不高的情况下使用。
- 长轮询技术(long-polling):客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息或超时(设置)才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。长轮询技术的优点是消息实时性高,无消息的情况下不会进行频繁的请求;缺点是服务端维持和客户端的连接会消耗掉一部分资源。
- 插件提供socket方式:比如利用Flash XMLSocket,Java Applet套接口,Activex包装的socket。优点是对原生socket的支持,和PC端和移动端的实现方式相似;缺点是浏览器需要安装相应的插件。
- WebSocket:是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。其优点是更好的节省服务器资源和带宽并达到实时通讯;缺点是目前还未普及,浏览器支持不好;
综上,考虑到浏览器兼容性和性能问题,采用长轮询(long-polling)是一种比较好的方式。netty-socketio是一个开源的Socket.io服务器端的一个java的实现, 它基于Netty框架。 项目地址为:
https://github.com/mrniko/netty-socketio
以下基于Netty-socketIO实现一个简单的聊天室功能,首先引入依赖:
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
定义Listen,用户监听Oncennect、disconnect和OnMSG事件:
package com.ps.learn.socketio.service;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.ps.learn.socketio.entity.MsgBean;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* Created by Administrator on 2018/7/21 0021.
* 定义Listen,用户监听Oncennect、disconnect和OnMSG事件:
*/
@Service("eventListenner")
public class EventListenner {
@Resource(name = "clientCache")
private SocketIOClientCache clientCache;
@Resource(name = "socketIORe