[webSocket] 인코더/디코더 사용하기

첸첸·2021년 11월 11일
0

webSocket in java

목록 보기
5/9

Java API는 encoders와 decoders를 통해 WebSocket 메세지와 자바 타입간의 컨버팅을 제공하고 있다.
encoder는 자바 객체를 JSON,XML, binary 형식으로 Websocket의 메세지로 전달 될 수 있게 한다.
decoder는 Websocket 메세지를 읽어서 JSON,XML,binary 형식을 자바 객체로 변환 하는 역할을 한다.

자바 객체를 웹소켓 메세지로 변환하는 Encoder 구현하기


1) 아래의 인터페이스 중 하나를 구현

	`Encoder.Text<T> for text messages`
	`Encoder.Binary<T> for binary messages`

2) @ServeEndpont의 옵션 파라미터에 인코더의 구현의 이름을 추가
3) RemoteEndpoint.Basic or RemoteEndpoint.Async interfaces sendObject(Object data) 를 사용하여 객체를 메세지로 보내기. 컨테이너는 해당 타입을 match시켜줄 인코더를 찾고, 사용하여 객체를 WebSocket메세지로 변환시켜줌

만약, 텍스트 메세지로 보내고 싶은 두개의 자바 타입(MessageA,MessageB)을 가지고 있다면, Encoder.Text<MessageA>Encoder.Text<MessageB> 를 아래와 같이 구현하면 된다.

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;
   }
}

Text<MessageB> 도 비슷하게 구현 한 후, @ServerEndpoint어노테이션에 다음과 같이 추가한다.

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

이제, 아래와 같이 MessageA 객체와 MessageB 객체를 sendObject 메서드를 사용해서, WebSocket 메세지로 보낼 수 있다.

endpoint와 같이 인코더 객체는 오직 하나의 웹소켓 연결과 상대방에 연관이 있으므로, 주어진 시간에 하나의 인코더만 실행할 수 있다.

WebSocket 메세지를 자바 객체로 변환하기

1) 아래의 인터페이스 중 하나를 구현

`Dcoder.Text<T> for text messages`
`Dcoder.Binary<T> for binary messages`

✔Encoder와는 다르게 하나의 Decoder만 사용 가능

2)@ServeEndpont의 옵션 파라미터에 디코더 구현의 이름을 추가
3) @onMessage 를 사용하여 특정 자바 객체를 파라미터로 받는 메서드를 만들 수 있다. endpoint가 특정 decoder로 디코딩 할 수 있눈 메세지를 받을 때, 컨테이너는 @OnMessage가 붙어 있는 메서드를 호출

만약, 텍스트 메세지로 받고 싶은 두개의 자바 타입(MessageA,MessageB)을 가지고 있다면, 하나의 decoder 밖에 사용하지 못하기 때문에 공통되는 클래스를 생성해야한다.(Message)

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;
   }
}

@ServerEndpoint`어노테이션에 다음과 같이 추가한다.

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

MessageAMessageB 객체를 받을 수 있는 메소드를 endpoint 클래스에 정의

@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...
   }
}

참고 : https://docs.oracle.com/javaee/7/tutorial/websocket007.htm

0개의 댓글