Static Webview - RTC - UDP - TCP - WSS
This commit is contained in:
@ -7,6 +7,8 @@
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
@ -34,7 +36,8 @@ ConnectionPool::~ConnectionPool() {
|
||||
}
|
||||
}
|
||||
|
||||
socket_t ConnectionPool::acquire_connection(const std::string& host, int port, bool is_ssl) {
|
||||
socket_t ConnectionPool::acquire_connection(const std::string& host, int port, bool is_ssl,
|
||||
std::atomic<bool>* cancel) {
|
||||
std::string key = make_key(host, port, is_ssl);
|
||||
|
||||
{
|
||||
@ -83,7 +86,65 @@ socket_t ConnectionPool::acquire_connection(const std::string& host, int port, b
|
||||
|
||||
memcpy(&server_addr.sin_addr, host_entry->h_addr, host_entry->h_length);
|
||||
|
||||
if (::connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
|
||||
#ifdef _WIN32
|
||||
u_long nb_mode = 1;
|
||||
ioctlsocket(sock, FIONBIO, &nb_mode);
|
||||
#else
|
||||
int old_flags = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, old_flags | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
bool connected = (::connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == 0);
|
||||
if (!connected) {
|
||||
#ifdef _WIN32
|
||||
int connect_err = WSAGetLastError();
|
||||
bool in_progress = (connect_err == WSAEWOULDBLOCK || connect_err == WSAEINPROGRESS);
|
||||
#else
|
||||
bool in_progress = (errno == EINPROGRESS);
|
||||
#endif
|
||||
auto deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(15000);
|
||||
while (in_progress) {
|
||||
if (cancel != nullptr && cancel->load()) {
|
||||
in_progress = false;
|
||||
break;
|
||||
}
|
||||
if (std::chrono::steady_clock::now() >= deadline) {
|
||||
in_progress = false;
|
||||
break;
|
||||
}
|
||||
fd_set wfds, efds;
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&efds);
|
||||
FD_SET(sock, &wfds);
|
||||
FD_SET(sock, &efds);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 50000;
|
||||
#ifdef _WIN32
|
||||
int sel = ::select(0, nullptr, &wfds, &efds, &tv);
|
||||
#else
|
||||
int sel = ::select(static_cast<int>(sock) + 1, nullptr, &wfds, &efds, &tv);
|
||||
#endif
|
||||
if (sel > 0) {
|
||||
int so_err = 0;
|
||||
socklen_t so_len = sizeof(so_err);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&so_err, &so_len);
|
||||
connected = (so_err == 0);
|
||||
break;
|
||||
}
|
||||
if (sel < 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
nb_mode = 0;
|
||||
ioctlsocket(sock, FIONBIO, &nb_mode);
|
||||
#else
|
||||
fcntl(sock, F_SETFL, old_flags);
|
||||
#endif
|
||||
|
||||
if (!connected) {
|
||||
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to connect to %s:%d", host.c_str(), port);
|
||||
#ifdef _WIN32
|
||||
closesocket(sock);
|
||||
@ -165,9 +226,23 @@ std::string ConnectionPool::make_key(const std::string& host, int port, bool is_
|
||||
}
|
||||
|
||||
bool ConnectionPool::is_socket_alive(socket_t socket) const {
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(socket, &rfds);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
#ifdef _WIN32
|
||||
int sel = ::select(0, &rfds, nullptr, nullptr, &tv);
|
||||
#else
|
||||
int sel = ::select(static_cast<int>(socket) + 1, &rfds, nullptr, nullptr, &tv);
|
||||
#endif
|
||||
if (sel < 0) return false;
|
||||
if (sel == 0) return true;
|
||||
char test_byte;
|
||||
int result = ::recv(socket, &test_byte, 1, MSG_PEEK);
|
||||
|
||||
if (result == 0) return false;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (result == SOCKET_ERROR) {
|
||||
int error = WSAGetLastError();
|
||||
@ -178,6 +253,6 @@ bool ConnectionPool::is_socket_alive(socket_t socket) const {
|
||||
return (errno == EWOULDBLOCK || errno == EAGAIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user