-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Closed
Labels
Description
Hi,
I'm having a problem with Poco::Net::WebSocket.sendFrame(). It takes forever (about 2 seconds) to execute in a non-blocking context. It seems that sendFrame() only works when a receive timeout happens, which makes the receiving end laggy and timeouty. I tried setting the WebSocket to non-blocking mode with ws->setBlocking(false), but that didn't help. If I set ws->setReceiveTimeout(Poco::Timespan(0, 1000)), the receive timeout keeps getting called, and sendFrame() doesn't lag at all.
What am I missing? Should I set the timeout low, catch it, and then ignore it? I'd appreciate any help or suggestions.
I've attached a sample code below.
#include <chrono>
#include <iostream>
#include <thread>
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/Net/WebSocket.h"
class WebSocketClient {
private:
Poco::Net::WebSocket* ws;
std::thread receiveThread;
std::atomic<bool> running{true};
public:
WebSocketClient(const std::string& host, uint16_t port, const std::string& path) {
Poco::Net::Context::Ptr context = new Poco::Net::Context(
Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, 9, false,
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::HTTPSClientSession session(host, port, context);
session.setTimeout(Poco::Timespan(5, 0));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path,
Poco::Net::HTTPMessage::HTTP_1_1);
Poco::Net::HTTPResponse response;
ws = new Poco::Net::WebSocket(session, request, response);
// ws->setReceiveTimeout(Poco::Timespan(0, 1000));
receiveThread = std::thread(&WebSocketClient::receiveLoop, this);
}
~WebSocketClient() {
running = false;
if (receiveThread.joinable()) {
receiveThread.join();
}
delete ws;
}
bool sendMessage(const std::string& message) {
try {
auto start = std::chrono::steady_clock::now();
int flags = Poco::Net::WebSocket::FRAME_TEXT;
int sent = ws->sendFrame(message.data(), message.length(), flags);
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Time taken for sendFrame: " << duration.count() << " ms\n";
return sent == message.length();
} catch (const Poco::TimeoutException& e) {
std::cerr << "Timeout sending message: " << e.what() << std::endl;
return false;
} catch (const Poco::Exception& e) {
std::cerr << "Error sending message: " << e.what() << std::endl;
return false;
}
}
private:
void receiveLoop() {
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
int flags = 0;
while (running) {
try {
int received = ws->receiveFrame(buffer, sizeof(buffer), flags);
if (received > 0) {
std::string message(buffer, received);
std::cout << "Received message: " << message << std::endl;
}
} catch (const Poco::TimeoutException&) {
std::cerr << "Timeout receiving message\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
} catch (const Poco::Exception& e) {
std::cerr << "Error in receive loop: " << e.what() << std::endl;
break;
}
}
}
};
int main() {
try {
WebSocketClient client("echo.websocket.org", 443, "/");
while (true) {
std::cout << "Sending message: test\n";
client.sendMessage("test");
std::this_thread::sleep_for(std::chrono::seconds(3));
}
} catch (const Poco::Exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}```
Reactions are currently unavailable