解决了
我对读取问题的解决方案是将代码移动到处理程序,并在那里使用 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 获取有效负载),所以也没有运气。
PS:在旁注中(因为我知道 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;