文章目錄
??一、技術(shù)介紹
線上演示地址: http://chat.breez.work
實(shí)時(shí)通信 (Instant Messaging,簡(jiǎn)稱IM)是一個(gè) 實(shí)時(shí) 通信系統(tǒng),允許兩人或多人使用網(wǎng)絡(luò)實(shí)時(shí)的傳遞 文字消息 、 文件 、 語(yǔ)音 與 視頻交流 。[4]
場(chǎng)景再現(xiàn):
- ??微信聊天
- ??QQ聊天
- ??網(wǎng)站在線客服
??1.1 客戶端WebSocket
WebSocket 對(duì)象提供了用于創(chuàng)建和管理 WebSocket 連接,以及可以通過該連接 發(fā)送 和 接收數(shù)據(jù) 的 API。使用 WebSocket() 構(gòu)造函數(shù)來構(gòu)造一個(gè) WebSocket。[1]
構(gòu)造函數(shù)如下所示:
const webSocket = WebSocket(url[, protocols])
例子如下:
const webSocket = new WebSocket(“ws://42.193.120.86:3688/ws/小明/翠花”)
??1.1.1 函數(shù)
1、 webSocket.send()
該函數(shù)用于向服務(wù)端發(fā)送一條消息,例子如下:
webSocket.send(“Hello server!”);
2、 webSocket.close()
該函數(shù)用于關(guān)閉客戶端與服務(wù)端的連接,例子如下:
webSocket.close();
??1.1.2事件
1、webSocket.onopen
該事件用于監(jiān)聽客戶端與服務(wù)端的連接狀態(tài),如果客戶端與服務(wù)端 連接成功 則該事件觸發(fā),例子如下:
webSocket.onopen = function(event) { console.log(“連接已經(jīng)建立,可以進(jìn)行通信”);};
2、webSocket.onclose
如果服務(wù)端與客戶端連接斷開,那么此事件出發(fā),例子如下:
webSocket.onclose = function(event) { console.log(“連接已經(jīng)關(guān)閉”);};
3、webSocket: message event
該事件用于監(jiān)聽服務(wù)端向客戶端發(fā)送的消息,例子如下:
webSocket.addEventListener(‘message’, function (event) { console.log(‘來自服務(wù)端的消息:’, event.data);});
4、webSocket:error event
如果客戶端與服務(wù)端發(fā)生錯(cuò)誤時(shí),那么此事件將會(huì)觸發(fā),例子如下:
webSocket.addEventListener(‘error’, function (event) { console.log(‘連接出現(xiàn)錯(cuò)誤’, event);});
??1.2 服務(wù)端WebSocket
@ServerEndpoint 用于聲明一個(gè)socket服務(wù),例子如下:
@ServerEndpoint(value = “/ws/{userId}/{targetId}”)
幾個(gè)重要的 方法 注解:
@OnOpen@OnClose@OnMessage@OnError
??二、實(shí)戰(zhàn)
??2.1、服務(wù)端
??2.1.1引入maven依賴
org.springframework.boot spring-boot-starter-websocket
??2.1.2 編寫配置類
@Configurationpublic class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}
??2.1.3 編寫WebSocketService服務(wù)類
下面的 userId 代表 發(fā)送者 的ID號(hào), target 代表 發(fā)送目標(biāo) ID號(hào)。
@Component@ServerEndpoint(value = “/ws/{userId}/{target}”)public class WebSocketService { //用于保存連接的用戶信息 private static ConcurrentHashMap SESSION = new ConcurrentHashMap(); //原子遞增遞減,用于統(tǒng)計(jì)在線用戶數(shù) private static AtomicInteger count = new AtomicInteger(); //消息隊(duì)列,用于保存待發(fā)送的信息 private Queue queue = new LinkedBlockingDeque(); //onOpen() //onClose() //onMessage() //onError()}
??2.1.4 建立連接
建立連接之前,判斷用戶是否已經(jīng)連接,如果沒有連接,那么將用戶session信息保存到集合,然后計(jì)數(shù)器遞增。
@OnOpen public void onOpen(Session session, @PathParam(“userId”) String userId) { if (!SESSION.containsKey(userId)) { SESSION.put(userId, session); count.incrementAndGet(); } }
??2.1.5 關(guān)閉連接
關(guān)閉連接的時(shí)候,將用戶session刪除和計(jì)數(shù)器遞減。
@OnClose public void onClose(@PathParam(“userId”) String userId) { SESSION.remove(userId); count.decrementAndGet(); }
??2.1.6 發(fā)送消息
發(fā)送采用的方法是: session.getBasicRemote().sendText(“你好”);
@OnMessage public void onMessage(String message, @PathParam(“userId”) String userId, @PathParam(“target”) String target) throws IOException { queue.add(message); Session s = SESSION.get(target); if (s == null) { Session b = SESSION.get(userId); b.getBasicRemote().sendText(“對(duì)方不在線”); } else { for (int i = 0; i < queue.size(); i++) { String msg = queue.poll(); Message m = new Message(); m.setUserId(userId); s.getBasicRemote().sendText(msg); } } }
??2.1.7 監(jiān)聽錯(cuò)誤
出現(xiàn)錯(cuò)誤,刪除用戶session信息和計(jì)數(shù)器遞減
@OnError public void onError(Throwable error, @PathParam(“userId”) String userId) { SESSION.remove(userId); count.decrementAndGet(); error.printStackTrace(); }
??2.2 客戶端
本案例中客戶端采用Nuxt編寫,相關(guān)代碼如下
??2.2.1 主頁(yè)面
運(yùn)行截圖如圖所示:
歡迎使用喵喵號(hào)聊天 聊一下 body { background: url(‘../static/img/cat.jpg’); }
??2.2.1 聊天頁(yè)面
運(yùn)行截圖如下:
小明
翠花
我的喵喵號(hào):{{user.userId}} 對(duì)方喵喵號(hào):{{user.targetId}} 清空消息 {{m.msg}} {{m.msg}} 系統(tǒng)消息:{{m.msg}} 發(fā)送
??三、開源地址
- ??Gitee: https://gitee.com//websocket
- 演示地址: http://chat.breez.work
??四、參考文獻(xiàn)
- [1]MDN: WebSocket
- [2]Nuxt: https://nuxtjs.org
- [3]Vue: https://cn.vuejs.org
- [4]百度百科: 及時(shí)通信
??收錄專欄:系統(tǒng)設(shè)計(jì)與實(shí)戰(zhàn)
原文鏈接:https://blog.csdn.net/m0_54853420/article/details/125244263?utm_source=tuicool&utm_medium=referral