首页 → 名言 → 哲理美文
Java中Websocket使用實例解析
日期:2023-03-09 16:36:55    编辑:网络投稿    来源:互联网
Java中Websocket使用實例解析  在 WebSocket API,瀏覽器和服務器只需要要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送
为你推荐:
  • 有哪些一眼就驚艷到
  • Java中Websocket使用實例解析

      在 WebSocket API,瀏覽器和服務器只需要要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。下面小編給大家介紹Java中Websocket使用實例解析,歡迎閱讀!

      Java中Websocket使用實例解析

      運行環境

      客戶端

      實現了websocket的瀏覽器



    Chrome Supported in version 4+ Firefox Supported in version 4+ Internet Explorer Supported in version 10+ Opera Supported in version 10+ Safari Supported in version 5+

      服務端

      依賴

      <dependency>

      <groupId>org.apache.tomcat</groupId>

      <artifactId>tomcat-websocket-api</artifactId>

      <version>7.0.47</version>

      <scope>provided</scope>

      </dependency>

      <dependency>

      <groupId>javax</groupId>

      <artifactId>javaee-api</artifactId>

      <version>7.0</version>

      <scope>provided</scope>

      </dependency>

      注意:早前業界沒有統一的標準,各服務器都有各自的實現,現在J2EE7的JSR356已經定義了統一的標準,請盡量使用支持最新通用標準的服務器。

      我是用的Tomcat 7.0.57 + Java7

      必須是Tomcat 7.0.47以上

      ps:最早我們是用的Tomcat 7自帶的實現,后來要升級Tomcat 8,結果原來的實現方式在Tomcat 8不支持了,就只好切換到支持Websocket 1.0版本的Tomcat了。

      主流的java web服務器都有支持JSR365標準的版本了,請自行Google。

      用nginx做反向代理的需要注意啦,socket請求需要做特殊配置的,切記!

      Tomcat的處理方式建議修改為NIO的方式,同時修改連接數到合適的參數,請自行Google!

      服務端不需要在web.xml中做額外的配置,Tomcat啟動后就可以直接連接了。

      實現

      import com.dooioo.websocket.utils.SessionUtils;

      import org.apache.commons.logging.Log;

      import org.apache.commons.logging.LogFactory;

      import javax.websocket.*;

      import javax.websocket.server.PathParam;

      import javax.websocket.server.ServerEndpoint;

      /**

      * 功能說明:websocket處理類, 使用J2EE7的標準

      * 切忌直接在該連接處理類中加入業務處理代碼

      */

      //relationId和userCode是我的業務標識參數,websocket.ws是連接的路徑,可以自行定義

      @ServerEndpoint("/websocket.ws/{relationId}/{userCode}")

      public class WebsocketEndPoint {

      private static Log log = LogFactory.getLog(WebsocketEndPoint.class);

      /**

      * 打開連接時觸發

      * @param relationId

      * @param userCode

      * @param session

      */

      @OnOpen

      public void onOpen(@PathParam("relationId") String relationId,

      @PathParam("userCode") int userCode,

      Session session){

      log.info("Websocket Start Connecting: " + SessionUtils.getKey(relationId, userCode));

      SessionUtils.put(relationId, userCode, session);

      }

      /**

      * 收到客戶端消息時觸發

      * @param relationId

      * @param userCode

      * @param message

      * @return

      */

      @OnMessage

      public String onMessage(@PathParam("relationId") String relationId,

      @PathParam("userCode") int userCode,

      String message) {

      return "Got your message (" + message + ").Thanks !";

      }

      /**

      * 異常時觸發

      * @param relationId

      * @param userCode

      * @param session

      */

      @OnError

      public void onError(@PathParam("relationId") String relationId,

      @PathParam("userCode") int userCode,

      Throwable throwable,

      Session session) {

      log.info("Websocket Connection Exception: " + SessionUtils.getKey(relationId, userCode));

      log.info(throwable.getMessage(), throwable);

      SessionUtils.remove(relationId, userCode);

      }

      /**

      * 關閉連接時觸發

      * @param relationId

      * @param userCode

      * @param session

      */

      @OnClose

      public void onClose(@PathParam("relationId") String relationId,

      @PathParam("userCode") int userCode,

      Session session) {

      log.info("Websocket Close Connection: " + SessionUtils.getKey(relationId, userCode));

      SessionUtils.remove(relationId, userCode);

      }

      }

      工具類用來存儲唯一key和連接

      這個是我業務的`需要,我的業務是服務器有對應動作觸發時,推送數據到客戶端,沒有接收客戶端數據的操作。

      import javax.websocket.Session;

      import java.util.Map;

      import java.util.concurrent.ConcurrentHashMap;

      /**

      * 功能說明:用來存儲業務定義的sessionId和連接的對應關系

      * 利用業務邏輯中組裝的sessionId獲取有效連接后進行后續操作

      */

      public class SessionUtils {

      public static Map clients = new ConcurrentHashMap<>();

      public static void put(String relationId, int userCode, Session session){

      clients.put(getKey(relationId, userCode), session);

      }

      public static Session get(String relationId, int userCode){

      return clients.get(getKey(relationId, userCode));

      }

      public static void remove(String relationId, int userCode){

      clients.remove(getKey(relationId, userCode));

      }

      /**

      * 判斷是否有連接

      * @param relationId

      * @param userCode

      * @return

      */

      public static boolean hasConnection(String relationId, int userCode) {

      return clients.containsKey(getKey(relationId, userCode));

      }

      /**

      * 組裝唯一識別的key

      * @param relationId

      * @param userCode

      * @return

      */

      public static String getKey(String relationId, int userCode) {

      return relationId + "_" + userCode;

      }

      }

      推送數據到客戶端

      在其他業務方法中調用

      /**

      * 將數據傳回客戶端

      * 異步的方式

      * @param relationId

      * @param userCode

      * @param message

      */

      public void broadcast(String relationId, int userCode, String message) {

      if (TelSocketSessionUtils.hasConnection(relationId, userCode)) {

      TelSocketSessionUtils.get(relationId, userCode).getAsyncRemote().sendText(message);

      } else {

      throw new NullPointerException(TelSocketSessionUtils.getKey(relationId, userCode) + " Connection does not exist");

      }

      }

      我是使用異步的方法推送數據,還有同步的方法

      客戶端代碼

      var webSocket = null;

      var tryTime = 0;

      $(function () {

      initSocket();

      window.onbeforeunload = function () {

      //離開頁面時的其他操作

      };

      });

      /**

      * 初始化websocket,建立連接

      */

      function initSocket() {

      if (!window.WebSocket) {

      alert("您的瀏覽器不支持websocket!");

      return false;

      }

      webSocket = new WebSocket("ws://127.0.0.1:8080/websocket.ws/" + relationId + "/" + userCode);

      // 收到服務端消息

      webSocket.onmessage = function (msg) {

      console.log(msg);

      };

      // 異常

      webSocket.onerror = function (event) {

      console.log(event);

      };

      // 建立連接

      webSocket.onopen = function (event) {

      console.log(event);

      };

      // 斷線重連

      webSocket.onclose = function () {

      // 重試10次,每次之間間隔10秒

      if (tryTime < 10) {

      setTimeout(function () {

      webSocket = null;

      tryTime++;

      initSocket();

      }, 500);

      } else {

      tryTime = 0;

      }

      };

      }

      其他調試工具

      Java實現一個websocket的客戶端

      依賴:

      <dependency>

      <groupId>org.java-websocket</groupId>

      <artifactId>Java-WebSocket</artifactId>

      <version>1.3.0</version>

      </dependency>

      代碼:

      import java.io.IOException;

      import javax.websocket.ClientEndpoint;

      import javax.websocket.OnError;

      import javax.websocket.OnMessage;

      import javax.websocket.OnOpen;

      import javax.websocket.Session;

      @ClientEndpoint

      public class MyClient {

      @OnOpen

      public void onOpen(Session session) {

      System.out.println("Connected to endpoint: " + session.getBasicRemote());

      try {

      session.getBasicRemote().sendText("Hello");

      } catch (IOException ex) {

      }

      }

      @OnMessage

      public void onMessage(String message) {

      System.out.println(message);

      }

      @OnError

      public void onError(Throwable t) {

      t.printStackTrace();

      }

      }

      import java.io.BufferedReader;

      import java.io.IOException;

      import java.io.InputStreamReader;

      import java.net.URI;

      import javax.websocket.ContainerProvider;

      import javax.websocket.DeploymentException;

      import javax.websocket.Session;

      import javax.websocket.WebSocketContainer;

      public class MyClientApp {

      public Session session;

      protected void start()

      {

      WebSocketContainer container = ContainerProvider.getWebSocketContainer();

      String uri = "ws://127.0.0.1:8080/websocket.ws/relationId/12345";

      System.out.println("Connecting to " + uri);

      try {

      session = container.connectToServer(MyClient.class, URI.create(uri));

      } catch (DeploymentException e) {

      e.printStackTrace();

      } catch (IOException e) {

      e.printStackTrace();

      }

      }

      public static void main(String args[]){

      MyClientApp client = new MyClientApp();

      client.start();

      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      String input = "";

      try {

      do{

      input = br.readLine();

      if(!input.equals("exit"))

      client.session.getBasicRemote().sendText(input);

      }while(!input.equals("exit"));

      } catch (IOException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      }

      }

      }

      chrome安裝一個websocket客戶端調試

      最后

      為了統一的操作體驗,對于一些不支持websocket的瀏覽器,請使用socketjs技術做客戶端開發。

    【Java中Websocket使用實例解析】相關文章:

    Java中synchronized的使用實例12-03

    java讀取解析xml文件實例11-05

    Java 異步回調機制實例解析11-30

    JAVA中If語句的使用10-03

    Java中的多態用法實例分析11-29

    Java中shuffle算法的使用12-03

    java中通用的線程池實例代碼11-29

    Java中的JDBC事務解析11-29

    Java中運算符的使用11-18

    这里有更多你想看的
  • 看透人心的句子 經
    • 本类最新
    • 精品图文
    • 时尚
    • 新闻
    • 生活
    • 视觉
    • 微爱
      栏目ID=88的表不存在(操作类型=0)

    头条推荐

    热门推荐

    特别推荐

    返回顶部