客户端会话
客户端会话(ClientSession)是会话接口(Session)的子集。集群客户端会连接多个地址,内部会有多个会话,有些方法不便使用,所以有了 ClientSession 这个子集。非集群模式下,可以强转为 Session。
但因为侧端不同,客户端有自己的一些隐式特点
1、客户端会话
- ClientSession 关闭
编码 | 描述 | 说明 |
---|---|---|
1000 | 因协议关闭开始(安全关闭) | “本端”可以再发消息。心跳继续。但不建议再使用 |
1001 | 因协议指令关闭 | “本端”再发消息会尝试重连。心跳继续 |
1002 | 因协议非法关闭 | 同上 |
1002 | 因协议非法关闭 | 同上 |
2001 | 因异常关闭 | 同上 |
2002 | 因重连关闭 | 同上 |
2008 | 因打开失败关闭 | 同上 |
2009 | 因用户主动关闭(不可再重连) | 给“对端”发送关闭协议帧(成功的话会触发关闭事件)。心跳中止。 “本端”再发消息会异常。需要手动重连后才能再发 |
如果是服务端的 Sessoin 没有心跳和重连。其它一样。
- ClientSession 心跳与自动重连
socket.d 是个长连接协议,通过心跳与自动重连保证连接的可靠性。心跳,客户端会定时发送 Ping 协议帧(默认为20秒,可配置)。服务端收到后会答复 Pong 协议帧。
心跳时,如果发现连接是无效的会尝试重新重连。这个也称为“自动重连”。
//配置心跳间隔(单位毫秒)。//更多配置参考“配置类”
ClientSession session = SocketD.createClient("sd:ws://127.0.0.1:8602/?u=a&p=2")
.config(c->c.heartbeatInterval(20_000))
.open();
- ClientSession 手动重连与自动重连的区别
自动重连,是由心跳机制触发的行为。在主动调用 session.close()
心跳会取消,不再支持自动重连。如果还需要再连接或发送消息,需要主动调用 session.reconnect()
。
手动重连,还可以应用在关闭事件里。在关闭时异步尝试重连(能连上去的机率比较低)。
//手动重连应用1(能连上去的机率比较低。刚断开,环境可能不未恢复)
ClientSession sessoin = SocketD.createClient("sd:ws://127.0.0.1:8602/?u=a&p=2")
.listen(new EventListener().doOnClose((s) -> {
RunUtils.delay(s::reconnect, 1000);//1秒后尝试一次重连。
}))
.open();
//手动重连应用2(做单元测试经常会用)
session.close();
session.reconnect();
2、客户端会话接口
- ClientSession 完整接口(以 Java 为例)
/**
* 客户会话
*/
public interface ClientSession extends Closeable {
/**
* 是否有效
*/
boolean isValid();
/**
* 是否关闭中
* */
boolean isClosing();
/**
* 获取会话Id
*/
String sessionId();
/**
* 手动重连(一般是自动)
*/
void reconnect() throws IOException;
/**
* 发送
*
* @param event 事件
* @param entity 实体
* @return 流
*/
SendStream send(String event, Entity entity) throws IOException;
/**
* 发送并请求
*
* @param event 事件
* @param entity 实体
* @return 流
*/
default RequestStream sendAndRequest(String event, Entity entity) throws IOException {
return sendAndRequest(event, entity, 0L);
}
/**
* 发送并请求
*
* @param event 事件
* @param entity 实体
* @param timeout 超时(单位:毫秒)
* @return 流
*/
RequestStream sendAndRequest(String event, Entity entity, long timeout) throws IOException;
/**
* 发送并订阅(答复结束之前,不限答复次数)
*
* @param event 事件
* @param entity 实体
* @return 流
*/
default SubscribeStream sendAndSubscribe(String event, Entity entity) throws IOException {
return sendAndSubscribe(event, entity, 0L);
}
/**
* 发送并订阅(答复结束之前,不限答复次数)
*
* @param event 事件
* @param entity 实体
* @param timeout 超时(单位:毫秒)
* @return 流
*/
SubscribeStream sendAndSubscribe(String event, Entity entity, long timeout) throws IOException;
/**
* 预关闭(用于两段式关闭,执行后对端的 session.isClosing() 为 true)
*/
void preclose() throws IOException;
/**
* 关闭
*/
void close() throws IOException;
}