C语言中的noPoll Web套接字库始终无法连接

时间:2015-05-22 10:09:40

标签: c websocket cometd

我正在尝试为C开发人员构建一个开源Cometd库,以便能够在几乎任何给定设备下运行客户端。

我设法使用longPolling技术完成握手和数据传输,下一步逻辑上是为用户提供选择Websocket连接的选项。

为了简化工作,我决定使用一个库,我再次上网,发现了两个非常相关的库:

  • WSlay库似乎运行良好,但由于epoll.h包含而不能在OSX下运行,但不支持apple。

  • 我认为NoPoll库是最好用的。

问题在于我无法使其正常运行,我总是遇到连接失败。阅读完整的文档后,我仍然不明白为什么?

这是我的代码:

    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 init消息,错误代码为:57(2),关闭会话

我真的希望有人已经成功使用了这个库,可以给我一些提示或指导。任何帮助将非常感谢,并将使我能够完成这个库。

代码仍然有点乱,但是如果你想看看我的代码,我可以上传到GitHub。

- > 更新: 我发现了一个讨厌的技巧来克服这个问题,我在nopoll_conn_shutdown();方法中评论了N•845 nopoll_conn.c行,我认为你已经猜到了它,属于图书馆。然后进行安装,不再出现错误57。

1 个答案:

答案 0 :(得分:1)

根据您的示例,我发现远程服务器正在通过报告以下错误来关闭连接:

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;
}

最诚挚的问候,