<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.3</version> </dependency>
package com.shucha.deveiface.web.config; /** * @author tqf * @Description * @Version 1.0 * @since 2022-04-12 15:35 */ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * 開啟WebSocket */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
package com.shucha.deveiface.web.ws; /** * @author tqf * @Description * @Version 1.0 * @since 2022-04-12 15:33 */ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @Component @ServerEndpoint("/webSocket/{userId}") @Slf4j public class WebSocketServer { private Session session; private String userId; /**靜態變數,用來記錄當前線上連線數。應該把它設計成執行緒安全的。*/ private static int onlineCount = 0; private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>(); /** * concurrent包的執行緒安全set,用來存放每個使用者端對應的MyWebSocket物件 */ private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap(); /** * 為了儲存線上使用者資訊,在方法中新建一個list儲存一下【實際專案依據複雜度,可以儲存到資料庫或者快取】 */ private final static List<Session> SESSIONS = Collections.synchronizedList(new ArrayList<>()); /** * 建立連線 * @param session * @param userId */ @OnOpen public void onOpen(Session session, @PathParam("userId") String userId) { this.session = session; this.userId = userId; webSocketSet.add(this); SESSIONS.add(session); if (webSocketMap.containsKey(userId)) { webSocketMap.remove(userId); webSocketMap.put(userId,this); } else { webSocketMap.put(userId,this); addOnlineCount(); } // log.info("【websocket訊息】有新的連線, 總數:{}", webSocketSet.size()); log.info("[連線ID:{}] 建立連線, 當前連線數:{}", this.userId, webSocketMap.size()); } /** * 斷開連線 */ @OnClose public void onClose() { webSocketSet.remove(this); if (webSocketMap.containsKey(userId)) { webSocketMap.remove(userId); subOnlineCount(); } // log.info("【websocket訊息】連線斷開, 總數:{}", webSocketSet.size()); log.info("[連線ID:{}] 斷開連線, 當前連線數:{}", userId, webSocketMap.size()); } /** * 傳送錯誤 * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.info("[連線ID:{}] 錯誤原因:{}", this.userId, error.getMessage()); error.printStackTrace(); } /** * 收到訊息 * @param message */ @OnMessage public void onMessage(String message) { // log.info("【websocket訊息】收到使用者端發來的訊息:{}", message); log.info("[連線ID:{}] 收到訊息:{}", this.userId, message); } /** * 傳送訊息 * @param message * @param userId */ public void sendMessage(String message,Long userId) { WebSocketServer webSocketServer = webSocketMap.get(String.valueOf(userId)); if (webSocketServer!=null){ log.info("【websocket訊息】推播訊息, message={}", message); try { webSocketServer.session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); log.error("[連線ID:{}] 傳送訊息失敗, 訊息:{}", this.userId, message, e); } } } /** * 群發訊息 * @param message */ public void sendMassMessage(String message) { try { for (Session session : SESSIONS) { if (session.isOpen()) { session.getBasicRemote().sendText(message); log.info("[連線ID:{}] 傳送訊息:{}",session.getRequestParameterMap().get("userId"),message); } } } catch (Exception e) { e.printStackTrace(); } } /** * 獲取當前連線數 * @return */ public static synchronized int getOnlineCount() { return onlineCount; } /** * 當前連線數加一 */ public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } /** * 當前連線數減一 */ public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } }
package com.shucha.deveiface.web.controller; import com.alibaba.fastjson.JSONObject; import com.shucha.deveiface.web.ws.WebSocketServer; import lombok.Data; import lombok.experimental.Accessors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author tqf * @Description * @Version 1.0 * @since 2022-04-12 15:44 */ @RestController @RequestMapping("/web") public class TestWebSocket { @Autowired private WebSocketServer webSocketServer; /** * 訊息傳送測試 */ @GetMapping("/test") public void test(){ for (int i=1;i<4;i++) { WebsocketResponse response = new WebsocketResponse(); response.setUserId(String.valueOf(i)); response.setUserName("姓名"+ i); response.setAge(i); webSocketServer.sendMessage(JSONObject.toJSONString(response), Long.valueOf(String.valueOf(i))); } } /** * 群發訊息測試(給當前連線使用者傳送) */ @GetMapping("/sendMassMessage") public void sendMassMessage(){ WebsocketResponse response = new WebsocketResponse(); response.setUserName("群發訊息模板測試"); webSocketServer.sendMassMessage(JSONObject.toJSONString(response)); } @Data @Accessors(chain = true) public static class WebsocketResponse { private String userId; private String userName; private int age; } }
存取測試傳送訊息:http://localhost:50041//web/test
測試存取地址:ws://192.168.0.115:50041/webSocket/1 wss://192.168.0.115:50041/webSocket/2
到此這篇關於SpringBoot實現WebSocket即時通訊的範例程式碼的文章就介紹到這了,更多相關SpringBoot WebSocket即時通訊內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45