Compare commits
4 Commits
feature/no
...
v1.5.0
Author | SHA1 | Date | |
---|---|---|---|
753fc845ac | |||
5dbc00bbfe | |||
14ec8522ef | |||
0c2d1c22bc |
@ -199,6 +199,8 @@ make install # will install to /usr/local on Unix, on macOS it is a good idea to
|
|||||||
|
|
||||||
Headers and a static library will be installed to the target dir.
|
Headers and a static library will be installed to the target dir.
|
||||||
|
|
||||||
|
A [conan](https://conan.io/) file is available at [conan-IXWebSocket](https://github.com/Zinnion/conan-IXWebSocket).
|
||||||
|
|
||||||
There is a unittest which can be executed by typing `make test`.
|
There is a unittest which can be executed by typing `make test`.
|
||||||
|
|
||||||
There is a Dockerfile for running some code on Linux. To use docker-compose you must make a docker container first.
|
There is a Dockerfile for running some code on Linux. To use docker-compose you must make a docker container first.
|
||||||
|
@ -35,7 +35,6 @@ namespace ix
|
|||||||
_activeJobs.erase(_id);
|
_activeJobs.erase(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we want hostname to be copied, not passed as a const reference
|
|
||||||
struct addrinfo* DNSLookup::getAddrInfo(const std::string& hostname,
|
struct addrinfo* DNSLookup::getAddrInfo(const std::string& hostname,
|
||||||
int port,
|
int port,
|
||||||
std::string& errMsg)
|
std::string& errMsg)
|
||||||
|
@ -196,6 +196,25 @@ namespace ix
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Socket::isWaitNeeded()
|
||||||
|
{
|
||||||
|
int err = getErrno();
|
||||||
|
|
||||||
|
if (err == EWOULDBLOCK || err == EAGAIN)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (err == WSAEWOULDBLOCK || err == WSATRY_AGAIN)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Socket::closeSocket(int fd)
|
void Socket::closeSocket(int fd)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -228,8 +247,7 @@ namespace ix
|
|||||||
return ret == len;
|
return ret == len;
|
||||||
}
|
}
|
||||||
// There is possibly something to be writen, try again
|
// There is possibly something to be writen, try again
|
||||||
else if (ret < 0 && (getErrno() == EWOULDBLOCK ||
|
else if (ret < 0 && Socket::isWaitNeeded())
|
||||||
getErrno() == EAGAIN))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -257,8 +275,7 @@ namespace ix
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// There is possibly something to be read, try again
|
// There is possibly something to be read, try again
|
||||||
else if (ret < 0 && (getErrno() == EWOULDBLOCK ||
|
else if (ret < 0 && Socket::isWaitNeeded())
|
||||||
getErrno() == EAGAIN))
|
|
||||||
{
|
{
|
||||||
// Wait with a 1ms timeout until the socket is ready to read.
|
// Wait with a 1ms timeout until the socket is ready to read.
|
||||||
// This way we are not busy looping
|
// This way we are not busy looping
|
||||||
@ -317,13 +334,12 @@ namespace ix
|
|||||||
size_t size = std::min(kChunkSize, length - output.size());
|
size_t size = std::min(kChunkSize, length - output.size());
|
||||||
ssize_t ret = recv((char*)&_readBuffer[0], size);
|
ssize_t ret = recv((char*)&_readBuffer[0], size);
|
||||||
|
|
||||||
if (ret <= 0 && (getErrno() != EWOULDBLOCK &&
|
if (ret <= 0 && !Socket::isWaitNeeded())
|
||||||
getErrno() != EAGAIN))
|
|
||||||
{
|
{
|
||||||
// Error
|
// Error
|
||||||
return std::make_pair(false, std::string());
|
return std::make_pair(false, std::string());
|
||||||
}
|
}
|
||||||
else if (ret > 0)
|
else
|
||||||
{
|
{
|
||||||
output.insert(output.end(),
|
output.insert(output.end(),
|
||||||
_readBuffer.begin(),
|
_readBuffer.begin(),
|
||||||
|
@ -41,8 +41,6 @@ namespace ix
|
|||||||
virtual ~Socket();
|
virtual ~Socket();
|
||||||
bool init(std::string& errorMsg);
|
bool init(std::string& errorMsg);
|
||||||
|
|
||||||
void configure();
|
|
||||||
|
|
||||||
// Functions to check whether there is activity on the socket
|
// Functions to check whether there is activity on the socket
|
||||||
PollResultType poll(int timeoutSecs = kDefaultPollTimeout);
|
PollResultType poll(int timeoutSecs = kDefaultPollTimeout);
|
||||||
bool wakeUpFromPoll(uint8_t wakeUpCode);
|
bool wakeUpFromPoll(uint8_t wakeUpCode);
|
||||||
@ -76,6 +74,7 @@ namespace ix
|
|||||||
const CancellationRequest& isCancellationRequested);
|
const CancellationRequest& isCancellationRequested);
|
||||||
|
|
||||||
static int getErrno();
|
static int getErrno();
|
||||||
|
static bool isWaitNeeded();
|
||||||
|
|
||||||
// Used as special codes for pipe communication
|
// Used as special codes for pipe communication
|
||||||
static const uint64_t kSendRequest;
|
static const uint64_t kSendRequest;
|
||||||
|
@ -247,7 +247,7 @@ namespace ix
|
|||||||
|
|
||||||
if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0)
|
if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0)
|
||||||
{
|
{
|
||||||
if (Socket::getErrno() != EWOULDBLOCK)
|
if (!Socket::isWaitNeeded())
|
||||||
{
|
{
|
||||||
// FIXME: that error should be propagated
|
// FIXME: that error should be propagated
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@ -270,7 +270,7 @@ namespace ix
|
|||||||
_onMessageCallback(WebSocket_MessageType_Error, "", 0,
|
_onMessageCallback(WebSocket_MessageType_Error, "", 0,
|
||||||
connectErr, WebSocketOpenInfo(),
|
connectErr, WebSocketOpenInfo(),
|
||||||
WebSocketCloseInfo());
|
WebSocketCloseInfo());
|
||||||
|
|
||||||
// Only sleep if we aren't in the middle of stopping
|
// Only sleep if we aren't in the middle of stopping
|
||||||
if (!_stop)
|
if (!_stop)
|
||||||
{
|
{
|
||||||
@ -340,9 +340,7 @@ namespace ix
|
|||||||
WebSocket::invokeTrafficTrackerCallback(msg.size(), true);
|
WebSocket::invokeTrafficTrackerCallback(msg.size(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 4. In blocking mode, getting out of this function is triggered by
|
// If we aren't trying to reconnect automatically, exit if we aren't connected
|
||||||
// an explicit disconnection from the callback, or by the remote end
|
|
||||||
// closing the connection, ie isConnected() == false.
|
|
||||||
if (!isConnected() && !_automaticReconnection) return;
|
if (!isConnected() && !_automaticReconnection) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,6 @@ namespace ix
|
|||||||
static OnTrafficTrackerCallback _onTrafficTrackerCallback;
|
static OnTrafficTrackerCallback _onTrafficTrackerCallback;
|
||||||
|
|
||||||
std::atomic<bool> _stop;
|
std::atomic<bool> _stop;
|
||||||
std::atomic<bool> _backgroundThreadRunning;
|
|
||||||
std::atomic<bool> _automaticReconnection;
|
std::atomic<bool> _automaticReconnection;
|
||||||
std::thread _thread;
|
std::thread _thread;
|
||||||
std::mutex _writeMutex;
|
std::mutex _writeMutex;
|
||||||
|
@ -296,8 +296,7 @@ namespace ix
|
|||||||
{
|
{
|
||||||
ssize_t ret = _socket->recv((char*)&_readbuf[0], _readbuf.size());
|
ssize_t ret = _socket->recv((char*)&_readbuf[0], _readbuf.size());
|
||||||
|
|
||||||
if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
|
if (ret < 0 && Socket::isWaitNeeded())
|
||||||
_socket->getErrno() == EAGAIN))
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -553,7 +552,7 @@ namespace ix
|
|||||||
// Get the reason.
|
// Get the reason.
|
||||||
std::string reason(_rxbuf.begin()+ws.header_size + 2,
|
std::string reason(_rxbuf.begin()+ws.header_size + 2,
|
||||||
_rxbuf.begin()+ws.header_size + (size_t) ws.N);
|
_rxbuf.begin()+ws.header_size + (size_t) ws.N);
|
||||||
|
|
||||||
bool remote = true;
|
bool remote = true;
|
||||||
|
|
||||||
close(code, reason, _rxbuf.size(), remote);
|
close(code, reason, _rxbuf.size(), remote);
|
||||||
@ -844,8 +843,7 @@ namespace ix
|
|||||||
{
|
{
|
||||||
ssize_t ret = _socket->send((char*)&_txbuf[0], _txbuf.size());
|
ssize_t ret = _socket->send((char*)&_txbuf[0], _txbuf.size());
|
||||||
|
|
||||||
if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
|
if (ret < 0 && Socket::isWaitNeeded())
|
||||||
_socket->getErrno() == EAGAIN))
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,11 @@ project (ixwebsocket_unittest)
|
|||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
|
||||||
find_package(Sanitizers)
|
find_package(Sanitizers)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
|
||||||
set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
|
||||||
|
|
||||||
set (CMAKE_CXX_STANDARD 14)
|
set (CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
||||||
|
set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
||||||
option(USE_TLS "Add TLS support" ON)
|
option(USE_TLS "Add TLS support" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace ix
|
|||||||
{
|
{
|
||||||
if (!redisClient.publish(channel, message, errMsg))
|
if (!redisClient.publish(channel, message, errMsg))
|
||||||
{
|
{
|
||||||
std::cerr << "Error publishing to channel " << channel
|
std::cerr << "Error publishing to channel " << channel
|
||||||
<< "error: " << errMsg
|
<< "error: " << errMsg
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
Reference in New Issue
Block a user