springboot整合websocket實現給擔任或多人傳送資料
阿新 • • 發佈:2021-06-17
伺服器端:
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
package cn.socket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @Component @ServerEndpoint("/pull/test/{id}") public class WebSocketServer { public WebSocketServer() { System.out.println("---------建立socket---------"); } private static int onlineCount = 0; private static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<>(); private static CopyOnWriteArraySet<WebSocketServer> webSockets =new CopyOnWriteArraySet<>(); //與某個客戶端的連線會話,需要通過它來給客戶端傳送資料 private Session session; private static Logger log = LogManager.getLogger(WebSocketServer.class); private String id = ""; /** * 連線建立成功呼叫的方法*/ @OnOpen public void onOpen(@PathParam(value = "id") String id, Session session) { this.session = session; this.id = id;//接收到傳送訊息的人員編號 webSocketSet.put(id, this); //加入set中 webSockets.add(this); addOnlineCount(); //線上數加1 log.info("使用者"+id+"加入!當前線上人數為" + getOnlineCount()); try { sendMessage("連線成功"); } catch (IOException e) { log.error("websocket IO異常"); } } /** * 連線關閉呼叫的方法 */ @OnClose public void onClose() { webSocketSet.remove(this); //從set中刪除 subOnlineCount(); //線上數減1 log.info("有一連線關閉!當前線上人數為" + getOnlineCount()); } /** * 收到客戶端訊息後呼叫的方法 * * @param message 客戶端傳送過來的訊息*/ @OnMessage public void onMessage(String message, Session session) { log.info("來自客戶端的訊息:" + message); //可以自己約定字串內容,比如 內容|0 表示資訊群發,內容|X 表示資訊發給id為X的使用者 String sendMessage = message.split("[|]")[0]; String sendUserId = message.split("[|]")[1]; try { if(sendUserId.equals("0")) sendtoAll(sendMessage); else sendtoUser(sendMessage,sendUserId); } catch (IOException e) { e.printStackTrace(); } } /** * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("發生錯誤"); error.printStackTrace(); } public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * 傳送資訊給指定ID使用者,如果使用者不線上則返回不線上資訊給自己 * @param message * @param sendUserId * @throws IOException */ public void sendtoUser(String message,String sendUserId) throws IOException { if (webSocketSet.get(sendUserId) != null) { if(!id.equals(sendUserId)) webSocketSet.get(sendUserId).sendMessage( "使用者" + id + "發來訊息:" + " <br/> " + message); else webSocketSet.get(sendUserId).sendMessage(message); } else { //如果使用者不線上則返回不線上資訊給自己 sendtoUser("當前使用者不線上",id); } } /** * 傳送資訊給所有人 * @param message * @throws IOException */ public void sendtoAll(String message) throws IOException { for (String key : webSocketSet.keySet()) { try { webSocketSet.get(key).sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } public void sendtoAll2(String message) throws IOException { for (WebSocketServer webSocket : webSockets) { try { webSocket.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } }
@RestController("outController") @Api(tags = "外部介面管理") @CrossOrigin //跨域訪問 swagger 要使用到 public class OutController extends BaseController { @Autowired private WebSocketServer webSocketServer; @ApiOperation("推送資料") @GetMapping("/toHome") public void toHome() throws Exception { webSocketServer.sendtoAll2("1"); } }
前端程式碼:
<!DOCTYPE html> <html style="height: 100%;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <title>建立緩衝區</title> </head> <body style="height: 100%;"> <script type="text/javascript"> const ws=new WebSocket('ws://localhost:33002/tianjin-cim/tuchu/apis/pull/test/1'); ws.onmessage =function(e){ console.log(e) }; </script> </body> </html>