重點
創(chuàng)新互聯(lián)公司是專業(yè)的安新網(wǎng)站建設(shè)公司,安新接單;提供網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行安新網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
1、JAVA內(nèi)的WebSocket是在Java jar7.0之后才能使用的。
2、需要在JavaServer項目lib目錄下引入 javaee-api-7.0 包
|前端代碼
|后端JAVA代碼
package websocketPro;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* writer: holien Time: 2017-08-01 13:00 Intent: webSocket public class ChatRoom { private static final Map> rooms = new ConcurrentHashMap(); @OnOpen //session 是可選的參數(shù),session為與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù) public void connect(@PathParam("roomName") String roomName, Session
session) throws Exception { if (!rooms.containsKey(roomName)) { Set room = new HashSet<>(); room.add(session); rooms.put(roomName, room); } else { rooms.get(roomName).add(session); } System.out.println("建立連接 !"); } @OnClose public void disConnect(@PathParam("roomName") String roomName, Session
session) { rooms.get(roomName).remove(session); System.out.println("斷開連接!"); } @OnMessage public void receiveMsg(@PathParam("roomName") String roomName, String msg,
Session session) throws Exception { System.out.println(msg); broadcast(roomName, msg); } // 按照房間名進行廣播 public static void broadcast(String roomName, String msg) throws Exception
{ for (Session session : rooms.get(roomName)) { session.getAsyncRemote().sendText(msg); } } } |JAVA服務(wù)器目錄結(jié)構(gòu) Tip:下面簡單的解釋一下每個函數(shù)及其方法的含義和關(guān)聯(lián)。 所有WebSocket項目雙向通信的建立,都需要前端先發(fā)送給后端一個請求,并且握手成功之后才能進行通信 就和打電話一個道理。 webSocket = new WebSocket(url); 上面這個就是前端JS創(chuàng)建一個WebSocket對象 并且發(fā)送給后端(URL地址的服務(wù)器)一個通信請求 你正在向一個人打電話,并且等他接電話 @ServerEndpoint("/webSocket/ChatRoom/{roomName}") var url = "ws://172.16.245.232:8080/WebsocketPro/webSocket/mainBlock/" +
roomName; 后端java這個注釋標記了當前這個Java文件的服務(wù)器訪問地址和前端的請求的地址是一致的。 前端定義 roomName 的名稱會被后端的 {roomName} 讀取到 之前 前端的roomName定義為 MainBlock 所以在請求之后后端注釋內(nèi)的訪問路徑就變成了 /webSocket/ChatRoom/MainBlock private static final Map> rooms = new ConcurrentHashMap(); @OnOpen public void connect(@PathParam("roomName") String roomName, Session
session) throws Exception { if (!rooms.containsKey(roomName)) { Set room = new HashSet<>(); //創(chuàng)建Hash數(shù)組 的數(shù)理化對象 room.add(session); //把session對象 即用戶對象 添加到Hash對象里 rooms.put(roomName, room); //并且根據(jù)房間名添加用戶組成的 Hash對象 這里就獲取了一個用戶集 } else { rooms.get(roomName).add(session); //獲取對應(yīng)房間的 用戶集 }鄭州較好的婦科醫(yī)院 http://www.kd0371.com/ System.out.println("建立連接 !"); } 關(guān)于 ConcurrentHashMap 參考ConcurrentHashMap 此時在申請之后會被后端的 @OnOpen注釋下的方法接收到 這個時候底層WebSocket會進行和前端的握手協(xié)議 我們是看不到的 諾訪問正常并且握手成功,則服務(wù)器會自動調(diào)用這個連接方法 此時底層會向服務(wù)器發(fā)送成功握手的協(xié)議 并且前端也會調(diào)用下面這個定義的的方法 webSocket.onopen = function () { console.log("和服務(wù)器的握手連接建立...(握手)") }; 到這里為止 前端和后端建立了一個理論上永久的通信協(xié)議,只要其中一方不要斷開連接。 你成功和他打通了電話 |開始交流 webSocket.send(msg); 我們前端調(diào)用了WebSocket對象的 send() 方法 傳入要發(fā)送給后臺的消息 封裝要發(fā)送到服務(wù)端的數(shù)據(jù)一般來說JSON比較好 @OnMessage public void receiveMsg(@PathParam("roomName") String roomName, String msg,
Session session) throws Exception { System.out.println(msg); broadcast(roomName, msg); } 傳入的消息就會被后臺的 @OnMessage 標記的方法接收 @PathParam(“roomName”) String roomName 這句話的意思就是之前標記的 /webSocket/ChatRoom/{roomName} 里的 roomName 的值 String msg 這個參數(shù)就是前臺發(fā)送的消息。 Session session 這個參數(shù)在代碼中說明了就不重復解釋 在接收到消息之后就調(diào)用這個這個函數(shù)內(nèi)的一個完美自定義的方法 broadcast() public static void broadcast(String roomName, String msg) throws Exception
{ for (Session session : rooms.get(roomName)) { session.getAsyncRemote().sendText(msg); } } 這個方法調(diào)用了 session 對象里的 getAsyncRemote() 方法的 sendText(msg) 用來向之前封裝的所有對象( rooms )廣播消息 webSocket.onmessage = function (evt) { var Data = JSON.parse(evt.data) }; 接收到廣播消息之后,前端調(diào)用了 WebSocket對象的 onmessage 方法 這里的 evt 參數(shù)就是廣播的消息 但是后端傳過來的是一個對象 我們要調(diào)用這個對象的 evt.data 方法 如果是Json數(shù)據(jù) 就把它轉(zhuǎn)換成我們js能識別的對象 到這里為止來就完成了消息的交流。 要斷開請求的話,就調(diào)用 webSocket.close() 方法 ,這個時候 后臺就會自動調(diào)用 下面這個方法 @OnClose public void disConnect(@PathParam("roomName") String roomName, Session
session) { System.out.println("斷開連接!"); } 同時響應(yīng)到前端 ,調(diào)用下面這個方法 webSocket.onclose = function () { console.log("和服務(wù)器的握手連接已關(guān)閉...(分手)") webSocket = null; }; 到這里來位置完成了WebSocket 完整的雙向通信。
分享題目:基于JavaServer為后端的WebSocket雙向通信工程
轉(zhuǎn)載注明:http://weahome.cn/article/pijess.html