<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java 實現 Websocket 通信

      代碼:https://github.com/ioufev/websocket-springboot-demo
      代碼備份下載:

      示例就是客戶端和服務端互相發送簡單的字符串。

      視頻說明

      WebSocket

      WebSocket 協議

      客戶端和服務端,都有6個API(準確說是4個事件2個方法),所以說客戶端和服務端是對等的。

      ?? onOpen()
      ?? onClose()
      ?? onError()
      ?? onMessage()
      ?? sendMessage()
      ?? close()

      Java 端的 4個事件2個方法

      js 端的 4個事件2個方法

      代碼

      WebSocketConfig

      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.socket.config.annotation.EnableWebSocket;
      import org.springframework.web.socket.server.standard.ServerEndpointExporter;
      
      @Configuration
      @EnableWebSocket
      public class WebSocketConfig {
          @Bean
          public ServerEndpointExporter serverEndpointExporter(){
              return new ServerEndpointExporter();
          }
      }
      

      WebSocketServer

      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.CopyOnWriteArraySet;
      
      @Component
      @ServerEndpoint("/ws/{sid}")
      public class WebSocketServer {
      
          private static int onlineCount = 0;
          private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
          private Session session;
          private String sid = "";
      
          @OnOpen
          public void onOpen(Session session, @PathParam("sid") String sid) {
              this.session = session;
              webSocketSet.add(this);     //加入set中
              addOnlineCount();           //在線數加1
              this.sid = sid;
              sendMessage("conn_success");
      
              System.out.println("新的窗口" + sid + "已連接!當前在線人數為" + getOnlineCount());
          }
      
          @OnClose
          public void onClose() {
              webSocketSet.remove(this);  //從set中刪除
              subOnlineCount();           //在線數減1
      
              System.out.println("連接窗口" + sid + "關閉!當前在線人數為" + getOnlineCount());
          }
      
          @OnMessage
          public void onMessage(String message, Session session) {
      
              if(message.startsWith("target-")){
                  int index = message.indexOf(":");
                  String sid = message.substring(7,index);
                  sendInfo(message.substring(index + 1), sid);
                  return;
              }
      
              this.session = session;
              sendMessage("服務端收到來自窗口" + sid + "發送的消息:" + message);
      
          }
      
          @OnError
          public void onError(Session session, Throwable error) {
              this.session = session;
              error.printStackTrace();
          }
      
          private void sendMessage(String message) {
              try {
                  this.session.getBasicRemote().sendText(message);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          // 群發消息
          /**
           * 群發自定義消息
           */
          public static void sendInfo(String message, @PathParam("sid") String sid) {
              System.out.println("推送消息到窗口" + sid + ",推送內容:" + message);
      
              for (WebSocketServer item : webSocketSet) {
                  //這里可以設定只推送給這個sid的,為null則全部推送
                  if (sid == null) {
      //                    item.sendMessage(message);
                  } else if (item.sid.equals(sid)) {
                      item.sendMessage(message);
                  }
              }
          }
      
          public static void sendInfo2(String message) {
              System.out.println("推送消息到所有窗口" + ",推送內容:" + message);
              for (WebSocketServer item : webSocketSet) {
                  item.sendMessage(message);
              }
          }
      
          /**
           * 群發自定義消息
           */
          public static void sendInfo2One(String message, @PathParam("sid") String sid) {
              System.out.println("推送消息到窗口" + sid + ",推送內容:" + message);
      
              for (WebSocketServer item : webSocketSet) {
                  if (item.sid.equals(sid)) {
                      item.sendMessage(message);
                  }
              }
          }
      
          public static synchronized int getOnlineCount() {
              return onlineCount;
          }
      
          public static synchronized void addOnlineCount() {
              WebSocketServer.onlineCount++;
          }
      
          public static synchronized void subOnlineCount() {
              WebSocketServer.onlineCount--;
          }
      
          public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
              return webSocketSet;
          }
      
      }
      

      ws-demo.html文件

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>測試WS</title>
      </head>
      <body>
      
      <div>隨機ID:
        <span id="ws-id">
      
        </span>
      </div>
      
      <button id="connect">開始連接</button>
      <br/>
      
      <label for="message">發送內容: </label><input id="message" type="text" placeholder="請輸入要發送的消息內容">
      <br/>
      <label for="target-id">發送給誰: </label><input id="target-id" type="text" placeholder="請輸入要發送給誰">
      <br/>
      <button id="sendButton">發送消息</button>
      <br/>
      
      <label for="back">收到消息: </label><textarea id="back" placeholder="提示消息" style="width: 600px;height: 200px"></textarea>
      
      <br>
      <button id="disconnect">斷開連接</button>
      
      <script>
      
        let sendButton = window.document.getElementById("sendButton");
        sendButton.addEventListener("click", () => {
          send();
        })
      
        document.getElementById("disconnect").addEventListener("click", () => {
          closeWebSocket();
        })
      
        let websocket;
        document.getElementById("connect").addEventListener("click" , () =>{
      
          if(websocket){
            closeWebSocket()
          }
      
          // 隨機整數
          let random = Math.floor(Math.random()*10000);
          window.document.getElementById("ws-id").innerText = random + '';
      
      
          //判斷當前瀏覽器是否支持WebSocket,是則創建WebSocket
          if ('WebSocket' in window) {
            websocket = new WebSocket("ws://localhost:8080/ws/" + random);
          }else {
            alert('當前瀏覽器 Not support websocket')
          }
      
          //連接發生錯誤的回調方法
          websocket.onerror = function () {
            console.log("WebSocket連接發生錯誤");
          };
          //連接成功建立的回調方法
          websocket.onopen = function () {
            console.log("WebSocket連接成功");
          }
          //接收到消息的回調方法
          websocket.onmessage = function (event) {
            console.log(event.data);
            window.document.getElementById("back").value = event.data;
          }
          //連接關閉的回調方法
          websocket.onclose = function () {
            console.log("WebSocket連接關閉");
          }
        })
      
        websocket = null;
      
        //關閉WebSocket連接
        function closeWebSocket() {
          websocket.close();
        }
        //發送消息
        function send() {
          let message = document.getElementById('message').value;
          let target_id = document.getElementById('target-id').value;
          if (target_id != ""){
            websocket.send('target-' + target_id + ':' + message);
            return;
          }
      
          websocket.send(message);
        }
      
        //如果websocket連接還沒斷開就關閉了窗口,后臺server端會拋異常。
        //所以增加監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接
        window.onbeforeunload = function () {
          closeWebSocket();
        }
      
      </script>
      </body>
      </html>
      

      服務端推送
      DemoController

      import com.ioufev.websocketspringbootdemo.ws.WebSocketServer;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.util.HashMap;
      import java.util.Map;
      
      @RestController
      public class DemoController {
          //推送數據接口
          @PostMapping("/push/{cid}")
          public Map pushToWeb(@PathVariable String cid, @RequestBody String message) {
              Map<String,Object> result = new HashMap<>();
              WebSocketServer.sendInfo(message, cid);
              result.put("code", cid);
              result.put("msg", message);
              return result;
          }
      
          @PostMapping("/push")
          public Map pushToWeb2(@RequestBody String message) {
              Map<String,Object> result = new HashMap<>();
              WebSocketServer.sendInfo2(message);
              result.put("msg", message);
              return result;
          }
      }
      

      動圖演示

      過程和問題

      關于 WebSocket 協議的一些資料

      rfc6455

      關于 WebSocketServer 類中的 static 關鍵字

      WebSocketServer 類的作用域是原型(Prototype),而其他 Bean 的作用域是單例(Singleton)。

      自動裝配其他 Bean 實例時需要一些設置

      關于 WebSocket 集群轉發

      分享我使用的 Redis 發布訂閱的實現,還可以使用消息隊列MQ,ZooKeeper。

      關于 WebSocket 的子協議

      把 WebSocket 當作傳輸層

      可以傳遞應用層協議,比如:MQTT、STOMP、AMQP、OPCUA(看代碼有),或者自定義的協議,反正只要知道別人發的消息是什么意思就行。

      posted @ 2022-09-05 17:27  ioufev  閱讀(2089)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲日韩乱码中文无码蜜桃臀| 久久自己只精产国品| 91偷自国产一区二区三区| 久久综合干| 欧洲亚洲精品免费二区| 日韩一区二区三区日韩精品| 18禁超污无遮挡无码网址| 免费大片av手机看片高清| 国产欧美一区二区精品性色| 久久精品国产99久久久古代 | 亚洲国产成人无码影片在线播放| 国产成人高清精品亚洲一区| 黑人av无码一区| 在线国产精品中文字幕| 国内熟女中文字幕第一页| 亚洲精品爆乳一区二区H| 2021亚洲国产精品无码| 久热这里只精品视频99| 极品vpswindows少妇| 日韩国产中文字幕精品| 免费国产精品黄色一区二区| 在线视频精品中文无码| 国产成人精品久久性色av| 国产亚洲AV电影院之毛片| 久久狠狠高潮亚洲精品| 国产成人精品视频国产| 久久精品免视看国产成人| 漂亮人妻被中出中文字幕| 最新国产精品好看的精品| 国内永久福利在线视频图片| 久久综合88熟人妻| 国产精品不卡一区二区久久| av在线播放观看国产| 国产真实露脸乱子伦原著| 视频一区二区不中文字幕| 99久久免费只有精品国产| 午夜免费福利小电影| 尤物国精品午夜福利视频| 无码内射中文字幕岛国片| mm1313亚洲国产精品| 国产精品国产高清国产专区|