如何使Libwebsockets的LWS_CALLBACK_RECEIVE进入指定协议回调函数
问题描述
基于Libwebsockets官方服务器示例的代码功能正常,但使用下述JavaScript客户端代码连接时,LWS_CALLBACK_RECEIVE始终进入callback_http()函数,如何让它进入callback_example()函数?
JavaScript客户端代码
let socket = new WebSocket("ws://172.16.20.202:8001/example-protocol");
Libwebsocket服务端协议配置代码
static struct lws_protocols protocols[] = { /* The first protocol must always be the HTTP handler */ { "http-only", /* name */ callback_http, /* callback */ 0, /* No per session data. */ 0, /* max frame size / rx buffer */ }, { "example-protocol", callback_example, sizeof(per_session_data), EXAMPLE_RX_BUFFER_BYTES, }, { NULL, NULL, 0, 0 } /* terminator */ };
解决方法
问题核心在于Libwebsockets的协议匹配逻辑:它是通过WebSocket握手请求里的Sec-WebSocket-Protocol请求头来匹配服务端定义的协议名,而非URL路径。你当前的客户端把协议名放在了URL路径中,服务端无法识别,只能走默认的HTTP回调。
步骤1:修改客户端代码
调整WebSocket连接方式,在构造函数的第二个参数指定协议名,URL路径使用常规路径(比如根路径):
let socket = new WebSocket("ws://172.16.20.202:8001/", "example-protocol");
修改后客户端会在握手时发送Sec-WebSocket-Protocol: example-protocol请求头,服务端就能匹配到对应的callback_example回调。
可选:自定义路径路由(特殊业务需求)
如果必须通过URL路径区分不同WebSocket服务,可以在callback_http中手动处理协议切换:
- 在
callback_http中捕获LWS_CALLBACK_HTTP事件,判断请求路径是否为/example-protocol - 调用
lws_set_protocol_by_name将当前会话切换到example-protocol - 后续的
LWS_CALLBACK_RECEIVE就会进入callback_example
但这种方式属于自定义逻辑,推荐优先使用标准的Sec-WebSocket-Protocol头匹配方式。
内容的提问来源于stack exchange,提问作者Robber Pen
相关产品推荐
相关产品推荐

