Подтвердить что ты не робот

Как отправить данные async через libwebsocket?

Я использую библиотеку hotcat libwebsocket C для небольшого сервера websocket. У меня есть примеры вверх и работаю и могу отправлять данные в ответ на прием данных из websocket (например, эхо отзыва назад обращенных байтов). Тем не менее, я не смог понять, как отправлять данные асинхронно с сервера, не будучи уже в функции обратного вызова libwebsocket. Мне нужен указатель wsi для перехода к libwebsocket_write(), но не вижу, как получить указатель, кроме как в обратном вызове.

Я читал, что libwebsocket не является потокобезопасным, поскольку мой собственный опыт, похоже, подтверждает.

В libwebsockets.c: line2483 я читал, что "функции обратного вызова протокола [...] вызываются периодически, чтобы разрешить передачу async". Это именно то, чего я хочу, но я не наблюдал этого в своем собственном коде и не нашел способ "включить его".

Предложения о том, как писать асинхронно на websocket, который я обслуживаю?

Код для libwebsocket: http://git.warmcat.com/cgi-bin/cgit/libwebsockets/

Пример использования: http://martinsikora.com/libwebsockets-simple-websocket-server

4b9b3361

Ответ 1

Я не нашел супер чистого способа сделать это. Я бы предложил зарегистрировать обратный вызов события, которое сервер может записать клиенту, а затем проверить, есть ли там асинхронная работа для отправки. событие LWS_CALLBACK_SERVER_WRITEABLE такое, и если вы вызываете libwebsocket_callback_on_writable(context, wsi); из вашего обратного вызова, он будет периодически вызываться.

Итак, что-то вроде этого:

static int callback_myprotocol(struct libwebsocket_context *context,
                               struct libwebsocket *wsi,
                               enum libwebsocket_callback_reasons reason,
                               void *user, void *in, size_t len)
{
    SendState *ss = (SendState*)user;

    switch (reason) {
    case LWS_CALLBACK_ESTABLISHED: 
        printf("connection established\n");
        // get the ball rolling
        libwebsocket_callback_on_writable(context, wsi);
        break;

    case LWS_CALLBACK_SERVER_WRITEABLE: {
        if (!work_to_be_done) {
            // schedule ourselves to run next tick anyway
            libwebsocket_callback_on_writable(context, wsi);
            return 0;
        }
        // send our asynchronous message
        libwebsocket_write(wsi, buf, size, flag);
        // and schedule ourselves again
        libwebsocket_callback_on_writable(context, wsi);
        break;
    }
    default:
        break;
    }

    return 0;
}

Я адаптировал это из примера test-fraggle.c; выше пример примерно того, что этот пример делает для отправки сообщений в более мелких фрагментах.