Создание двойного веб / сокет-сервера с mongoose
Я пытаюсь перенести пример, который я построил с Node.js, Express и Socket.io, на mongoose, но у меня возникают проблемы с тем, чтобы созданный сервер реагировал как на соединения WebSocket, так и на общие запросы HTTP.
Я начал с копирования примера web_server из mongoose, который просто создает HTTP-сервер. В этом примере строка 384 звонков mg_create_server(NULL, EV_HANDLER)
где EV_HANDLER
на самом деле NULL - поэтому все HTTP-запросы к серверу просто отображаются соответствующим образом на "document_root", как и следовало ожидать. Все идет нормально.
Однако, когда я смотрю на различные примеры WebSocket, которые поставляются вместе с mongoose, я вижу, что mg_create_server(server, handler)
для вызовов определен фактический метод-обработчик - что-то вроде этого:
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
switch (ev) {
case MG_REQUEST:
if (conn->is_websocket) {
handle_websocket_message(conn);
return MG_TRUE;
}
else {
mg_send_file(conn, "index.html", NULL); // Return MG_MORE after!
return MG_MORE;
}
case MG_WS_CONNECT:
// New websocket connection. Send connection ID back to the client.
conn->connection_param = calloc(1, sizeof(struct conn_data));
mg_websocket_printf(conn, WEBSOCKET_OPCODE_TEXT, "id %p", conn);
return MG_FALSE;
case MG_CLOSE:
free(conn->connection_param);
return MG_TRUE;
case MG_AUTH:
return MG_TRUE;
default:
return MG_FALSE;
}
}
В этих примерах MG_REQUEST
case вручную возвращает "index.html" для любого запроса, который не поступает от WebSocket... отлично подходит для простых примеров, но это не помогает мне понять, как разместить веб-сайт И соединения с сокетами на одном сервере.
Я попробовал просто портировать ev_handler
метод из примеров WebSocket в пример "web_server", но HTTP-запросы, похоже, просто зависают и никогда не разрешаются.
Любая помощь будет оценена!
1 ответ
Есть несколько способов справиться с этим:
Исправьте пример, который у вас есть. Изменить это
mg_send_file(conn, "index.html", NULL); return MG_MORE;
к этому
return MG_FALSE;
Не забудьте установить опцию "document_root".
Используйте fossa - это библиотека того же производителя (Cesanta). Fossa - это расширенная версия Mongoose с более богатым и понятным API. Fossa использует разные события для простого HTTP и Websocket-запроса. Вот пример: https://github.com/cesanta/fossa/blob/master/examples/websocket_chat/websocket_chat.c