JSR 356, Java API for WebSocket

来源:互联网 发布:mac钥匙串访问在哪 编辑:程序博客网 时间:2024/06/04 20:43

接口驱动方法

前面介绍的注解驱动方法允许我们通过相应的生命周期注解来注解相应的类和方法。而接口驱动的方法,开发者需要扩展javax.websocket.Endpoint,并覆盖其中的onOpen,onClose和onError方法:

  1. public class myOwnEndpoint extends javax.websocket.Endpoint {
  2. public void onOpen(Session session, EndpointConfig config) {...}
  3. public void onClose(Session session, CloseReason closeReason) {...}
  4. public void onError (Session session, Throwable throwable) {...}
  5. }

为了拦截消息,在onOpen的实现中需要注册一个javax.websocket.MessageHandler:

  1. public void onOpen (Session session, EndpointConfig config) {
  2. session.addMessageHandler (new MessageHandler() {...});
  3. }

MessageHandler是一个接口,它有两个子接口:MessageHandler.Partial和MessageHandler.Whole。如果开发者想要消息部分传递时得到通知则应该使用MessageHandler.Partial接口,而如果开发者想要在消息传递完成以后得到通知,则需要使用MessageHandler.Whole接口。

下面的代码片段监听到来的文本消息,并将文本消息的大写形式发送回给对等的节点:

  1. public void onOpen (Session session, EndpointConfig config) {
  2. final RemoteEndpoint.Basic remote = session.getBasicRemote();
  3. session.addMessageHandler (new MessageHandler.Whole() {
  4. public void onMessage(String text) {
  5. try {
  6. remote.sendString(text.toUpperCase());
  7. } catch (IOException ioe) {
  8. // handle send failure here
  9. }
  10. }
  11.  
  12. });
  13. }

消息类型,编码,解码

WebSocket的Java API是非常强大的,它允许直接将Java对象作为WebSocket消息进行发送或接收。

基本上,有三种不同的消息类型:

  • 文本消息
  • 二进制消息
  • Pong消息,也即WebSocket连接本身

当使用接口驱动模型时,每个Session最多可以为每种消息类型注册一个MessageHandler。

当使用注解驱动模型时,对于每个消息类型,可以使用一个@onMessage注解,注解方法中可以使用的参数依赖于消息所属的类型。

@OnMessage注解的Javadoc清楚地指明了其基于消息的类型来指定可选的消息参数:

(1)如果方法是处理文本消息:

  • String用于接收整个消息,
  • Java原语(primitive)或类相当于接收整个消息并转换为该类型
  • String和boolean对用于分批接收消息
  • Reader用于采用阻塞流方式接收整个消息

(2)如果方法处理的是二进制消息:

  • byte[]或ByteBufffer用于接收整个消息
  • byte[]和boolean对,或ByteBuffer和boolean对来分批接收消息
  • 采用阻塞流方式接收整个消息的InputStream

(3)如果方法处理的是Pong消息

  • PongMessage用于处理pong消息.

任意Java对象都可以通过编码器来编码为文本或二进制类型消息。文本及二进制消息被传送到对等的节点,之后接收方将其解码为对应的Java对象,或者可以使用其它的WebSocket库进行解释转换。通常,XML或JSON用于WebSocket消息的转换,这样编码/解码便变成了序列化(marshaling)Java对象为XML或JSON,或者相反,将对应的对象转换为Java对象。

编码器是javax.websocket.Encoder接口的一个实现,而解码器则是javax.websocket.Decoder的一个实现。EndPoint实例需要以某种方式知道可能的编码/解码器有哪些,如果使用注解驱动的方法,编码/解码器的列表可以通过@ClientEndPoint和@ServerEndpoint注解中编码/解码器元素进行传递。

下面的示例代码,展示了如何注册一个定义了MyJavaObject到文本消息的转换的编码器类MessageEncoder,以及进行相反的转换的解码器类MessageDecoder。

  1. @ServerEndpoint(value="/endpoint", encoders = MessageEncoder.class, decoders= MessageDecoder.class)
  2. public class MyEndpoint {
  3. ...
  4. }
  5.  
  6. class MessageEncoder implements Encoder.Text {
  7. @override
  8. public String encode(MyJavaObject obj) throws EncodingException {
  9. ...
  10. }
  11. }
  12.  
  13. class MessageDecoder implements Decoder.Text {
  14. @override
  15. public MyJavaObject decode (String src) throws DecodeException {
  16. ...
  17. }
  18.  
  19. @override
  20. public boolean willDecode (String src) {
  21. // return true if we want to decode this String into a MyJavaObject instance
  22. }
  23. }

Encoder接口有许多的子接口:

  • Encoder.Text用于将Java对象转换为文本消息
  • Encoder.TextStream用于将Java对象添加到字符流中
  • Encoder.Binary用于将Java对象转换为二进制消息
  • Encoder.BinaryStream用于将Java对象添加到二进制流

同样的,Decoder接口也有四个子接口:

  • Decoder.Text用于将文件消息转换为Java对象
  • Decoder.TextStream用于从字符流中读取Java对象
  • Decoder.Binary用于将二进制消息转换为Java对象
  • Decoder.BinaryStream用于从二进制流中读取Java对象

结论

WebSocket的Java API为Java开发者提供了一个符合IETF WebSocket标准的标准API。这样,采用任意WebSocket实现的Web客户端或原生客户端便可以很容易与Java后端进行交互。

Java API是高度可配置且灵活性强的,它允许开发者使用他们的首选模式。

 

0 0