WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通信的網絡技術。依靠這種技術能夠實現客戶端和服務器端的長鏈接,雙向實時通訊。
特色:
事件驅動
異步
使用ws或者wss協議的客戶端socketjava
可以實現真正意義上的推送功能web
缺點:數組
少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別。瀏覽器
websocket容許經過JavaScript創建與遠程服務器的鏈接,從而實現客戶端與服務器間雙向的通訊。在websocket中有兩個方法:
一、send() 向遠程服務器發送數據
二、close() 關閉該websocket連接
websocket同時還定義了幾個監聽函數
一、onopen 當網絡鏈接創建時觸發該事件
二、onerror 當網絡發生錯誤時觸發該事件
三、onclose 當websocket被關閉時觸發該事件
四、onmessage 當websocket接收到服務器發來的消息的時觸發的事件,也是通訊中最重要的一個監聽事件。msg.data
websocket還定義了一個readyState屬性,這個屬性能夠返回websocket所處的狀態:
一、CONNECTING(0) websocket正嘗試與服務器創建鏈接
二、OPEN(1) websocket與服務器已經創建鏈接
三、CLOSING(2) websocket正在關閉與服務器的鏈接
四、CLOSED(3) websocket已經關閉了與服務器的鏈接安全
websocket的url開頭是ws,若是須要ssl加密可使用wss,當咱們調用websocket的構造方法構建一個websocket對象(new WebSocket(url))的以後,就能夠進行即時通訊了。服務器
<script type="text/JavaScript"> function init() { var websocket = null; var loginuserid=$("#userid").val(); console.log(loginuserid); var strs= new Array(); //定義一數組 //判斷當前瀏覽器是否支持WebSocket if('WebSocket' in window){ websocket = new WebSocket("ws://110.56.17.4/websocket?"+loginuserid); } else{ alert('Not support websocket'); } //鏈接發生錯誤的回調方法 websocket.onerror = function(){ setMessageInnerHTML("error"); }; //鏈接成功創建的回調方法 websocket.onopen = function(event){ setMessageInnerHTML("open"); }; //接收到消息的回調方法 websocket.onmessage = function(event){ setMessageInnerHTML(event.data); }; //鏈接關閉的回調方法 websocket.onclose = function(){ setMessageInnerHTML("close"); }; //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。 window.onbeforeunload = function(){ websocket.close(); }; //將消息顯示在網頁上 function setMessageInnerHTML(innerHTML){ //document.getElementById('message').innerHTML += innerHTML + '<br/>'; if(innerHTML=="一級告警") { $("#soundid1").empty(); var div = document.getElementById('soundid1'); div.innerHTML = '<audio src="'+"<%= path %>/jsp/sound/ALARM1.WAV"+'" hidden="true" autoplay="true" loop="false"></audio>'; } else if(innerHTML=="二級告警") { $("#soundid1").empty(); var div = document.getElementById('soundid1'); if(div!=null) { div.innerHTML = '<audio src="'+"<%= path %>/jsp/sound/ALARM3.WAV"+'" hidden="true" autoplay="true" loop="false"></audio>'; } } } //關閉鏈接 function closeWebSocket(){ websocket.close(); } //發送消息 function send(){ var message = document.getElementById('text').value; websocket.send(message); } } </script>
package com.maven.websocket; import java.io.IOException; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/websocket") public class MyWebSocket{ //與某個客戶端的鏈接會話,須要經過它來給客戶端發送數據 private Session session; //靜態變量,用來記錄當前在線鏈接數。應該把它設計成線程安全的。 private static int onlineCount = 0; /** * 鏈接創建成功調用的方法 * @param session 可選的參數。session爲與某個客戶端的鏈接會話,須要經過它來給客戶端發送數據 * @throws Exception */ @OnOpen public void onOpen(Session session) throws Exception{ this.session = session; WebSocketMapUtil.put(session.getQueryString(),this); addOnlineCount(); //在線數加1 System.out.println("有新鏈接加入!當前在線人數爲" + getOnlineCount()); } /** * 鏈接關閉調用的方法 * @throws Exception */ @OnClose public void onClose() throws Exception{ //從map中刪除 WebSocketMapUtil.remove(session.getQueryString()); subOnlineCount(); //在線數減1 System.out.println("有一鏈接關閉!當前在線人數爲" + getOnlineCount()); } /** * 收到客戶端消息後調用的方法 * @param message 客戶端發送過來的消息 * @param session 可選的參數 * @throws IOException */ @OnMessage public void onMessage(String message, Session session) throws IOException { String sendUserID = message.split("[|]")[1]; String sendMessage = message.split("[|]")[0]; try { if (WebSocketMapUtil.get(sendUserID) != null) { WebSocketMapUtil.get(sendUserID).sendMessage(sendMessage); } else { System.out.println("當前用戶不在線!"+WebSocketMapUtil.get(sendUserID)+sendUserID); } } catch (IOException e) { e.printStackTrace(); } /*try { MyWebSocket myWebSocket= ((MyWebSocket) WebSocketMapUtil.get(session.getQueryString().replace("service","client"))); if(myWebSocket != null){ myWebSocket.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); }*/ } /** * 發生錯誤時調用 * @param session * @param error */ @OnError public void onError(Session session, Throwable error){ error.printStackTrace(); } /** * 發送消息方法。 * @param message * @throws IOException */ public void sendMessage(String message) throws IOException{ this.session.getBasicRemote().sendText(message); } /** * 羣發消息方法。 * @param message * @throws IOException */ public void sendMessageAll(String message) throws IOException{ for(MyWebSocket myWebSocket : WebSocketMapUtil.getValues()){ myWebSocket.sendMessage(message); } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { MyWebSocket.onlineCount++; } public static synchronized void subOnlineCount() { MyWebSocket.onlineCount--; } }
package com.maven.websocket; import java.io.IOException; import java.net.URI; import javax.websocket.ClientEndpoint; import javax.websocket.ContainerProvider; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.WebSocketContainer; @ClientEndpoint public class MyClient { private Session session; @OnOpen public void onOpen(Session session) throws IOException { this.session = session; } @OnMessage public void onMessage(String message) { } @OnError public void onError(Throwable t) { t.printStackTrace(); } /** * 鏈接關閉調用的方法 * @throws Exception */ @OnClose public void onClose() throws Exception{ } /** * 關閉連接方法 * @param message * @throws IOException */ public void closeSocket() throws IOException{ this.session.close(); } /** * 發送消息方法。 * @param message * @throws IOException */ public void sendMessage(String message) throws IOException{ this.session.getBasicRemote().sendText(message); } //啓動客戶端並創建連接 public void start(String uri) { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); try { this.session = container.connectToServer(MyClient.class, URI.create(uri)); } catch (Exception e) { e.printStackTrace(); } } }
package com.maven.websocket; import java.io.IOException; public class MyClientApp { public static void main(String[] args){ MyClient client = new MyClient(); client.start(new WebSocketMapUtil().url); try { client.sendMessage("一級告警|12132313"); client.closeSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.maven.websocket; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; public class WebSocketMapUtil { public String url = "ws://110.56.17.4/websocket?service123"; public static ConcurrentMap<String, MyWebSocket> webSocketMap = new ConcurrentHashMap<String, MyWebSocket>(); public static void put(String key, MyWebSocket myWebSocket){ webSocketMap.put(key, myWebSocket); } public static MyWebSocket get(String key){ return webSocketMap.get(key); } public static void remove(String key){ webSocketMap.remove(key); } public static Collection<MyWebSocket> getValues(){ return webSocketMap.values(); } }