Java WebSocket 基础 消息通信
为了发送WebSocket消息,无论注解式端点还是编程式端点,其API都是相同的:RemoteEndpoint和它的子类
Ping和Pong消息通常被开发人员用来检查WebSocket底层连接的健康性
从Session对象获得的RemoteEndpoint实例提供方法:
public void sendPing(ByteBuffer applicationData) throws IOException, IllegalArgumentException; public void sendPong(ByteBuffer applicationData) throws IOException, IllegalArgumentException
- WebSocket规范定义了Ping和Pong消息可以传输125个字节大小的二进制数据
- 调用这些方法时,如果传入的ByteBuffer参数超过了125个字节,则会抛出IllegalArgumentException异常
- RemoteEndpoint接口和它的派生类中的所有发送消息的方法都会通过抛出IOException异常来表明在消息的传输过程中出现了错误
1. 发送消息
同步发送 RemoteEndpoint.Basic接口
1.1 发送字符串消息
//发送文本消息
public void sendText(String text) throws IOException;
//使用Writter API发送String消息
public Writter getSendStream() throws IOException;
//以分片的方式发送文本消息
public void sendText(String partialMessage, boolean isLast) throws IOException;
1.2 发送二进制消息
//发送二进制消息
public void sendBinary(ByteBuffer data) throws IOException;
//分片发送二进制消息
public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException;
//使用流发送二进制消息
public Outputstream getSendStream() throws IOException;
1.3 发送对象消息
//发送Java对象消息
public void sendObject(Object data) throws IOException, EncodeException;
javax.websocket.Encoder.Text<T>
是最通用的接口,T就是想发送的对象类型(DrawingObject
)- 每次使用sendObject方法发送T类型的对象时,WebSocket实现都会调用相应的编码器,发给远程端点的实际是encode()方法返回的字符串
- 如果你的编码器无法把指定对象转换成字符串,很可能会抛出EncodeException异常,在这种情形下,EncodeException将会传播给sendObject方法
2. 接收消息
2.1 注解式端点接收消息
//接收文本消息
@OnMessage
public void handleTextMessage(String textMessage) {
…
}
//接收二进制消息
@OnMessage
public void handleBinaryMessage(byte[] messageData) {
…
}
@OnMessage
public void handleBinaryMessage(ByteBuffer messageData) {
…
}
//接收Pong消息,需要声明一个类型为 javax.websocket.PongMessage 的方法参数
@OnMessage
public String handlePongMessage(PongMessage pongMessage) {
return “I got ” + pongMessage.getApplicationData().length + ” bytes of data.”;
}
//处理文本消息流
@OnMessage
public void handle(Reader message) {}
//
//处理到达的文本消息片段
@OnMessage
public void handlePartial(String textMessagePart, boolean isLast) {
}
//处理到达的二进制消息片段
@OnMessage
public void handlePartial(byte[] data, boolean isLast) {}
@OnMessage
public void handlePartial(ByteBuffer data, boolean isLast) {}
-
Decoder.Text<T>
把入站的文本消息转换成T类型的对象 -
willDecode
判断消息格式是否要用此解码
2.2 编程式端点接收消息
编程式端点使用什么方式接收消息取决于MessageHandler接口和它的子类性
public class ProgrammaticEchoServer extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
final Session mySession = session;
mySession.addMessageHandler(new MessageHandler.Whole() {
@Override
public void onMessage(String incomingMessage) {
try {
mySession.getBasicRemote().sendText(“I got this (” + incomingMessage + “) so I am sending it back.”);
} catch (IOException e) {
System.out.println(“something went wrong:” + e.getMessage());
}
}
});
}
}
MessageHandler.Whole<String>
文本消息 String-
MessageHandler.Whole<Reader>
文本消息 Java I/O流 -
MessageHandler.Whole<ByteBuffer>
二进制 Java NIO ByteBuffer -
MessageHandler.Whole<byte[]>
二进制 Byte数组 -
MessageHandler.Whole<InputStream>
二进制 Java I/O流 -
MessageHandler.Partial<String>
文本片段 Java字符串序列 -
MessageHandler.Partial<ByteBuffer>
二进制片段 ByteBuffer序列 -
MessageHandler.Partial<byte[]>
二进制片段 字节数组序列 -
MessageHandler.Whole<T>
和Decoder.Text<T>
或者Decoder.TextStream<T>
文本消息 对象类型T -
MessageHandler.Whole<T>
和Decoder.Binary<T>
或者Decoder.BinaryStream<T>
二进制消息 对象类型
//在编程式服务器端点中配置Decoder
public class MyServerApplicationConfig implements ServerApplicationConfig {
@Override
public Set getEndpointConfigs(Set> set) {
Set configSet = new HashSet<>();
List> decoders = new ArrayList<>();
decoders.add(MyOrangeDecoder.class);
ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(MyEndpoint
.class, “/fruit”).decoders(decoders).build();
configSet.add(serverEndpointConfig);
return configSet;
}
@Override
public Set> getAnnotatedEndpointClasses(Set> set) {
return set;
}