1.什么是WebSocket
WebSocket協議是基於TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。
2.實現原理
在實現websocket連線過程中,需要通過瀏覽器發出websocket連線請求,然后服務器發出回應,這個過程通常稱為“握手” 。在 WebSocket API,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。
3.優點
在以前的消息推送機制中,用的都是 Ajax 輪詢(polling),在特定的時間間隔由瀏覽器自動發出請求,將服務器的消息主動的拉回來,這種方式是非常消耗資源的,因為它本質還是http請求,而且顯得非常笨拙。而WebSocket 在瀏覽器和服務器完成一個握手的動作,在建立連接之后,服務器可以主動傳送數據給客戶端,客戶端也可以隨時向服務器發送數據。
4.WebSocket和Socket的區別
1.WebSocket:
websocket通訊的建立階段是依賴於http協議的。最初的握手階段是http協議,握手完成后就切換到websocket協議,並完全與http協議脫離了。建立通訊時,也是由客戶端主動發起連接請求,服務端被動監聽。通訊一旦建立連接后,通訊就是“全雙工”模式了。也就是說服務端和客戶端都能在任何時間自由得發送數據,非常適合服務端要主動推送實時數據的業務場景。交互模式不再是“請求-應答”模式,完全由開發者自行設計通訊協議。通信的數據是基於“幀(frame)”的,可以傳輸文本數據,也可以直接傳輸二進制數據,效率高。當然,開發者也就要考慮封包、拆包、編號等技術細節。
2.Socket:
服務端監聽通訊,被動提供服務;客戶端主動向服務端發起連接請求,建立起通訊。每一次交互都是:客戶端主動發起請求(request),服務端被動應答(response)。服務端不能主動向客戶端推送數據。通信的數據是基於文本格式的。二進制數據(比如圖片等)要利用base64等手段轉換為文本后才能傳輸。
5.WebSocket客戶端:
var websocket = null;
var host = document.location.host;
var username = "${loginUsername}"; // 獲得當前登錄人員的userName
// alert(username)
//判斷當前瀏覽器是否支持WebSocket
if ('WebSocket' in window) {
alert("瀏覽器支持Websocket")
websocket = new WebSocket('ws://'+host+'/mm-dorado/webSocket/'+username);
} else {
alert('當前瀏覽器 Not support websocket')
}
//連接發生錯誤的回調方法
websocket.onerror = function() {
alert("WebSocket連接發生錯誤")
setMessageInnerHTML("WebSocket連接發生錯誤");
};
//連接成功建立的回調方法
websocket.onopen = function() {
alert("WebSocket連接成功")
setMessageInnerHTML("WebSocket連接成功");
}
//接收到消息的回調方法
websocket.onmessage = function(event) {
alert("接收到消息的回調方法")
alert("這是后台推送的消息:"+event.data);
websocket.close();
alert("webSocket已關閉!")
}
//連接關閉的回調方法
websocket.onclose = function() {
setMessageInnerHTML("WebSocket連接關閉");
}
//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
window.onbeforeunload = function() {
closeWebSocket();
}
//關閉WebSocket連接
function closeWebSocket() {
websocket.close();
}
//將消息顯示在網頁上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
6.WebSocket服務端(java后台):
1.核心類:
package com.mes.util;
import

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.google.gson.JsonObject;
import net.sf.json.JSONObject;
@ServerEndpoint("/webSocket/{username}")
public class WebSocket {
private static int onlineCount = 0;
private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
private Session session;
private String username;
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) throws IOException {
this.username = username;
this.session = session;
addOnlineCount();
clients.put(username, this);
System.out.println("已連接");
}
@OnClose
public void onClose() throws IOException {
clients.remove(username);
subOnlineCount();
}
@OnMessage
public void onMessage(String message) throws IOException {
JSONObject jsonTo = JSONObject.fromObject(message);
String mes = (String) jsonTo.get("message");
if (!jsonTo.get("To