【问题标题】:GWAN Bidirectional Communication using websockets使用 websockets 的 GWAN 双向通信
【发布时间】:2013-05-12 15:51:27
【问题描述】:

已解决

我对读取问题的解决方案是将代码移动到处理程序,并在那里使用 HDL_AFTER_READ 状态来处理 websocket 连接。握手回复缓冲区后,返回 2 发送。此外,您可能想要更改 KALIVE_TMO,因为这决定了在没有流量的情况下连接关闭的时间。我还没有完成整个 websocket 的事情,因为之后我似乎无法识别连接(US_REQUEST_DATA 在这里不起作用),但这是一个不同的话题,我只在这里提到它,所以人们知道我为什么没有(还)更新我的代码。

-- 原始问题:

我目前正在尝试让 websockets 与 GWAN (http://gwan.com/) 4.3.14 一起使用。到目前为止,我已经通过 firefox/chrome 的连接握手,但之后连接在几秒钟后关闭。

我已经猜到为什么会发生这种情况,这可能是服务器缺少 PONG,但我现在的问题是,我不知道如何从 servlet 中从客户端读取更多数据。我发现似乎可以从处理程序中做到这一点(至少根据手册,我发现它是错误/过时的几次),但似乎也有几种可能性使用我更喜欢的 servlet。

到目前为止,我已经尝试过: - 在 get_env(argv, HTTP_HEADERS) 的 file_fd 上使用 WK_FD 唤醒;无论我做什么,wake_up 似乎都不起作用(尝试使用 WK_MS,其值在 1000 和 100000 之间,没有区别 - 返回 RC_NOHEADERS + RC_STREAMING 后立即再次调用 servlet) - 在 get_env(argv, CLIENT_SOCKET) 上接收;这里 recv 告诉我,我正在操作的任何东西(值为 0 的 int)都不是套接字(过去也从未让 CLIENT_SOCKET 工作,我一定在那里做错了什么?) - 简单的 sleep(1)(最多 20 个)调用 - READ_XBUF 之后没有新数据,即使客户端上的 wireshark + 服务器上的 tcpdump 告诉我有数据从客户端传输到服务器

过去,我也尝试过使用不同的处理程序状态返回 1 来表示“从客户端读取更多数据”(某些版本之前,所以也许这已经修复了 - 但如前所述,我更喜欢使用 servlet 的解决方案) .这甚至不适用于简单的 ajax post 请求(大多数浏览器在使用 post 时会在第二个 tcp 数据包中发送 post 数据,因此您最初不会使用 gwan 获取有效负载),所以也没有运气。

P.S:在旁注中(我知道 Gil 在这里回答了大多数与 gwan 相关的问题),我已经想在 GWAN 网站上注册业余爱好者支持合同几次,但我没有了解如何通过初始价目表(截至撰写本文时,该价目表还没有欧元)。

我很乐意提供任何可以帮助解决此问题的代码,

非常感谢您的宝贵时间。

编辑:主函数代码(我知道终止代码是错误的,所以请暂时忽略它,因为这也不是我在这里提出问题的原因)

printf("\n---------- RUN ---------\n");


xbuf_t *reply = get_reply(argv);


xbuf_t *request = (xbuf_t *)get_env(argv, READ_XBUF);


   void **pdata = (void**)get_env(argv, US_REQUEST_DATA);


   if (!pdata[0]) { // no request data yet, send upgrade to websocket

  char *upgrade = xbuf_findstr(request, "\r\nUpgrade: websocket\r\n"); // FF only sends this ; chrome also sends "Connection: Upgrade\r\n" afterwards



  if (upgrade != NULL) { // correct upgrade header found?
     const char keyHeader[] ="\r\nSec-WebSocket-Key: ";

     char *key = xbuf_findstr(request, (char *)keyHeader);

     if (key != NULL && (key += sizeof(keyHeader) - 1) != NULL && (request->len - (u32)(key - request->ptr)) >= (u32)23) { // correct key header found? + sanity check
        char websocketGUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // 8 + 4 + 4 + 4 + 12 = 32 + 4 bytes for '-' = 36

        const char data[] = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %20B\r\n\r\n";

        // 36 + 24
        char keyCompose[60];
        strncpy(keyCompose, key, 24);
        strncpy(keyCompose + 24, websocketGUID, 36);

        u8 sha[20];
        sha1_t ctx;
        sha1_init(&ctx);
        sha1_add(&ctx, (u8 *)keyCompose, 60);

        sha1_end(&ctx, sha);


        xbuf_xcat(reply, (char *)data, sha);

        pdata[0] = (void*)1;

        printf("Init.");

        return RC_NOHEADERS + RC_STREAMING; // don't build headers automatically
     }
  }


   } else { // websocket connection here


 const unsigned char websocketTerm[2] = { 0x00, 0xFF }; // websocket close = opcode 0x8
  printf("Streaming!\n"); // TODO: next find way to get next user input (best would be to only wake up on user input or if we have something to send?)

  char *buf = alloca(2);
  buf[0] = 0; buf[1] = 0;

  pdata[0]++;

  if ((int)(pdata[0]) >= 20) {
  xbuf_ncat(reply, (char *)websocketTerm, 2);

  printf("Fin.\n");

  pdata[0] = 0; // cleanup

  return RC_NOHEADERS;
  }

  return RC_NOHEADERS + RC_STREAMING;
   }

   xbuf_cat(reply, "test");

   return 403;

【问题讨论】:

    标签: c websocket g-wan


    【解决方案1】:

    G-WAN Servlets 显然不是实现网络协议的最有效方式。

    由于websockets 破坏了 HTTP 协议,您应该使用 G-WAN Handler

    而 G-WAN Protocol Handlers 致力于这项任务。由于我们最近不得不关注基于 G-WAN 的应用程序,因此该领域缺乏文档和示例。

    【讨论】:

    • 非常感谢,这就是我“害怕”的事情。您能否告诉我如何处理这种“阅读更多”的场景+能够在需要时写入客户端连接,例如获取 gwans 客户端套接字的句柄,以便我可以将其存储在持久处理程序或 kv 中,并将数据从不同的客户端(=servlet/handler)推送到它?如果您可以添加一些信息,我很乐意接受这个作为答案。非常感谢你!
    • 无法编辑我之前的评论,但我现在使用处理程序让它工作了。非常感谢您的帮助!
    • @griffin 你能发布你的解决方案吗?
    【解决方案2】:

    如果没有您使用的任何代码,几乎不可能调试您可能出错的地方。

    另外,我也想知道付款方式,我相信他会使用 PayPal 或其他付款网关,付款会自动从您自己的货币转换为瑞士法郎。如果是直接信用卡商户授权,可能会向您的信用卡公司收取兑换费,通常为 3%。

    【讨论】:

    • 复制并粘贴我得到的代码。但重要的东西仍然在文本中(如果你认为它会有所帮助,我也可以添加不同的唤醒调用等,但我更喜欢让所有内容尽可能短,这就是为什么我尝试不添加所有代码的原因一开始,只是写下我遇到的问题)
    【解决方案3】:

    使用这个库怎么样? https://github.com/payden/libwebsock 而不是尝试重新编写完整的 websocket 实现?

    【讨论】:

    • 问题不在于 websocket 代码本身,这非常简单直接(这就是我不想打扰另一个库的原因)。问题是“......我不知道如何从 servlet 中从客户端读取更多数据。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多