1. 程式人生 > 程式設計 >SpringBoot2.0整合WebSocket程式碼例項

SpringBoot2.0整合WebSocket程式碼例項

這篇文章主要介紹了SpringBoot2.0整合WebSocket程式碼例項,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

之前公司的某個系統為了實現推送技術,所用的技術都是Ajax輪詢,這種方式瀏覽器需要不斷的向伺服器發出請求,顯然這樣會浪費很多的頻寬等資源,所以研究了下WebSocket,本文將詳細介紹下。

一、什麼是WebSocket?

WebSocket是HTML5開始提供的一種在單個TCP連線上進行全雙工通訊的協議,能更好的節省伺服器資源和頻寬,並且能夠更實時地進行通訊。

WebSocket 使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料,在WebSocket API中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。

二、SpringBoot整合WebSocket

新建一個spring boot專案spring-boot-websocket,按照下面步驟操作。

pom.xml引入jar包

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

新建WebSocket的配置類

這個配置類檢測帶註解@ServerEndpoint的bean並註冊它們,配置類程式碼如下:

@Configuration
public class WebSocketConfig {
  /**
   * 給spring容器注入這個ServerEndpointExporter物件
   * 相當於xml:
   * <beans>
   * <bean id="serverEndpointExporter" class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>
   * </beans>
   * <p>
   * 檢測所有帶有@serverEndpoint註解的bean並註冊他們。
   *
   * @return
   */
  @Bean
  public ServerEndpointExporter serverEndpointExporter() {
    System.out.println("我被注入了");
    return new ServerEndpointExporter();
  }
}

新建WebSocket的處理類

這個處理類需要使用@ServerEndpoint,這個類裡監聽連線的建立關閉、訊息的接收等,具體程式碼如下:

@ServerEndpoint(value = "/ws/asset")
@Component
public class WebSocketServer {

  @PostConstruct
  public void init() {
    System.out.println("websocket 載入");
  }
  private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  private static final AtomicInteger OnlineCount = new AtomicInteger(0);
  // concurrent包的執行緒安全Set,用來存放每個客戶端對應的Session物件。
  private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();


  /**
   * 連線建立成功呼叫的方法
   */
  @OnOpen
  public void onOpen(Session session) {
    SessionSet.add(session);
    int cnt = OnlineCount.incrementAndGet(); // 線上數加1
    log.info("有連線加入,當前連線數為:{}",cnt);
    SendMessage(session,"連線成功");
  }

  /**
   * 連線關閉呼叫的方法
   */
  @OnClose
  public void onClose(Session session) {
    SessionSet.remove(session);
    int cnt = OnlineCount.decrementAndGet();
    log.info("有連線關閉,當前連線數為:{}",cnt);
  }

  /**
   * 收到客戶端訊息後呼叫的方法
   *
   * @param message
   *      客戶端傳送過來的訊息
   */
  @OnMessage
  public void onMessage(String message,Session session) {
    log.info("來自客戶端的訊息:{}",message);
    SendMessage(session,"收到訊息,訊息內容:"+message);

  }

  /**
   * 出現錯誤
   * @param session
   * @param error
   */
  @OnError
  public void onError(Session session,Throwable error) {
    log.error("發生錯誤:{},Session ID: {}",error.getMessage(),session.getId());
    error.printStackTrace();
  }

  /**
   * 傳送訊息,實踐表明,每次瀏覽器重新整理,session會發生變化。
   * @param session
   * @param message
   */
  public static void SendMessage(Session session,String message) {
    try {
//      session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)",message,session.getId()));
      session.getBasicRemote().sendText(message);
    } catch (IOException e) {
      log.error("傳送訊息出錯:{}",e.getMessage());
      e.printStackTrace();
    }
  }

  /**
   * 群發訊息
   * @param message
   * @throws IOException
   */
  public static void BroadCastInfo(String message) throws IOException {
    for (Session session : SessionSet) {
      if(session.isOpen()){
        SendMessage(session,message);
      }
    }
  }

  /**
   * 指定Session傳送訊息
   * @param sessionId
   * @param message
   * @throws IOException
   */
  public static void SendMessage(String message,String sessionId) throws IOException {
    Session session = null;
    for (Session s : SessionSet) {
      if(s.getId().equals(sessionId)){
        session = s;
        break;
      }
    }
    if(session!=null){
      SendMessage(session,message);
    }
    else{
      log.warn("沒有找到你指定ID的會話:{}",sessionId);
    }
  }
}

新建一個html

目前大部分瀏覽器支援WebSocket,比如Chrome,Mozilla,Opera和Safari,在html頁面進行websocket的連線建立、收訊息的監聽,頁面程式碼如下:

<html>
<head>
  <meta charset="UTF-8">
  <title>websocket測試</title>
  <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
  <style type="text/css">
    h3,h4{
      text-align:center;
    }
  </style>
</head>
<body>

<h3>WebSocket測試,客戶端接收到的訊息如下:</h3>

<textarea id = "messageId" readonly="readonly" cols="150" rows="30" >

</textarea>


<script type="text/javascript">
  var socket;
  if (typeof (WebSocket) == "undefined") {
    console.log("遺憾:您的瀏覽器不支援WebSocket");
  } else {
    console.log("恭喜:您的瀏覽器支援WebSocket");
    //實現化WebSocket物件
    //指定要連線的伺服器地址與埠建立連線
    //注意ws、wss使用不同的埠。我使用自簽名的證書測試,
    //無法使用wss,瀏覽器開啟WebSocket時報錯
    //ws對應http、wss對應https。
    socket = new WebSocket("ws://localhost:8080/ws/asset");
    //連線開啟事件
    socket.onopen = function() {
      console.log("Socket 已開啟");
      socket.send("訊息傳送測試(From Client)");
    };
    //收到訊息事件
    socket.onmessage = function(msg) {
      $("#messageId").append(msg.data+ "\n");
      console.log(msg.data );
    };
    //連線關閉事件
    socket.onclose = function() {
      console.log("Socket已關閉");
    };
    //發生了錯誤事件
    socket.onerror = function() {
      alert("Socket發生了錯誤");
    }
    //視窗關閉時,關閉連線
    window.unload=function() {
      socket.close();
    };
  }
</script>

</body>
</html>

三、檢視執行效果

啟動SpringBoot專案

開啟首頁

本地瀏覽器開啟首頁http://localhost:8080/,出現WebSocket測試頁面,同時後臺列印連線的日誌。

有連線加入,當前連線數為:1,sessionId=0

往客戶端傳送訊息

通過上面日誌可以看到客戶端連線連線的sessionId,我測試時候sessionId是0,然後瀏覽器訪問下面介面即可往客戶端傳送訊息。

//引數說明: id:sessionID 
//引數說明: message:訊息內容
http://localhost:8080/api/ws/sendOne?id=0&message=你好Java碎碎念

傳送訊息動圖

到此SpringBoot整合WebSocket的功能已經全部實現,有問題歡迎留言溝通哦!

完整原始碼地址:https://github.com/suisui2019/springboot-study

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。