WebSocket应用

matevip 2021-6-8 大约 3 分钟

# 一、什么是WebSocket?

webSocket 是一种在单个TCP连接上进行全双工通信的协议,这里不在表述 websocket 相关基础知识。

plus 中有两个包和 websocket 相关:

# 1.1 mate-starter-websocket引用

<dependency>
    <groupId>vip.mate</groupId>
    <artifactId>mate-starter-websocket</artifactId>
</dependency>
1
2
3
4

# 二、核心概念

mate-starter-websocket的二次封装中的一些角色信息如下:

# 2.1 Message

websocket 双方交互传递的数据就是 message,message 可以是任意格式的文本信息。

# JsonMessage

为了方便使用和解析,plus 使用 json 来作为消息传递的格式,且规定 json 数据中,必须有 type 属性。

例如字典修改的消息体如下:

{
    // 必有属性
    type: 'dict-change',   
   	// 自定义的属性,用来标识当前哪个字段被修改了
    dictCode: 'gender',
}
1
2
3
4
5
6

新增其他类型的消息,只需要继承 AbstractJsonWebSocketMessage 即可:

public abstract class AbstractJsonWebSocketMessage implements JsonWebSocketMessage {
	public static final String TYPE_FIELD = "type";
	private final String type;

	public AbstractJsonWebSocketMessage(String type) {
		this.type = type;
	}

	@Override
	public String getType() {
		return type;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# PlanTextMessgae

当消息体无法使用 Json 解析时,或者解析出的 Json 中没有 Type,就会认为当前消息是一个普通文本。

PlanText 消息体将直接使用 String 传递。

# 2.2 MessageHandler

针对不同类型的消息,需要不同逻辑的处理,MessageHandler 就是用来管理处理逻辑的。

# JsonMessageHandler

JsonMessage 的处理器必须实现 JsonMessageHandler 接口。

public interface JsonMessageHandler<T extends JsonWebSocketMessage> {

	/**
	 * JsonWebSocketMessage 类型消息处理
	 * @param session 当前接收 session
	 * @param message 当前接收到的 message
	 */
	void handle(WebSocketSession session, T message);

	/**
	 * 当前处理器处理的消息类型
	 * @return messageType
	 */
	String type();

	/**
	 * 当前处理器对应的消息Class
	 * @return Class<T>
	 */
	Class<T> getMessageClass();

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • type(): 返回当前处理器对应的 type 类型,便于接收到不同 type 的 jsonMessage 时,进行调度。
  • getMessageClass():返回 type 对象类型的 Json 映射实体类,Plus 会自动将接收到的消息,转化为此实体实例
  • handle():消息处理方法,在此实现接收到消息后的处理逻辑

Plus 默认提供了一个 PingJsonMessageHandler,当客户端向服务端发送 ping 消息,服务端接收到后会自动响应 pong 消息,用于 websocket 连接保活。

{
    type: "ping"
}
{
    type: "pong"
}
1
2
3
4
5
6

# PlanTextMessageHandler

PlanTextMessgae 的处理器接口定义如下所示:

public interface PlanTextMessageHandler {

	/**
	 * 普通文本消息处理
	 * @param session 当前接收消息的session
	 * @param message 文本消息
	 */
	void handle(WebSocketSession session, String message);

}
1
2
3
4
5
6
7
8
9
10
  • handle():入参为 webSocketSession 和消息原文,实现此方法自定义处理逻辑

# 2.3 WebSocketSession

每一个客户端和服务端建立了 websocket 连接后,都会产生一个 webScoketSession,通过 WebSocketSession 我们就可以向指定客户端进行发送消息。

为了方便快速的定位到用户对应的 webSocketSession,我们需要给每个 session 分配一个唯一标识。

Plus 使用 WebSocketSessionHolder 使用一个 ConcurrentHashMap 持有了所有连接中的 webSocketSession,并在 websocket 连接建立或者断开时,自动加入或移除对应的 session。

而 map 中的 key 则是通过 SessionKeyGenerator 对象获取的:

public interface SessionKeyGenerator {

	/**
	 * 获取当前session的唯一标识
	 * @param webSocketSession 当前session
	 * @return session唯一标识
	 */
	Object sessionKey(WebSocketSession webSocketSession);

}
1
2
3
4
5
6
7
8
9
10

用户需要自己实现该接口,并注册到 spring 容器中。

# 2.4 WebSocketMessageSender

消息发送者,用户可以通过该类进行消息广播,或者对指定 websocketSession 进行消息发送。

# 三、配置属性

mate-starter-websocket 提供了以下的属性配置

上次编辑于: 2021年6月8日 16:31
贡献者: matevip