在WEB項目中,服務器向WEB頁面推送消息是一種常見的業務需求。PC端的推送技術可使用socket創建一個長鏈接來實現。傳統的web服務都是客戶端發出請求,服務端給出響應。可是如今直觀的要求是容許特定時間內在沒有客戶端發起請求的狀況下服務端主動推送消息到客戶端。最近的預警系統中,須要服務端向預警系統推送商品行情和K線相關的數據,因此對經常使用的WEB端推送方式進行調研。常見的手段主要包括如下幾種:
綜上,考慮到瀏覽器兼容性和性能問題,採用長輪詢(long-polling)是一種比較好的方式。netty-socketio是一個開源的Socket.io服務器端的一個java的實現, 它基於Netty框架。 項目地址爲: https://github.com/mrniko/net...javascript
如下基於Netty-socketIO實現一個簡單的聊天室功能,首先引入依賴:html
<dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.3</version> </dependency>
定義Listen,用戶監聽Oncennect、disconnect和OnMSG事件:java
@Service("eventListenner") public class EventListenner { @Resource(name = "clientCache") private SocketIOClientCache clientCache; @Resource(name = "socketIOResponse") private SocketIOResponse socketIOResponse; @OnConnect public void onConnect(SocketIOClient client) { System.out.println("創建鏈接"); } @OnEvent("OnMSG") public void onSync(SocketIOClient client, MsgBean bean) { System.out.printf("收到消息-from: %s to:%s\n", bean.getFrom(), bean.getTo()); clientCache.addClient(client, bean); SocketIOClient ioClients = clientCache.getClient(bean.getTo()); System.out.println("clientCache"); if (ioClients == null) { System.out.println("你發送消息的用戶不在線"); return; } socketIOResponse.sendEvent(ioClients,bean); } @OnDisconnect public void onDisconnect(SocketIOClient client) { System.out.println("關閉鏈接"); } }
定義消息發送類:jquery
@Service("socketIOResponse") public class SocketIOResponse { public void sendEvent(SocketIOClient client, MsgBean bean) { System.out.println("推送消息"); client.sendEvent("OnMSG", bean); } }
定義Cache用於保存全部和Web端的鏈接:git
@Service("clientCache") public class SocketIOClientCache { //String:EventType類型 private Map<String,SocketIOClient> clients=new ConcurrentHashMap<String,SocketIOClient>(); //用戶發送消息添加 public void addClient(SocketIOClient client,MsgBean msgBean){ clients.put(msgBean.getFrom(),client); } //用戶退出時移除 public void remove(MsgBean msgBean) { clients.remove(msgBean.getFrom()); } //獲取全部 public SocketIOClient getClient(String to) { return clients.get(to); } }
定義Server:github
//繼承InitializingBean,使Spring加載完配置文件,自動運行以下方法 @Service("chatServer") public class ChatServer implements InitializingBean{ @Resource private EventListenner eventListenner; public void afterPropertiesSet() throws Exception { Configuration config = new Configuration(); config.setPort(9098); SocketConfig socketConfig = new SocketConfig(); socketConfig.setReuseAddress(true); socketConfig.setTcpNoDelay(true); socketConfig.setSoLinger(0); config.setSocketConfig(socketConfig); config.setHostname("localhost"); SocketIOServer server = new SocketIOServer(config); server.addListeners(eventListenner); server.start(); System.out.println("啓動正常"); } }
定義MSGbean:web
public class MsgBean { private String from; private String to; private String content; public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "MsgBean [from=" + from + ", to=" + to + ", content=" + content + "]"; } }
定義Main:瀏覽器
public class Main { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/applicationContext-push.xml"); context.start(); context.getBean("chatServer"); } }
HTML頁面:服務器
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Socketio chat</title> <script src="./jquery-1.7.2.min.js" type="text/javascript"></script> <script type="text/javascript" src="./socket.io.js"></script> <style> body { padding: 20px; } #console { height: 400px; overflow: auto; } .username-msg { color: orange; } .connect-msg { color: green; } .disconnect-msg { color: red; } .send-msg { color: #888 } </style> </head> <body> <h1>Netty-socketio chat demo</h1> <br /> <div id="console" class="well"></div> <form class="well form-inline" onsubmit="return false;"> <input id="from" class="input-xlarge" type="text" placeholder="from. . . " /> <input id="to" class="input-xlarge" type="text" placeholder="to. . . " /> <input id="content" class="input-xlarge" type="text" placeholder="content. . . " /> <button type="button" onClick="sendMessage()" class="btn">Send</button> <button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button> </form> </body> <script type="text/javascript"> var socket = io.connect('http://localhost:9098'); socket.on('connect',function() { output('<span class="connect-msg">Client has connected to the server!</span>'); }); socket.on('OnMSG', function(data) { output('<span class="username-msg">' + data.content + ' : </span>'); }); socket.on('disconnect',function() { output('<span class="disconnect-msg">The client has disconnected! </span>'); }); function sendDisconnect() { socket.disconnect(); } function sendMessage() { var from = $("#from").val(); var to = $("#to").val(); var content = $('#content').val(); socket.emit('OnMSG', { from : from, to : to, content : content }); } function output(message) { var currentTime = "<span class='time' >" + new Date() + "</span>"; var element = $("<div>" + currentTime + " " + message + "</div>"); $('#console').prepend(element); } </script> </html>
相關文章:
基於netty-socketio的web推送服務
gitee源代碼Socket.io 和 netty-socketio使用網絡