<address id="ousso"></address>
<form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
  1. Java中Websocket使用實例解析

    時間:2025-12-23 13:24:11 java語言

    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的標準

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

      */

      /pic/p>

      @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 () {

      /pic/p>

      };

      });

      /**

      * 初始化websocket,建立連接

      */

      function initSocket() {

      if (!window.WebSocket) {

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

      return false;

      }

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

      /pic/p>

      webSocket.onmessage = function (msg) {

      console.log(msg);

      };

      /pic/p>

      webSocket.onerror = function (event) {

      console.log(event);

      };

      /pic/p>

      webSocket.onopen = function (event) {

      console.log(event);

      };

      /pic/p>

      webSocket.onclose = function () {

      /pic/p>

      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:/pic/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) {

      /pic/p>

      e.printStackTrace();

      }

      }

      }

      chrome安裝一個websocket客戶端調試

      最后

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

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

    Java中synchronized的使用實例10-06

    Java for循環語句使用實例01-13

    java讀取解析xml文件實例02-26

    Java中的Spring入門實例02-27

    Java 異步回調機制實例解析03-07

    Java中的多態用法實例分析12-03

    JAVA中If語句的使用02-22

    JAVA中的if語句的使用10-15

    Java中的MessageFormat.format用法實例02-01

    <address id="ousso"></address>
    <form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
    1. 日日做夜狠狠爱欧美黑人