libwebsockets 与Netty websocket库之间的通讯 - housekeeper-software/tech GitHub Wiki
问题
libwebsockets(C++)作为websockets 服务器,netty websocket 作为客户端,连接5分钟后服务器断开与netty客户端的连接。
原因分析
libwebsockets 4.2或者更高版本改变了内部超时机制,通过lws_retry_bo_t 去控制连接的超时。一般,我们在服务器上不去设置此选项,因为系统有默认参数,代码如下所示:
context->default_retry.retry_ms_table = default_backoff_table;
context->default_retry.conceal_count =
context->default_retry.retry_ms_table_count =
LWS_ARRAY_SIZE(default_backoff_table);
context->default_retry.jitter_percent = 20;
context->default_retry.secs_since_valid_ping = 300; //notice
context->default_retry.secs_since_valid_hangup = 310; //notice
if (info->retry_and_idle_policy &&
info->retry_and_idle_policy->secs_since_valid_ping) {
context->default_retry.secs_since_valid_ping =
info->retry_and_idle_policy->secs_since_valid_ping;
context->default_retry.secs_since_valid_hangup =
info->retry_and_idle_policy->secs_since_valid_hangup;
}
意思是说,作为 libwebsockets 服务器,对于每条连接,每隔300秒会向客户端发送一个Ping包,如果在10秒内没有收到客户端Pong包回复,则认为客户端已经断开,从而服务器主动断开连接。
解决方案
经过测试,java端使用org.java-websocket包实现websocket client 无此问题。因为内部已经实现了对ping/pong的自动处理。但是netty内部没有默认实现,需要在如下的地方响应:
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
.... //处理其他的业务
} else if (frame instanceof PingWebSocketFrame) {
ch.writeAndFlush(new PongWebSocketFrame());
}
}
至此,问题解决。
其他
到目前为止,只发现 netty 作为客户端的时候有此问题需要注意,其他语言的websocket库一般都有内部默认实现。