中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

websocket實戰(2) 信息處理發送、接收和編碼

發布時間:2020-09-18 14:20:17 來源:網絡 閱讀:12548 作者:randy_shandong 欄目:開發技術

websocket 和傳統意義上的socket編程雖然存在差別,但也存在相通概念,也分服務端和客戶端。

主要區別

  1. 對于websocket,客戶端的編寫方式是通過JS編寫回調函數完成交互;而傳統socket,則需要連接端口,通過輸入輸出流來傳遞信息,完成交互;

  2. 傳統的socket,服務端則需要綁定端口,通過accept 方法,等待客戶端的連接。websocket 規范則把處理細節由web服務器來完成。

數據處理是websocket的一項主要工作。按工作階段劃分,主要包括以下方面。

  1. 信息發送

  2. 信息解碼

  3. 信息編碼

  4. 信息接收

按傳遞數據劃分,分為

  1. 文本信息

  2. 二進制流信息

  3. ping/pong信息

上面的內容,僅限于服務端,websocket html5相關暫時不討論

1.信息發送( Sending Messages)

表示服務端,將消息傳遞給客戶端(peer)

1.1將消息廣播到所有連接客戶端

@ServerEndpoint("/echoall")
public class EchoAllEndpoint {
   @OnMessage
   public void onMessage(Session session, String msg) {//1
      try {
         for (Session sess : session.getOpenSessions()) {
            if (sess.isOpen())
               sess.getBasicRemote().sendText(msg);//2,3
         }
      } catch (IOException e) { ... }
   }
}

信息發送三步

1.Obtain the Session object from the connection.(通過在參數中添加Session,獲取Session)

2.Use the Session object to obtain a RemoteEndpoint object.

3.Use the RemoteEndpoint object to send messages to the peer.

1.2返回值,作為信息發送

@OnMessage
public String onMessage(String message,Session session) {
    System.out.println("Received : "+ message);
    return message+"-"+session.getId();
}

2.信息解碼和編碼(codec)

拿打電話為例,如果電話雙方,都用一樣的標準普通話溝通,就沒必要用翻譯器了。如果電話雙方,一邊用著標準的牛津話,一方操著標準的山東土話,想想也能想想出來,溝通直接亂掉了,這時候必須要用到雙方必須都需要翻譯器了。websocket的編碼和解碼部分就是“翻譯器”的角色。

編碼及×××位置

websocket實戰(2) 信息處理發送、接收和編碼

可以簡單理解為:解碼就是反序列化的過程;編碼就是序列化的過程。

2.1 使用Encoders 反序列化對象

響應信息需要轉換成二進制,才能進行網絡傳遞。

來自j2ee的例子

1.實現Encoder.Text<T> 或Encoder.Binary<T>接口

public class MessageATextEncoder implements Encoder.Text<MessageA> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public String encode(MessageA msgA) throws EncodeException {
      // Access msgA's properties and convert to JSON text...
      return msgAJsonString;
   }
}

2.將第一步中新建的Encoder,添加到ServerEndpoint 注解的encoders 屬性中

@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class }
)
public class EncEndpoint { ... }

3.使用RemoteEndpoint.Basic or RemoteEndpoint.Async 的sendObject發送對象。

MessageA msgA = new MessageA(...);
MessageB msgB = new MessageB(...);
session.getBasicRemote.sendObject(msgA);
session.getBasicRemote.sendObject(msgB);

2.2 使用Decoders 序列化信息

將請求信息轉換成對象,才方便ServerPoint處理響應

與Encoders處理步驟類似

1.實現Decoder.Text<T>或Decoder.Binary<T>接口

public class MessageTextDecoder implements Decoder.Text<Message> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public Message decode(String string) throws DecodeException {
      // Read message...
      if ( /* message is an A message */ )
         return new MessageA(...);
      else if ( /* message is a B message */ )
         return new MessageB(...);
   }
   @Override
   public boolean willDecode(String string) {
      // Determine if the message can be converted into either a
      // MessageA object or a MessageB object...
      return canDecode;
   }
}

請注意willDecode方法,決定是否進行解碼


2. 新建的Decoder,添加到ServerEndpoint 注解的decoders 屬性中

@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class },
   decoders = { MessageTextDecoder.class }
)
public class EncDecEndpoint { ... }

3. 這時候就可以在@OnMessage注解的參數方法中直接使用Decoder.decode返回的對象類型了。

@OnMessage
public void message(Session session, Message msg) {
   if (msg instanceof MessageA) {
      // We received a MessageA object...
   } else if (msg instanceof MessageB) {
      // We received a MessageB object...
   }
}

具體例子,見我的github項目。https://github.com/janecms/websocket_example

  • (XML)編碼解密處理(codec)

  • (JSON)編碼解密處理(codec)

3.信息接收(Receiving Messages)

3.1 接收三種不同形式消息

package com.sample.websocket.endpoint;
import javax.websocket.OnMessage;
import javax.websocket.PongMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.nio.ByteBuffer;

@ServerEndpoint("/receive")
public class ReceiveEndpoint {
   @OnMessage
   public void textMessage(Session session, String msg) {
      System.out.println("Text message: " + msg);
   }
    @OnMessage
   public void textMessage(Session session, String msg) {
      System.out.println("Text message: " + msg);
   }
   @OnMessage
   public void binaryMessage(Session session, ByteBuffer msg) {
      System.out.println("Binary message: " + msg.toString());
   }
   @OnMessage
   public void pongMessage(Session session, PongMessage msg) {
      System.out.println("Pong message: " +  msg.getApplicationData().toString());
   }
}

一個奇怪的情況,不同版本的Tomcat,對@OnMessage注解的方法限制有所不同。也進一步說明,websocket規范是個快速變化中的規范。有的直接編譯期出錯;有的運行時錯誤。(有可能和我選擇不同版本的開發工具有關系,不太確定,一樣的代碼,表現不同的行為,蹊蹺)

需要注意的是被OnMessage注解的三個方法,分別接收不同的消息類型。

3.2 錯誤代碼

@ServerEndpoint("/echo")
public class EchoEndpoint {
    @OnMessage
    public String onMessage(String message,Session session) {
        System.out.println("Received : "+ message);
        return message+"-"+session.getId();
    }

    @OnMessage
    public String onMessage2(String message,Session session) {
        System.out.println("Received : "+ message);
        return message+"####"+session.getId();
    }
}

代碼,報運行時異常。

javax.servlet.ServletException: javax.websocket.DeploymentException: Duplicate annotation

一種消息類型,只能對應一個OnMessage方法。

參考資源

https://docs.oracle.com/javaee/7/tutorial/websocket005.htm

結論:主要討論了消息相關的內容 按消息處理的不同階段進行總結。接下來即將討論websocket相關的配置信息,及錯誤處理。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

建平县| 荥经县| 育儿| 东阳市| 鄄城县| 南岸区| 通江县| 洪江市| 邹城市| 沙洋县| 怀仁县| 玉树县| 霞浦县| 阿荣旗| 沙河市| 宁远县| 永和县| 青川县| 庐江县| 隆安县| 加查县| 偏关县| 万宁市| 贞丰县| 拜城县| 新营市| 皮山县| 民乐县| 武威市| 信阳市| 明光市| 勃利县| 皋兰县| 大方县| 余江县| 安国市| 海原县| 临颍县| 陵川县| 蕉岭县| 和顺县|