SpringBoot整合 websocket 實(shí)現(xiàn)群聊,點(diǎn)對(duì)點(diǎn)聊天
閱讀本文大概需要 7?分鐘。
來自:blog.csdn.net/qq_38455201/article/details/80374712
1.websocket
2.在springboot程序當(dāng)中使用websocket,接下來這套程序能夠?qū)崿F(xiàn)的功能有:






<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-websocketartifactId>
dependency>
/**
?*?websocket的配置
?*/
@Configuration
public?class?WebSocketStompConfig{
????@Bean
????public?ServerEndpointExporter?serverEndpointExporter()
????{
????????return?new?ServerEndpointExporter();
????}
}
@Component
@ServerEndpoint("/websocket/{username}")
public?class?WebSocket?{
????private?Logger?logger?=?LoggerFactory.getLogger(this.getClass());
????/**
?????*?在線人數(shù)
?????*/
????public?static?int?onlineNumber?=?0;
????/**
?????*?以用戶的姓名為key,WebSocket為對(duì)象保存起來
?????*/
????private?static?Map?clients?=?new?ConcurrentHashMap ();
????/**
?????*?會(huì)話
?????*/
????private?Session?session;
????/**
?????*?用戶名稱
?????*/
????private?String?username;
????/**
?????*?建立連接
?????*
?????*?@param?session
?????*/
????@OnOpen
????public?void?onOpen(@PathParam("username")?String?username,?Session?session)
????{
????????onlineNumber++;
????????logger.info("現(xiàn)在來連接的客戶id:"+session.getId()+"用戶名:"+username);
????????this.username?=?username;
????????this.session?=?session;
????????logger.info("有新連接加入!?當(dāng)前在線人數(shù)"?+?onlineNumber);
????????try?{
????????????//messageType?1代表上線?2代表下線?3代表在線名單?4代表普通消息
????????????//先給所有人發(fā)送通知,說我上線了
????????????Map?map1?=?Maps.newHashMap();
????????????map1.put("messageType",1);
????????????map1.put("username",username);
????????????sendMessageAll(JSON.toJSONString(map1),username);
?
????????????//把自己的信息加入到map當(dāng)中去
????????????clients.put(username,?this);
????????????//給自己發(fā)一條消息:告訴自己現(xiàn)在都有誰在線
????????????Map?map2?=?Maps.newHashMap();
????????????map2.put("messageType",3);
????????????//移除掉自己
????????????Set?set?=?clients.keySet();
????????????map2.put("onlineUsers",set);
????????????sendMessageTo(JSON.toJSONString(map2),username);
????????}
????????catch?(IOException?e){
????????????logger.info(username+"上線的時(shí)候通知所有人發(fā)生了錯(cuò)誤");
????????}
?
?
?
????}
?
????@OnError
????public?void?onError(Session?session,?Throwable?error)?{
????????logger.info("服務(wù)端發(fā)生了錯(cuò)誤"+error.getMessage());
????????//error.printStackTrace();
????}
????/**
?????*?連接關(guān)閉
?????*/
????@OnClose
????public?void?onClose()
????{
????????onlineNumber--;
????????//webSockets.remove(this);
????????clients.remove(username);
????????try?{
????????????//messageType?1代表上線?2代表下線?3代表在線名單??4代表普通消息
????????????Map?map1?=?Maps.newHashMap();
????????????map1.put("messageType",2);
????????????map1.put("onlineUsers",clients.keySet());
????????????map1.put("username",username);
????????????sendMessageAll(JSON.toJSONString(map1),username);
????????}
????????catch?(IOException?e){
????????????logger.info(username+"下線的時(shí)候通知所有人發(fā)生了錯(cuò)誤");
????????}
????????logger.info("有連接關(guān)閉!?當(dāng)前在線人數(shù)"?+?onlineNumber);
????}
?
????/**
?????*?收到客戶端的消息
?????*
?????*?@param?message?消息
?????*?@param?session?會(huì)話
?????*/
????@OnMessage
????public?void?onMessage(String?message,?Session?session)
????{
????????try?{
????????????logger.info("來自客戶端消息:"?+?message+"客戶端的id是:"+session.getId());
????????????JSONObject?jsonObject?=?JSON.parseObject(message);
????????????String?textMessage?=?jsonObject.getString("message");
????????????String?fromusername?=?jsonObject.getString("username");
????????????String?tousername?=?jsonObject.getString("to");
????????????//如果不是發(fā)給所有,那么就發(fā)給某一個(gè)人
????????????//messageType?1代表上線?2代表下線?3代表在線名單??4代表普通消息
????????????Map?map1?=?Maps.newHashMap();
????????????map1.put("messageType",4);
????????????map1.put("textMessage",textMessage);
????????????map1.put("fromusername",fromusername);
????????????if(tousername.equals("All")){
????????????????map1.put("tousername","所有人");
????????????????sendMessageAll(JSON.toJSONString(map1),fromusername);
????????????}
????????????else{
????????????????map1.put("tousername",tousername);
????????????????sendMessageTo(JSON.toJSONString(map1),tousername);
????????????}
????????}
????????catch?(Exception?e){
????????????logger.info("發(fā)生了錯(cuò)誤了");
????????}
?
????}
?
?
????public?void?sendMessageTo(String?message,?String?ToUserName)?throws?IOException?{
????????for?(WebSocket?item?:?clients.values())?{
????????????if?(item.username.equals(ToUserName)?)?{
????????????????item.session.getAsyncRemote().sendText(message);
????????????????break;
????????????}
????????}
????}
?
????public?void?sendMessageAll(String?message,String?FromUserName)?throws?IOException?{
????????for?(WebSocket?item?:?clients.values())?{
????????????????item.session.getAsyncRemote().sendText(message);
????????}
????}
?
????public?static?synchronized?int?getOnlineCount()?{
????????return?onlineNumber;
????}
?
}
html>
<html>
<head>
????<title>websockettitle>
????<script?type="text/javascript"?src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js">script>
????<script?src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js">script>
????<script?src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js">script>
head>
?
<body>
????<div?style="margin:?auto;text-align:?center">
????????<h1>Welcome?to?websocketh1>
????div>
????<br/>
????<div?style="margin:?auto;text-align:?center">
????????<select?id="onLineUser">
????????????<option>--所有--option>
????????select>
????????<input?id="text"?type="text"?/>
????????<button?οnclick="send()">發(fā)送消息button>
????div>
????<br>
????<div?style="margin-right:?10px;text-align:?right">
????????<button?οnclick="closeWebSocket()">關(guān)閉連接button>
????div>
????<hr/>
????<div?id="message"?style="text-align:?center;">div>
????<input??type="text"?th:value="${username}"?id="username"?style="display:?none"?/>
body>
?
?
<script?type="text/javascript">
????var?webSocket;
????var?commWebSocket;
????if?("WebSocket"?in?window)
????{
????????webSocket?=?new?WebSocket("ws://localhost:9030/websocket/"+document.getElementById('username').value);
?
????????//連通之后的回調(diào)事件
????????webSocket.onopen?=?function()
????????{
????????????//webSocket.send(?document.getElementById('username').value+"已經(jīng)上線了");
????????????console.log("已經(jīng)連通了websocket");
????????????setMessageInnerHTML("已經(jīng)連通了websocket");
????????};
?
????????//接收后臺(tái)服務(wù)端的消息
????????webSocket.onmessage?=?function?(evt)
????????{
????????????var?received_msg?=?evt.data;
????????????console.log("數(shù)據(jù)已接收:"?+received_msg);
????????????var?obj?=?JSON.parse(received_msg);
????????????console.log("可以解析成json:"+obj.messageType);
????????????//1代表上線?2代表下線?3代表在線名單?4代表普通消息
????????????if(obj.messageType==1){
????????????????//把名稱放入到selection當(dāng)中供選擇
????????????????var?onlineName?=?obj.username;
????????????????var?option?=?"+onlineName+"";
????????????????$("#onLineUser").append(option);
????????????????setMessageInnerHTML(onlineName+"上線了");
????????????}
????????????else?if(obj.messageType==2){
????????????????$("#onLineUser").empty();
????????????????var?onlineName?=?obj.onlineUsers;
????????????????var?offlineName?=?obj.username;
????????????????var?option?=?"+"--所有--"+"";
????????????????for(var?i=0;i????????????????????if(!(onlineName[i]==document.getElementById('username').value)){ script>
????????????????????????option+="+onlineName[i]+""
????????????????????}
????????????????}
????????????????$("#onLineUser").append(option);
?
????????????????setMessageInnerHTML(offlineName+"下線了");
????????????}
????????????else?if(obj.messageType==3){
????????????????var?onlineName?=?obj.onlineUsers;
????????????????var?option?=?null;
????????????????for(var?i=0;i????????????????????if(!(onlineName[i]==document.getElementById('username').value)){
????????????????????????option+="+onlineName[i]+""
????????????????????}
????????????????}
????????????????$("#onLineUser").append(option);
????????????????console.log("獲取了在線的名單"+onlineName.toString());
????????????}
????????????else{
????????????????setMessageInnerHTML(obj.fromusername+"對(duì)"+obj.tousername+"說:"+obj.textMessage);
????????????}
????????};
?
????????//連接關(guān)閉的回調(diào)事件
????????webSocket.onclose?=?function()
????????{
????????????console.log("連接已關(guān)閉...");
????????????setMessageInnerHTML("連接已經(jīng)關(guān)閉....");
????????};
????}
????else{
????????//?瀏覽器不支持?WebSocket
????????alert("您的瀏覽器不支持?WebSocket!");
????}
????//將消息顯示在網(wǎng)頁上
????function?setMessageInnerHTML(innerHTML)?{
????????document.getElementById('message').innerHTML?+=?innerHTML?+?'
';
????}
?
????function?closeWebSocket()?{
????????//直接關(guān)閉websocket的連接
????????webSocket.close();
????}
?
????function?send()?{
????????var?selectText?=?$("#onLineUser").find("option:selected").text();
????????if(selectText=="--所有--"){
????????????selectText?=?"All";
????????}
????????else{
????????????setMessageInnerHTML(document.getElementById('username').value+"對(duì)"+selectText+"說:"+?$("#text").val());
????????}
????????var?message?=?{
????????????"message":document.getElementById('text').value,
????????????"username":document.getElementById('username').value,
????????????"to":selectText
????????};
????????webSocket.send(JSON.stringify(message));
????????$("#text").val("");
?
????}
?
html>
????@RequestMapping("/websocket/{name}")
????public?String?webSocket(@PathVariable?String?name,Model?model){
????????try{
????????????logger.info("跳轉(zhuǎn)到websocket的頁面上");
????????????model.addAttribute("username",name);
????????????return?"websocket";
????????}
????????catch?(Exception?e){
????????????logger.info("跳轉(zhuǎn)到websocket的頁面上發(fā)生異常,異常信息是:"+e.getMessage());
????????????return?"error";
????????}
????}
自定義注解+攔截器優(yōu)雅的實(shí)現(xiàn)敏感數(shù)據(jù)的加解密!
內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper、數(shù)據(jù)結(jié)構(gòu)、限流熔斷降級(jí)......等技術(shù)棧!
?戳閱讀原文領(lǐng)??!? ? ? ? ? ? ? ??? ??? ? ? ? ? ? ? ? ? ?朕已閱?
評(píng)論
圖片
表情

