Netty-SocketIO是一个开源的、基于Netty的、Java版的即时消息推送项目。通过Netty-SocketIO,我们可以轻松的实现服务端主动向客户端推送消息的场景,比如说股票价格变化、K线图、消息提醒等。它和websocket有相同的作用,只不过Netty-SocketIO可支持所有的浏览器。
GitHub项目地址为: https://github.com/mrniko/netty-socketio。
Socket.IO除了支持WebSocket通讯协议外,还支持许多种轮询(Polling)机制以及其它实时通信方式,并封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。Socket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、AJAX multipart streaming、持久Iframe、JSONP轮询等。Socket.IO能够根据浏览器对通讯机制的支持情况自动地选择最佳的方式来实现网络实时应用。
###一、下载Netty-SocketIO
socket.io-client-master
netty-socketio-master
netty-socketio-demo-master
从netty-socketio的git上可下载到以上三个压缩包,分别对应的是web 客户端的所需文件、netty socketio的java服务端实现、以及对应的可以应用web推送的demo。
###二、部署server的资源项目
从git上下载的socketio server压缩包中没有项目所需的jar包,我是自己新建了一个项目,本来上传到了CSDN的代码库里了,但写博客的时候怎么也打不开了,那么只能提供对应项目导航图,同时提供jar包的下载地址,需要的可动手去获得。
从http://mvnrepository.com/网站上课下载到需要的所有jar包。
然后将jar包添加到项目中。
切记jdk的版本一定要在1.7以上,我在本地环境中用的1.7,但是服务器上一直用的是1.6,部署项目的时候没有注意,导致服务端可以接收到客户端的socketio 的connect,但是客户端的response相应中却连接不通,开始的时候以为是跨域问题导致的,搜了好多帖子,但问题根本就是不是跨域引起的,jdk的版本换成1.7就ok了,因为netty的nio是基于java的1.7的。
###三、应用server
在需要应用socketio的项目上右键,为项目添加socketio项目支持(注意红色标出的)。
新建main类。
public static void main(String[] args) throws InterruptedException { Configuration config = new Configuration(); config.setHostname("localhost"); config.setPort(10015); SocketIOServer server = new SocketIOServer(config); server.addConnectListener(new ConnectListener() {// 添加客户端连接监听器 @Override public void onConnect(SocketIOClient client) { logger.info(client.getRemoteAddress() + " web客户端接入"); client.sendEvent("helloPush", "hello"); } }); // 握手请求 server.addEventListener("helloevent", HelloUid.class, new DataListener<HelloUid>() { @Override public void onData(final SocketIOClient client, HelloUid data, AckRequest ackRequest) { // 握手 if (data.getMessage().equals("hello")) { int userid = data.getUid(); logger.info(Thread.currentThread().getName() + "web读取到的userid:" + userid); // send message back to client with ack callback // WITH data client.sendEvent("hellopush", new AckCallback<String>(String.class) { @Override public void onSuccess(String result) { logger.info("ack from client: " + client.getSessionId() + " data: " + result); } }, sessionTime); } else { logger.info("行情接收到了不应该有的web客户端请求1111..."); } } }); server.start(); Thread.sleep(Integer.MAX_VALUE); server.stop(); }
当client通过ip和端口连接到server后,会构造一个SocketIOClient client的对象,在实际的应用中,可以将该client保存起来,通过client.sendEvent("helloPush", "hello");就可以向client端发送相应的数据了。
###四、应用client
####①、引入socket.io.js
<script type="text/javascript" src="${ctx}/components/socketio/socket.io.js"></script>
####②、创建connection的公共方法
function connectQuotation(uid, callback) { // 链接行情server socket = io.connect('http://localhost:10015'); // 如果用户在web端登陆,那么发送握手请求 if (uid) { // 连接上server后 socket.on('connect', function() { // 发送握手请求 var jsonObject = { uid : parseInt(uid), message : "hello" }; this.emit('helloevent', jsonObject); this.on('hellopush', function(data, ackServerCallback, arg1) { // base64转码的数据,可忽视 YUNM.session = { sessionId : $.base64.atob(data.sessionId), time : $.base64.atob(data.time) }; if (ackServerCallback) { ackServerCallback('server message was delivered to client!'); } }); }); } // 如果web端session超时,socket断开,10分钟扫描一次 int = window.setInterval(function() { // 我是通过ajax判断session超时的,你也可以通过其他方式 $.ajax({ type : 'POST', url : common.ctx + "/getSessionTimeout", dataType : "json", cache : false, success : function(json) { var timeout = parseInt(json.message); // session超时后,socket断开,服务端就可以监听到释放资源 if (timeout == 0) { socket.disconnect(); } }, error : function() { socket.disconnect(); // 清除 window.clearInterval(int); } }); }, YUNM._set.interval); callback(); }
####③、需要web推送的页面进行socketio的连接
$(function() { connectQuotation($("#global_uid").val(), function() { socket.on("pushQuotation", function(message) { if (message.type == "dealOrder") { var msg = message.response.result; // 输出服务端消息 YUNM.debug(msg); } }); }); });