решаемымиГван двунаправленная связь с использованием WebSockets
Моего решения проблемы чтения было переместить код в обработчик, и там с помощью HDL_AFTER_READ состояния для обработки соединения WebSocket. Положив рукопожатие в буфер ответа, верните 2, чтобы отправить его. Кроме того, вы можете изменить KALIVE_TMO, поскольку это определяет, сколько времени соединение закрывается, если нет трафика. Я все еще не получил завершение всего веб-приложения, так как я не могу определить соединение после этого (US_REQUEST_DATA здесь не работает), но это другая тема, и я упоминаю здесь только здесь, чтобы люди знали, почему я не (пока) обновление моего кода.
- Оригинальный вопрос:
Я в настоящее время в процессе пытается получить WebSockets работать с Гван (http://gwan.com/) 4.3.14. До сих пор я прошел мимо рукопожатия подключения с помощью firefox/chrome, но после этого соединение закрывается через несколько секунд.
У меня уже есть догадка, почему это происходит, что, вероятно, является недостающим PONG с сервера, но теперь моя проблема заключается в том, что я не могу понять, как читать больше данных от клиента из сервлета. Я обнаружил, что это возможно сделать с помощью обработчика (по крайней мере, согласно руководству, которое, как я обнаружил, ошибочно/устарело пару раз), но также существует пара возможностей используя сервлеты, которые я бы предпочел.
До сих пор я пробовал: - wake_up с WK_FD на file_fd из get_env (argv, HTTP_HEADERS); wake_up не работает независимо от того, что я делаю (пробовал использовать WK_MS со значениями от 1000 до 100000 без разницы - сервлет был вызван снова сразу после возвращения RC_NOHEADERS + RC_STREAMING) - recv on get_env (argv, CLIENT_SOCKET); здесь recv сообщает мне, что все, что я работаю (int со значением 0), не является сокетом (никогда не было CLIENT_SOCKET, чтобы работать в прошлом, я должен что-то делать не так?) - простой сон (1) (вверх до 20) - READ_XBUF не имеет новых данных после этого, даже если wirehark на клиенте + tcpdump на сервере сообщает мне, что есть данные, идущие от клиента к серверу
Я также пробовал использовать разные состояния обработчиков, возвращающих 1 для «читать больше данных от клиента» в прошлом (некоторые версии назад, так что, возможно, это уже исправлено - но, как сказано, я бы предпочел решение с сервлетами). Это даже не работало с простым запросом на отправку ajax (большинство браузеров отправляют данные post во втором пакете tcp при использовании сообщения, так что вы сначала не получаете полезную нагрузку с помощью gwan), так что и вам не повезло.
PS: На боковой панели (как я знаю, Гил отвечает на большинство, если не все связанные с Гваном вопросы здесь), я хотел несколько раз зарегистрироваться на сайте поддержки GWAN на веб-сайте GWAN, но у меня есть не узнать, как пройти первоначальный прайс-лист (который не доступен в евро на момент написания этого).
Я с удовольствием предоставить любой вид кода, который мог бы помочь решению этого
Большое спасибо за ваше время.
Edit: Код основной функции (я знаю, что код завершения неправильно, поэтому, пожалуйста, игнорировать его сейчас, так как это тоже не причина моего вопроса здесь)
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;
Большое спасибо, это то, чего я «боялся». Не могли бы вы просто рассказать мне, как обрабатывать этот сценарий «читать больше» +, имея возможность писать на клиентское соединение, когда это необходимо, например. получить дескриптор gwans client socket, чтобы я мог хранить его в постоянном обработчике или kv и нажимать на него данные с другого клиента (= сервлет/обработчик)? Я бы с радостью принял это как ответ, если бы вы могли добавить немного этой информации. Большое вам спасибо, как всегда! – griffin
Не могу отредактировать мой предыдущий комментарий, но теперь я начал работать с обработчиками. Огромное спасибо за помощь! – griffin
@griffin Не могли бы вы предоставить вам решение? – Nagi