libwebsocket:如果一段时间(超时)没有服务器响应,如何断开客户端连接?
libwebsocket: How to disconnect client if there is no server response for a while (with timeout)?
我有一个客户端使用 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] = '[=10=]';
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()]='[=10=]';
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_);
}
您可以尝试使用:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
return -1;
break;
或
lws_set_timeout
但我不是 100% 确定这会奏效,您也可以尝试在他们的 GitHub 上创建一个 issue/question,他们往往会回答 fast/clear。
我也不确定你是否应该实施
我解决了这个问题。
我在
中编写了一个定时器
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;
工作正常!
我有一个客户端使用 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] = '[=10=]';
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()]='[=10=]';
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_);
}
您可以尝试使用:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
return -1;
break;
或
lws_set_timeout
但我不是 100% 确定这会奏效,您也可以尝试在他们的 GitHub 上创建一个 issue/question,他们往往会回答 fast/clear。
我也不确定你是否应该实施
我解决了这个问题。
我在
中编写了一个定时器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;
工作正常!