C语言的noPoll Web套接字库总是连接不上
noPoll Web socket library in C language always failing to connect
我正在尝试为 C 开发人员构建一个开源的 Cometd 库,以便能够 运行 几乎任何给定设备下的客户端。
我设法用 longPolling 技术完成了握手和数据传输,下一步逻辑上是给用户选择 Websocket 连接的选项。
为了简化工作,我决定为此使用一个库,我再次上网并找到了两个真正相关的库:
问题是我不能让它正常运行,我总是连接失败。看完完整的文档我还是不明白为什么?
这是我的代码:
int main(void)
{
cometd *cometd = cometd_new();
JsonNode *connect = json_node_new(JSON_NODE_OBJECT);
noPollCtx *ctx = nopoll_ctx_new(); //init the context of the lib
noPollMsg *msg; //variable to get messages
if (!ctx) //check if the context is well inited
puts("error ctx is nill");
/*After the new you can enable or disable the Websocket simply do this, enabled by defautl*/
cometd->config->webSockState = true;
cometd_configure(cometd, COMETDOPT_URL, "http://m.zpush.ovh:8080/str/strd");
cometd_configure(cometd, COMETDOPT_MAX_BACKOFF, 5000);
struct _cometd_ext* logger = cometd_ext_logger_new();
cometd_ext_add(&cometd->exts, logger);
cometd_connect(cometd);
connect = cometd_msg_connect_new(cometd);
cometd_transport_send(cometd, connect);
//everything until here is for the handshake wich proceed well and the server returns a successful header
//here i check if the user wants to Websocket upgrade his connection
if (cometd->config->webSockState == true)
{
// here i target the server
noPollConn *conn = nopoll_conn_new(ctx, "54.171.156.38" , "8080" , "m.zpush.ovh:8080" , "ws://m.zpush.ovh:8080/str/strd", NULL, "null");
if (!nopoll_conn_wait_until_connection_ready(conn, 5) )
// here i check if the connection is ready
{puts("nopoll_conn failed"); return (0);}
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40)
{puts("send text just failed."); return(0);}
else
{
while (nopoll_true) //the loop to receive and send messages
{
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn))
{
puts("connection failed during msg wait");
return nopoll_false;
}
}
}
}
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "service/GmY-HuzW/6sd0/updateMeta", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/newFile", handler);
cometd_transport_send(cometd, cometd_ping_ls(cometd, "/service/GmY-HuzW/6sd0/ls"));
cometd_listen(cometd);
nopoll_ctx_unref(ctx);
return 0;
}
NoPoll 实现了调试选项,结果如下:
(proc 49413): (debug) nopoll_ctx.c:260 (nopoll_bool nopoll_ctx_register_conn(noPollCtx *, noPollConn *)) registered connection id 2, role: 0
(proc 49413): (debug) nopoll_conn.c:505 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Created noPoll conn-id=2 (ptr: 0x7f9d00501b60, context: 0x7f9d0041cdf0, socket: 3)
(proc 49413): (debug) nopoll_conn.c:284 (char *__nopoll_conn_get_client_init(noPollConn *)) Created Sec-WebSocket-Key nonce: Z0WLawAAAADGI3syAAAAAA==
(proc 49413): (debug) nopoll_conn.c:551 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Sending websocket client init: GET / HTTP/1.1
Host: 10.0.0.103
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Z0WLawAAAADGI3syAAAAAA==
Origin: http://10.0.0.103
Sec-WebSocket-Version: 13
(proc 49413): (critical) nopoll_conn.c:643 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) ***Failed to send websocket init message, error code was: 57 (2), closing session***
(proc 49413): (debug) nopoll_conn.c:1036 (void nopoll_conn_shutdown(noPollConn *)) shutting down connection id=2 (session: 3, role: client)
(proc 49413): (debug) nopoll_conn.c:651 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Web socket initial client handshake sent
-> 为了更好地阅读:发送 websocket 初始化消息失败,错误代码为:57 (2),关闭会话
我真的希望有人已经成功地使用了这个库,并且可以给我一些提示或指南。任何帮助将不胜感激,并将让我有能力完成这个图书馆。
代码仍然有点乱,但如果你想完整地了解我的代码,我可以上传到 GitHub。
--> 更新 :
我发现了一个克服这个问题的讨厌的技巧,我在 nopoll_conn.c
方法中注释了 N•845 nopoll_conn_shutdown();
行,我想你已经猜到了,它属于图书馆。然后进行安装,不再出现错误 57.
在处理您的示例时,我发现远程服务器正在通过报告以下错误来关闭连接:
INFO: conn=0x1238500, conn-id=2, nopoll_conn_is_ok (0x1238500)=1, nopoll_conn_is_ready (0x1238500)=1...sending content
ERROR: connection failed during msg wait, peer reported status=[1011] and reason=[java.text.ParseException: hello how are you doing, do we connect ?]
也就是说,您为此 WebSocket 发送了意外的应用程序格式,这导致连接关闭。但是,不支持 noPoll 对带正文的关闭帧(包括状态代码和原因)的支持。
我已经更新了库,现在它得到了完全支持。您必须从此处获取库的副本(至少使用 SVN rev 227)。
除此之外,这是一个更新的工作示例,它直达我正在谈论的要点,还有一些功能可以让您获得远程对等方报告的状态和原因:
#include <nopoll.h>
int main (void) {
/* init the context of the lib */
noPollCtx * ctx = nopoll_ctx_new();
/* variable to get messages */
noPollMsg * msg;
noPollConn * conn;
/* nopoll_log_enable (ctx, nopoll_true);
nopoll_log_color_enable (ctx, nopoll_true); */
if (!ctx) {
puts("error ctx is nill");
return -1; /* do not continue */
}
/* here i target the server */
conn = nopoll_conn_new (ctx, "54.171.156.38" ,
"8080" ,
"m.zpush.ovh:8080" ,
"ws://m.zpush.ovh:8080/str/strd",
NULL, "null");
if (!nopoll_conn_wait_until_connection_ready (conn, 5) ) {
/* here i check if the connection is ready */
puts ("nopoll_conn failed");
return -1;
} /* end if */
printf ("INFO: conn=%p, conn-id=%d, nopoll_conn_is_ok (%p)=%d, nopoll_conn_is_ready (%p)=%d...sending content\n",
conn, nopoll_conn_get_id (conn), conn,
nopoll_conn_is_ok (conn), conn,
nopoll_conn_is_ready (conn));
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40) {
puts("send text just failed.");
return - 1;
} /* end if */
while (nopoll_true) {
/* the loop to receive and send messages */
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn)) {
printf ("ERROR: connection failed during msg wait, peer reported status=[%d] and reason=[%s]\n",
nopoll_conn_get_close_status (conn),
nopoll_conn_get_close_reason (conn));
return nopoll_false;
}
}
/* close connection always */
nopoll_conn_close (conn);
/* release context */
nopoll_ctx_unref (ctx);
return 0;
}
此致,
我正在尝试为 C 开发人员构建一个开源的 Cometd 库,以便能够 运行 几乎任何给定设备下的客户端。
我设法用 longPolling 技术完成了握手和数据传输,下一步逻辑上是给用户选择 Websocket 连接的选项。
为了简化工作,我决定为此使用一个库,我再次上网并找到了两个真正相关的库:
问题是我不能让它正常运行,我总是连接失败。看完完整的文档我还是不明白为什么?
这是我的代码:
int main(void)
{
cometd *cometd = cometd_new();
JsonNode *connect = json_node_new(JSON_NODE_OBJECT);
noPollCtx *ctx = nopoll_ctx_new(); //init the context of the lib
noPollMsg *msg; //variable to get messages
if (!ctx) //check if the context is well inited
puts("error ctx is nill");
/*After the new you can enable or disable the Websocket simply do this, enabled by defautl*/
cometd->config->webSockState = true;
cometd_configure(cometd, COMETDOPT_URL, "http://m.zpush.ovh:8080/str/strd");
cometd_configure(cometd, COMETDOPT_MAX_BACKOFF, 5000);
struct _cometd_ext* logger = cometd_ext_logger_new();
cometd_ext_add(&cometd->exts, logger);
cometd_connect(cometd);
connect = cometd_msg_connect_new(cometd);
cometd_transport_send(cometd, connect);
//everything until here is for the handshake wich proceed well and the server returns a successful header
//here i check if the user wants to Websocket upgrade his connection
if (cometd->config->webSockState == true)
{
// here i target the server
noPollConn *conn = nopoll_conn_new(ctx, "54.171.156.38" , "8080" , "m.zpush.ovh:8080" , "ws://m.zpush.ovh:8080/str/strd", NULL, "null");
if (!nopoll_conn_wait_until_connection_ready(conn, 5) )
// here i check if the connection is ready
{puts("nopoll_conn failed"); return (0);}
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40)
{puts("send text just failed."); return(0);}
else
{
while (nopoll_true) //the loop to receive and send messages
{
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn))
{
puts("connection failed during msg wait");
return nopoll_false;
}
}
}
}
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "service/GmY-HuzW/6sd0/updateMeta", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/newFile", handler);
cometd_transport_send(cometd, cometd_ping_ls(cometd, "/service/GmY-HuzW/6sd0/ls"));
cometd_listen(cometd);
nopoll_ctx_unref(ctx);
return 0;
}
NoPoll 实现了调试选项,结果如下:
(proc 49413): (debug) nopoll_ctx.c:260 (nopoll_bool nopoll_ctx_register_conn(noPollCtx *, noPollConn *)) registered connection id 2, role: 0
(proc 49413): (debug) nopoll_conn.c:505 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Created noPoll conn-id=2 (ptr: 0x7f9d00501b60, context: 0x7f9d0041cdf0, socket: 3)
(proc 49413): (debug) nopoll_conn.c:284 (char *__nopoll_conn_get_client_init(noPollConn *)) Created Sec-WebSocket-Key nonce: Z0WLawAAAADGI3syAAAAAA==
(proc 49413): (debug) nopoll_conn.c:551 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Sending websocket client init: GET / HTTP/1.1
Host: 10.0.0.103
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Z0WLawAAAADGI3syAAAAAA==
Origin: http://10.0.0.103
Sec-WebSocket-Version: 13
(proc 49413): (critical) nopoll_conn.c:643 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) ***Failed to send websocket init message, error code was: 57 (2), closing session***
(proc 49413): (debug) nopoll_conn.c:1036 (void nopoll_conn_shutdown(noPollConn *)) shutting down connection id=2 (session: 3, role: client)
(proc 49413): (debug) nopoll_conn.c:651 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Web socket initial client handshake sent
-> 为了更好地阅读:发送 websocket 初始化消息失败,错误代码为:57 (2),关闭会话
我真的希望有人已经成功地使用了这个库,并且可以给我一些提示或指南。任何帮助将不胜感激,并将让我有能力完成这个图书馆。
代码仍然有点乱,但如果你想完整地了解我的代码,我可以上传到 GitHub。
--> 更新 :
我发现了一个克服这个问题的讨厌的技巧,我在 nopoll_conn.c
方法中注释了 N•845 nopoll_conn_shutdown();
行,我想你已经猜到了,它属于图书馆。然后进行安装,不再出现错误 57.
在处理您的示例时,我发现远程服务器正在通过报告以下错误来关闭连接:
INFO: conn=0x1238500, conn-id=2, nopoll_conn_is_ok (0x1238500)=1, nopoll_conn_is_ready (0x1238500)=1...sending content
ERROR: connection failed during msg wait, peer reported status=[1011] and reason=[java.text.ParseException: hello how are you doing, do we connect ?]
也就是说,您为此 WebSocket 发送了意外的应用程序格式,这导致连接关闭。但是,不支持 noPoll 对带正文的关闭帧(包括状态代码和原因)的支持。
我已经更新了库,现在它得到了完全支持。您必须从此处获取库的副本(至少使用 SVN rev 227)。
除此之外,这是一个更新的工作示例,它直达我正在谈论的要点,还有一些功能可以让您获得远程对等方报告的状态和原因:
#include <nopoll.h>
int main (void) {
/* init the context of the lib */
noPollCtx * ctx = nopoll_ctx_new();
/* variable to get messages */
noPollMsg * msg;
noPollConn * conn;
/* nopoll_log_enable (ctx, nopoll_true);
nopoll_log_color_enable (ctx, nopoll_true); */
if (!ctx) {
puts("error ctx is nill");
return -1; /* do not continue */
}
/* here i target the server */
conn = nopoll_conn_new (ctx, "54.171.156.38" ,
"8080" ,
"m.zpush.ovh:8080" ,
"ws://m.zpush.ovh:8080/str/strd",
NULL, "null");
if (!nopoll_conn_wait_until_connection_ready (conn, 5) ) {
/* here i check if the connection is ready */
puts ("nopoll_conn failed");
return -1;
} /* end if */
printf ("INFO: conn=%p, conn-id=%d, nopoll_conn_is_ok (%p)=%d, nopoll_conn_is_ready (%p)=%d...sending content\n",
conn, nopoll_conn_get_id (conn), conn,
nopoll_conn_is_ok (conn), conn,
nopoll_conn_is_ready (conn));
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40) {
puts("send text just failed.");
return - 1;
} /* end if */
while (nopoll_true) {
/* the loop to receive and send messages */
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn)) {
printf ("ERROR: connection failed during msg wait, peer reported status=[%d] and reason=[%s]\n",
nopoll_conn_get_close_status (conn),
nopoll_conn_get_close_reason (conn));
return nopoll_false;
}
}
/* close connection always */
nopoll_conn_close (conn);
/* release context */
nopoll_ctx_unref (ctx);
return 0;
}
此致,