1

我有一个客户端使用 libwebsocket 建立与服务器的连接。每当客户端发送请求时,服务器都会发送响应,并在收到响应后关闭连接。工作正常。

但是当服务器不响应请求时,我遇到了客户端一直等待响应的问题。当什么都没有发生时,永远不会调用回调,并且不可能通过从回调函数返回 -1 来关闭连接。

有什么方法可以使连接关闭超时?还是有可能从回调函数外部关闭连接?

到目前为止,这是我的代码:

int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) {

    switch (reason) {

        case LWS_CALLBACK_CLIENT_ESTABLISHED: {
            std::cout << "LWS_CALLBACK_CLIENT_ESTABLISHED" << std::endl;
            libwebsocket_callback_on_writable(context, wsi);
        }
        break;

        case LWS_CALLBACK_CLOSED:{
            std::cout << "LWS_CALLBACK_CLOSED" << std::endl;
        }
        break;

        case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
        case LWS_CALLBACK_CLIENT_RECEIVE:{
            std::cout << "LWS_CALLBACK_CLIENT_RECEIVE" << endl;
            ((char *)in)[len] = '\0';
            answers_[current_request] = answers_[current_request] + string((char *)in);
            if (libwebsocket_is_final_fragment(wsi)){
                std::cout << "request:" << requests_[current_request] << std::endl;
                std::cout << "answer:" << answers_[current_request] << std::endl;
                current_request++;
                if(current_request >= answers_.size()) {
                    ready = true;

                    return -1;
                }
                libwebsocket_callback_on_writable(context, wsi);
            }
        }
        break;

        case LWS_CALLBACK_CLIENT_WRITEABLE:{
            std::cout << "LWS_CALLBACK_CLIENT_WRITEABLE" << endl;
            unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING];

            const std::string message = std::string(requests_[current_request]);

            std::copy(message.begin(), message.end(), &buf[LWS_SEND_BUFFER_PRE_PADDING]);
            buf[LWS_SEND_BUFFER_PRE_PADDING+(int)message.size()]='\0';

            int n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], (size_t)message.size(), static_cast<libwebsocket_write_protocol>(LWS_WRITE_BINARY));

            if (n < 0){
                std::cout << kLogErr << "bad things are happening" << std::endl;
                return -1;
            }
            if (n < (int)message.size()) {
                std::cout << kLogErr << "Partial write LWS_CALLBACK_CLIENT_WRITEABLE" << std::endl;
                return -1;
            }
        }
        break;

        default:
            std::cout << "CALLBACK_DEFAULT: " << reason << endl;
        break;
    }

    return 0;
}

vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) {

    ready = error = false;
    current_request = 0;

    requests_ = vector<string>(messages);
    answers_ = vector<string>(requests_.size(), "");
    int ietf_version = -1; /* latest */
    wsi_ = libwebsocket_client_connect(context_, server.c_str(), port, 2,  path.c_str(), server.c_str(), "origin", NULL, ietf_version);

    if (wsi_ == NULL) {
        std::cout << kLogErr << "libwebsocket connect failed server:" << server  << " port: " << port << " path: " << path << std::endl;
        error = true;
        return vector<string>();
    }

    bool first_time = true;
    int n = 0;
    while (n >= 0 && !force_exit && !ready) {
        n = libwebsocket_service(context_, 0);
        if(first_time) {
            libwebsocket_callback_on_writable(context_, wsi_);
            first_time = false;
        }
        if (n < 0){
            continue;
        }
        if (wsi_ == NULL) {
            break;
        }
    }
    error = !ready;
    wsi_ = NULL;
    return vector<string>(answers_);
}
4

2 回答 2

0

您可以尝试使用:

case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
   return -1;
break;

或者

lws_set_timeout

但我不是 100% 确定这会起作用,您也可以尝试在他们的 GitHub 上创建问题/问题,他们往往会很快/清楚地回答。

我也不确定你是否应该实施

于 2016-07-12T06:53:13.310 回答
0

我解决了这个问题。

我在里面编写了一个计时器

vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) 

当超时到达时,定时器设置一个标志并触发

libwebsocket_callback_on_writable(context_, wsi_);

再次。然后在

int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len)

如果

LWS_CALLBACK_CLIENT_WRITEABLE

我检查标志,如果设置了回调,则中止

return -1;

工作正常!

于 2016-07-28T06:59:42.620 回答