Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
74833f95e4 |
@ -38,7 +38,7 @@ Interested? Go read the [docs](https://machinezone.github.io/IXWebSocket/)! If t
|
||||
|
||||
IXWebSocket is actively being developed, check out the [changelog](https://machinezone.github.io/IXWebSocket/CHANGELOG/) to know what's cooking. If you are looking for a real time messaging service (the chat-like 'server' your websocket code will talk to) with many features such as history, backed by Redis, look at [cobra](https://github.com/machinezone/cobra).
|
||||
|
||||
IXWebSocket client code is autobahn compliant beginning with the 6.0.0 version. See the current [test results](https://bsergean.github.io/autobahn/reports/clients/index.html). Some tests are still failing in the server code.
|
||||
IXWebSocket client code is autobahn compliant beginning with the 6.0.0 version. See the current [test results](https://bsergean.github.io/IXWebSocket/autobahn/index.html). Some tests are still failing in the server code.
|
||||
|
||||
## Users
|
||||
|
||||
|
@ -1,13 +1,9 @@
|
||||
# Changelog
|
||||
All changes to this project will be documented in this file.
|
||||
|
||||
## [7.9.4] - 2020-01-12
|
||||
## [7.9.3] - 2020-01-08
|
||||
|
||||
(openssl + mbedssl) fix #140, can send large files with ws send over ssl / still broken with apple ssl
|
||||
|
||||
## [7.9.3] - 2020-01-10
|
||||
|
||||
(apple ssl) model write method after the OpenSSL one for consistency
|
||||
(Windows) OpenSSL can be used for SSL communication
|
||||
|
||||
## [7.9.2] - 2020-01-06
|
||||
|
||||
|
@ -54,17 +54,14 @@ namespace ix
|
||||
// to ::poll does fix that.
|
||||
//
|
||||
// However poll isn't as portable as select and has bugs on Windows, so we
|
||||
// have a shim to fallback to select on those platforms. See
|
||||
// should write a shim to fallback to select on those platforms. See
|
||||
// https://github.com/mpv-player/mpv/pull/5203/files for such a select wrapper.
|
||||
//
|
||||
nfds_t nfds = 1;
|
||||
struct pollfd fds[2];
|
||||
memset(fds, 0, sizeof(fds));
|
||||
|
||||
fds[0].fd = sockfd;
|
||||
fds[0].events = (readyToRead) ? POLLIN : POLLOUT;
|
||||
|
||||
// this is ignored by poll, but our select based poll wrapper on Windows needs it
|
||||
fds[0].events |= POLLERR;
|
||||
|
||||
// File descriptor used to interrupt select when needed
|
||||
@ -135,11 +132,6 @@ namespace ix
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (sockfd != -1 && (fds[0].revents & POLLERR || fds[0].revents & POLLHUP ||
|
||||
fds[0].revents & POLLNVAL))
|
||||
{
|
||||
pollResult = PollResultType::Error;
|
||||
}
|
||||
|
||||
return pollResult;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ namespace ix
|
||||
virtual void close();
|
||||
|
||||
virtual ssize_t send(char* buffer, size_t length);
|
||||
ssize_t send(const std::string& buffer);
|
||||
virtual ssize_t send(const std::string& buffer);
|
||||
virtual ssize_t recv(void* buffer, size_t length);
|
||||
|
||||
// Blocking and cancellable versions, working with socket that can be set
|
||||
|
@ -265,6 +265,11 @@ namespace ix
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t SocketAppleSSL::send(const std::string& buffer)
|
||||
{
|
||||
return send((char*) &buffer[0], buffer.size());
|
||||
}
|
||||
|
||||
// No wait support
|
||||
ssize_t SocketAppleSSL::recv(void* buf, size_t nbyte)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ namespace ix
|
||||
virtual void close() final;
|
||||
|
||||
virtual ssize_t send(char* buffer, size_t length) final;
|
||||
virtual ssize_t send(const std::string& buffer) final;
|
||||
virtual ssize_t recv(void* buffer, size_t length) final;
|
||||
|
||||
private:
|
||||
|
@ -230,23 +230,35 @@ namespace ix
|
||||
|
||||
ssize_t SocketMbedTLS::send(char* buf, size_t nbyte)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
ssize_t sent = 0;
|
||||
|
||||
ssize_t res = mbedtls_ssl_write(&_ssl, (unsigned char*) buf, nbyte);
|
||||
while (nbyte > 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if (res > 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
else if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
{
|
||||
errno = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
ssize_t res = mbedtls_ssl_write(&_ssl, (unsigned char*) buf, nbyte);
|
||||
|
||||
if (res > 0)
|
||||
{
|
||||
nbyte -= res;
|
||||
sent += res;
|
||||
}
|
||||
else if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
{
|
||||
errno = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t SocketMbedTLS::send(const std::string& buffer)
|
||||
{
|
||||
return send((char*) &buffer[0], buffer.size());
|
||||
}
|
||||
|
||||
ssize_t SocketMbedTLS::recv(void* buf, size_t nbyte)
|
||||
|
@ -35,6 +35,7 @@ namespace ix
|
||||
virtual void close() final;
|
||||
|
||||
virtual ssize_t send(char* buffer, size_t length) final;
|
||||
virtual ssize_t send(const std::string& buffer) final;
|
||||
virtual ssize_t recv(void* buffer, size_t length) final;
|
||||
|
||||
private:
|
||||
|
@ -603,30 +603,42 @@ namespace ix
|
||||
|
||||
ssize_t SocketOpenSSL::send(char* buf, size_t nbyte)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
ssize_t sent = 0;
|
||||
|
||||
if (_ssl_connection == nullptr || _ssl_context == nullptr)
|
||||
while (nbyte > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
ERR_clear_error();
|
||||
ssize_t write_result = SSL_write(_ssl_connection, buf, (int) nbyte);
|
||||
int reason = SSL_get_error(_ssl_connection, (int) write_result);
|
||||
if (_ssl_connection == nullptr || _ssl_context == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reason == SSL_ERROR_NONE)
|
||||
{
|
||||
return write_result;
|
||||
}
|
||||
else if (reason == SSL_ERROR_WANT_READ || reason == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
errno = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
ERR_clear_error();
|
||||
ssize_t write_result = SSL_write(_ssl_connection, buf + sent, (int) nbyte);
|
||||
int reason = SSL_get_error(_ssl_connection, (int) write_result);
|
||||
|
||||
if (reason == SSL_ERROR_NONE)
|
||||
{
|
||||
nbyte -= write_result;
|
||||
sent += write_result;
|
||||
}
|
||||
else if (reason == SSL_ERROR_WANT_READ || reason == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
errno = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t SocketOpenSSL::send(const std::string& buffer)
|
||||
{
|
||||
return send((char*) &buffer[0], buffer.size());
|
||||
}
|
||||
|
||||
ssize_t SocketOpenSSL::recv(void* buf, size_t nbyte)
|
||||
|
@ -33,6 +33,7 @@ namespace ix
|
||||
virtual void close() final;
|
||||
|
||||
virtual ssize_t send(char* buffer, size_t length) final;
|
||||
virtual ssize_t send(const std::string& buffer) final;
|
||||
virtual ssize_t recv(void* buffer, size_t length) final;
|
||||
|
||||
private:
|
||||
|
@ -350,9 +350,28 @@ namespace ix
|
||||
}
|
||||
else if (pollResult == PollResultType::ReadyForRead)
|
||||
{
|
||||
if (!receiveFromSocket())
|
||||
while (true)
|
||||
{
|
||||
return PollResult::AbnormalClose;
|
||||
ssize_t ret = _socket->recv((char*) &_readbuf[0], _readbuf.size());
|
||||
|
||||
if (ret < 0 && Socket::isWaitNeeded())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (ret <= 0)
|
||||
{
|
||||
// if there are received data pending to be processed, then delay the abnormal
|
||||
// closure to after dispatch (other close code/reason could be read from the
|
||||
// buffer)
|
||||
|
||||
closeSocket();
|
||||
|
||||
return PollResult::AbnormalClose;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rxbuf.insert(_rxbuf.end(), _readbuf.begin(), _readbuf.begin() + ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pollResult == PollResultType::Error)
|
||||
@ -720,7 +739,7 @@ namespace ix
|
||||
|
||||
// if an abnormal closure was raised in poll, and nothing else triggered a CLOSED state in
|
||||
// the received and processed data then close the connection
|
||||
if (pollResult != PollResult::Succeeded)
|
||||
if (pollResult == PollResult::AbnormalClose)
|
||||
{
|
||||
_rxbuf.clear();
|
||||
|
||||
@ -1034,17 +1053,19 @@ namespace ix
|
||||
wsheader_type::TEXT_FRAME, message, _enablePerMessageDeflate, onProgressCallback);
|
||||
}
|
||||
|
||||
ssize_t WebSocketTransport::send()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_socketMutex);
|
||||
return _socket->send((char*) &_txbuf[0], _txbuf.size());
|
||||
}
|
||||
|
||||
bool WebSocketTransport::sendOnSocket()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_txbufMutex);
|
||||
|
||||
while (_txbuf.size())
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_socketMutex);
|
||||
ret = _socket->send((char*) &_txbuf[0], _txbuf.size());
|
||||
}
|
||||
ssize_t ret = send();
|
||||
|
||||
if (ret < 0 && Socket::isWaitNeeded())
|
||||
{
|
||||
@ -1065,34 +1086,6 @@ namespace ix
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebSocketTransport::receiveFromSocket()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ssize_t ret = _socket->recv((char*) &_readbuf[0], _readbuf.size());
|
||||
|
||||
if (ret < 0 && Socket::isWaitNeeded())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (ret <= 0)
|
||||
{
|
||||
// if there are received data pending to be processed, then delay the abnormal
|
||||
// closure to after dispatch (other close code/reason could be read from the
|
||||
// buffer)
|
||||
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rxbuf.insert(_rxbuf.end(), _readbuf.begin(), _readbuf.begin() + ret);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebSocketTransport::sendCloseFrame(uint16_t code, const std::string& reason)
|
||||
{
|
||||
bool compress = false;
|
||||
|
@ -99,6 +99,7 @@ namespace ix
|
||||
bool remote = false);
|
||||
|
||||
void closeSocket();
|
||||
ssize_t send();
|
||||
|
||||
ReadyState getReadyState() const;
|
||||
void setReadyState(ReadyState readyState);
|
||||
@ -244,8 +245,6 @@ namespace ix
|
||||
|
||||
bool flushSendBuffer();
|
||||
bool sendOnSocket();
|
||||
bool receiveFromSocket();
|
||||
|
||||
WebSocketSendInfo sendData(wsheader_type::opcode_type type,
|
||||
const std::string& message,
|
||||
bool compress,
|
||||
|
@ -6,4 +6,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define IX_WEBSOCKET_VERSION "7.9.4"
|
||||
#define IX_WEBSOCKET_VERSION "7.9.3"
|
||||
|
@ -55,12 +55,12 @@ set (SOURCES
|
||||
IXDNSLookupTest.cpp
|
||||
IXWebSocketSubProtocolTest.cpp
|
||||
IXSentryClientTest.cpp
|
||||
IXWebSocketChatTest.cpp
|
||||
)
|
||||
|
||||
# Some unittest don't work on windows yet
|
||||
if (UNIX)
|
||||
list(APPEND SOURCES
|
||||
IXWebSocketChatTest.cpp
|
||||
IXWebSocketCloseTest.cpp
|
||||
)
|
||||
endif()
|
||||
|
@ -1,17 +1,8 @@
|
||||
FROM python:3.8.0-alpine3.10
|
||||
|
||||
RUN pip install websockets
|
||||
COPY ws_proxy.py /usr/bin
|
||||
RUN chmod +x /usr/bin/ws_proxy.py
|
||||
|
||||
COPY vendor/protocol.py /usr/local/lib/python3.8/site-packages/websockets/protocol.py
|
||||
|
||||
COPY *.py /usr/bin/
|
||||
COPY entrypoint.sh /usr/bin/
|
||||
RUN chmod +x /usr/bin/*.py
|
||||
|
||||
RUN mkdir /certs
|
||||
COPY *.pem /certs/
|
||||
|
||||
WORKDIR /certs
|
||||
|
||||
EXPOSE 8765 8766
|
||||
CMD ["sh", "/usr/bin/entrypoint.sh"]
|
||||
EXPOSE 8765
|
||||
CMD ["python", "/usr/bin/ws_proxy.py"]
|
||||
|
@ -830,17 +830,3 @@ $ honcho start
|
||||
15:29:59 system | nginx.1 stopped (rc=0)
|
||||
15:29:59 system | websocket_server.1 stopped (rc=-15)
|
||||
```
|
||||
|
||||
## Sending large files over SSL
|
||||
|
||||
Running inside docker
|
||||
|
||||
```
|
||||
$ make docker && make server_ssl
|
||||
```
|
||||
|
||||
On the client
|
||||
|
||||
```
|
||||
$ make ws_mbedtls && cp build/ws/ws /usr/local/bin/ws && ws send --verify_none wss://localhost:8766 /tmp/big_file
|
||||
```
|
||||
|
@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# WS server example
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import websockets
|
||||
|
||||
|
||||
clients = set()
|
||||
|
||||
|
||||
async def echo(websocket, path):
|
||||
clients.add(websocket)
|
||||
|
||||
try:
|
||||
while True:
|
||||
msg = await websocket.recv()
|
||||
|
||||
for ws in clients:
|
||||
if ws != websocket:
|
||||
print(f'Sending {len(msg)} bytes to {ws}')
|
||||
await ws.send(msg)
|
||||
except websockets.exceptions.ConnectionClosedOK:
|
||||
print('Client terminating')
|
||||
clients.remove(websocket)
|
||||
|
||||
|
||||
host = os.getenv('BIND_HOST', 'localhost')
|
||||
print(f'Serving on {host}:8766')
|
||||
|
||||
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30)
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# WS server example
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import pathlib
|
||||
import ssl
|
||||
import websockets
|
||||
|
||||
|
||||
clients = set()
|
||||
|
||||
|
||||
async def echo(websocket, path):
|
||||
clients.add(websocket)
|
||||
|
||||
try:
|
||||
while True:
|
||||
msg = await websocket.recv()
|
||||
|
||||
for ws in clients:
|
||||
if ws != websocket:
|
||||
print(f'Sending {len(msg)} bytes to {ws}')
|
||||
await ws.send(msg)
|
||||
except websockets.exceptions.ConnectionClosedOK:
|
||||
print('Client terminating')
|
||||
clients.remove(websocket)
|
||||
|
||||
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
ssl_context.load_cert_chain('trusted-server-crt.pem',
|
||||
'trusted-server-key.pem')
|
||||
|
||||
host = os.getenv('BIND_HOST', 'localhost')
|
||||
print(f'Serving on {host}:8766')
|
||||
|
||||
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30, ssl=ssl_context)
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
# WS server example
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import websockets
|
||||
|
||||
|
||||
@ -12,10 +11,9 @@ async def echo(websocket, path):
|
||||
print(f'Received {len(msg)} bytes')
|
||||
await websocket.send(msg)
|
||||
|
||||
host = os.getenv('BIND_HOST', 'localhost')
|
||||
print(f'Serving on {host}:8766')
|
||||
|
||||
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30)
|
||||
print('Serving on localhost:8766')
|
||||
start_server = websockets.serve(echo, 'localhost', 8766, max_size=2 ** 25)
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# WS server example
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import pathlib
|
||||
import ssl
|
||||
import websockets
|
||||
|
||||
|
||||
async def echo(websocket, path):
|
||||
msg = await websocket.recv()
|
||||
print(f'Received {len(msg)} bytes')
|
||||
await websocket.send(msg)
|
||||
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
ssl_context.load_cert_chain('trusted-server-crt.pem',
|
||||
'trusted-server-key.pem')
|
||||
|
||||
host = os.getenv('BIND_HOST', 'localhost')
|
||||
print(f'Serving on {host}:8766')
|
||||
|
||||
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30, ssl=ssl_context)
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
case $MODE in
|
||||
echo_server)
|
||||
python /usr/bin/echo_server.py
|
||||
;;
|
||||
echo_server_ssl)
|
||||
python /usr/bin/echo_server_ssl.py
|
||||
;;
|
||||
broadcast_server)
|
||||
python /usr/bin/broadcast_server.py
|
||||
;;
|
||||
broadcast_server_ssl)
|
||||
python /usr/bin/broadcast_server_ssl.py
|
||||
;;
|
||||
esac
|
@ -1 +0,0 @@
|
||||
trusted-client-crt.pem
|
@ -3,7 +3,7 @@ all:
|
||||
|
||||
.PHONY: docker
|
||||
|
||||
NAME := bsergean/echo_server
|
||||
NAME := bsergean/ws_proxy
|
||||
TAG := $(shell cat DOCKER_VERSION)
|
||||
IMG := ${NAME}:${TAG}
|
||||
LATEST := ${NAME}:latest
|
||||
@ -21,15 +21,3 @@ docker_push:
|
||||
docker tag ${IMG} ${LATEST}
|
||||
docker push ${LATEST}
|
||||
docker push ${IMG}
|
||||
|
||||
echo_server:
|
||||
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=echo_server -it --rm bsergean/echo_server:build
|
||||
|
||||
echo_server_ssl:
|
||||
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=echo_server_ssl -it --rm bsergean/echo_server:build
|
||||
|
||||
broadcast_server:
|
||||
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=broadcast_server -it --rm bsergean/echo_server:build
|
||||
|
||||
broadcast_server_ssl:
|
||||
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=broadcast_server_ssl -it --rm bsergean/echo_server:build
|
||||
|
@ -1,19 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLDCCAhSgAwIBAgIJALyEpMxNH62fMA0GCSqGSIb3DQEBCwUAMEExFDASBgNV
|
||||
BAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDETMBEGA1UEAwwK
|
||||
dHJ1c3RlZC1jYTAeFw0xOTEyMjQwMDM3MzVaFw0yMDEyMjMwMDM3MzVaMEUxFDAS
|
||||
BgNVBAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDEXMBUGA1UE
|
||||
AwwOdHJ1c3RlZC1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQCv0T68TZZ7nab+UWPhssGLrInE0egzWn1AF20RkJv1ePIyU0rQbDxuuP+HQbXD
|
||||
FzF6vo2j+5p+VxxvUOfko9V6xad3cB4T3AoFrT5sYI8gQX1uby6pjqVX16TK5t+c
|
||||
i56aNhUXdmcWhuUzlIMIauvueohd+pNj6E6weWqCf8QFD6KYPgK3wWCR4VfWA5QY
|
||||
RJUhv2aI9HrC9P4Mg0mut8LYURRQvGxOhtbAw76FJ6IgBujpgI5GLHgVK5Q1GlXK
|
||||
8W7RlNKNmxX+mzK2D6nHixCUGvrFk9nZgZiaHI/h5x0IGXu0sbwlTPjqQ4Axpofw
|
||||
G1FDi/er4FaGCzU4CKmc7rxRAgMBAAGjIzAhMB8GA1UdEQQYMBaCCWxvY2FsaG9z
|
||||
dIIJMTI3LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4IBAQBkUB6smmApnBfr2eDwKJew
|
||||
GQUMUAa7TlyANYlwQ6EjbAH7H6oNf7Sm63Go2Y72JjZPw3OvZl3QcvvS14QxYJ71
|
||||
kRdvJ1mhEbIaA2QkdZCuDmcQGLfVEyo0j5q03amQKt9QtSv9MsX1Ok2HqGL17Tf1
|
||||
QiUqlkzGCqMIsU20X8QzqwYCGzYZeTFtwLYi75za15Uo/6tE2KwzU7oUhuIebOaS
|
||||
Sa+s2Y1TjpbWyw9usnuQWQ0k1FJR78F1mKJGghmPBoySBHJdLkLYOMhE1u2shgk5
|
||||
N0muMcDRTeHLxm1aBPLHtkRbW3QscEQB6GkT2Dt4U66qNV2CY7Gk0F5xxOrGBC/9
|
||||
-----END CERTIFICATE-----
|
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAr9E+vE2We52m/lFj4bLBi6yJxNHoM1p9QBdtEZCb9XjyMlNK
|
||||
0Gw8brj/h0G1wxcxer6No/uaflccb1Dn5KPVesWnd3AeE9wKBa0+bGCPIEF9bm8u
|
||||
qY6lV9ekyubfnIuemjYVF3ZnFoblM5SDCGrr7nqIXfqTY+hOsHlqgn/EBQ+imD4C
|
||||
t8FgkeFX1gOUGESVIb9miPR6wvT+DINJrrfC2FEUULxsTobWwMO+hSeiIAbo6YCO
|
||||
Rix4FSuUNRpVyvFu0ZTSjZsV/psytg+px4sQlBr6xZPZ2YGYmhyP4ecdCBl7tLG8
|
||||
JUz46kOAMaaH8BtRQ4v3q+BWhgs1OAipnO68UQIDAQABAoIBAG/bIR2uAyJMT7UX
|
||||
VQN/tbFGKTRmE2Owm2UOQl7dcMvAkd5AraViZyROYIvN23TuKZWc7AI7DbR5eWa8
|
||||
w3vsW+JLI9tSImCiKmIoMUHEQOrVn5aF99r6HOmBEZ/hOLyg+1vDMrIFq1pioimp
|
||||
v5+4XrgPjvizddgnMQEHjiLOZIiOtin+alixN/W41Ij0jOtRycM5wq3Xr/0RAs5A
|
||||
ziNeQvWdvDwqa6L9upHZpFfYqP/+KflJPlHLfEkBHZtZQF3uy5tQ1VusfVMO3Xvb
|
||||
Ljk6RBnD9dKayreD9NVzotr36zYEy/V1oGJcP/8AD1xmDA0/2Kb+bfm+WQHG5wp6
|
||||
o09zsZECgYEA5Y3d79Nrfi6InVaZ0r5Y+XXqSZFTsgFnxRseVEbuK4jvrh7eC9jW
|
||||
pWoaXDh8W6RoT59BPSCKtbQ9mjdECh+aJ6MOeCzCiGSppJboOhC1iVFqFuQLDRO7
|
||||
w+2NgkhOvNnJJJYmdTwfokTLmaRUiNqwWAtBm+h7py9e5eXujzqt4+UCgYEAxBKL
|
||||
OO8CWRb0yGlwKoCwYgGCsVauvbZHaELOAKJUB6H+YhZ+SJqd915u8aYs5nbcMyne
|
||||
5kuewzd+32WpkykI0Fz4SrGvDETKB5/Yynblp9m69LNdgYoVWgQqQocXVw0nD/nA
|
||||
KQdFSBZZRExXC/aUAa55txFJitMC4FjgTENgR/0CgYAS/OonxVg15sl8Ika1DPO1
|
||||
JtDLZw8CQWWBA1494GQhC8GvqHP7jOMsaZtml3GJ7w6Fz4mI8eEnaJJT6FBjefu5
|
||||
XZ57yFALEjCKIcVx0CIECsz4ucJEQaadbU/wP+TrcCRYN2dU+TUwqfohaltnupct
|
||||
oTi7Gb7otF1oLN3P0S3DFQKBgEnVjdXPszunOGBrzBBFS6ZsWTG8qarJBFTPq1Fz
|
||||
z17ccrWvMLjYeJnZVr/qyseyhLNDlit02IE82ar4VoYTEr2b9Ofzxy5AjS+X0wRT
|
||||
B6JQjGVvUcvhGq8+GEfbJT/jtQ0ACIuqsD04JT9h2/mmTg/gCveUK/R6B4BCF5zA
|
||||
VnZlAoGBANOG5T7KsOH+Hbb//dEmfZYMQmkO/+1Pac9eP4uDFNAVF00M6XHf5LrR
|
||||
gRp5t46drDtLgxdufN0oUItp8y74EuMa9FHlBQVZRaSqYF4bCgf2PieGApbKWG2n
|
||||
QhnxYfZqf9S2oVK95EHiJxmtumOFBL7YI9NdzNEeoJExS5Bw6kUn
|
||||
-----END RSA PRIVATE KEY-----
|
1432
test/compatibility/python/websockets/vendor/protocol.py
vendored
1432
test/compatibility/python/websockets/vendor/protocol.py
vendored
File diff suppressed because it is too large
Load Diff
@ -72,7 +72,7 @@ namespace ix
|
||||
size_t bufferedAmount = client->bufferedAmount();
|
||||
spdlog::info("{} bytes left to be sent", bufferedAmount);
|
||||
|
||||
std::chrono::duration<double, std::milli> duration(500);
|
||||
std::chrono::duration<double, std::milli> duration(10);
|
||||
std::this_thread::sleep_for(duration);
|
||||
} while (client->bufferedAmount() != 0);
|
||||
}
|
||||
|
@ -10,12 +10,12 @@
|
||||
//
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <iostream>
|
||||
#include <ixwebsocket/IXSocket.h>
|
||||
#include <ixwebsocket/IXWebSocket.h>
|
||||
#include <queue>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
// for convenience
|
||||
using json = nlohmann::json;
|
||||
|
@ -45,8 +45,6 @@ namespace ix
|
||||
ix::WebSocket _webSocket;
|
||||
bool _enablePerMessageDeflate;
|
||||
|
||||
std::atomic<bool> _connected;
|
||||
|
||||
std::mutex _conditionVariableMutex;
|
||||
std::condition_variable _condition;
|
||||
|
||||
@ -58,7 +56,6 @@ namespace ix
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
: _url(url)
|
||||
, _enablePerMessageDeflate(enablePerMessageDeflate)
|
||||
, _connected(false)
|
||||
{
|
||||
_webSocket.disableAutomaticReconnection();
|
||||
_webSocket.setTLSOptions(tlsOptions);
|
||||
@ -122,8 +119,6 @@ namespace ix
|
||||
std::stringstream ss;
|
||||
if (msg->type == ix::WebSocketMessageType::Open)
|
||||
{
|
||||
_connected = true;
|
||||
|
||||
_condition.notify_one();
|
||||
|
||||
log("ws_send: connected");
|
||||
@ -136,8 +131,6 @@ namespace ix
|
||||
}
|
||||
else if (msg->type == ix::WebSocketMessageType::Close)
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
ss << "ws_send: connection closed:";
|
||||
ss << " code " << msg->closeInfo.code;
|
||||
ss << " reason " << msg->closeInfo.reason << std::endl;
|
||||
@ -241,7 +234,7 @@ namespace ix
|
||||
{
|
||||
std::vector<uint8_t> content;
|
||||
{
|
||||
Bench bench("ws_send: load file from disk");
|
||||
Bench bench("load file from disk");
|
||||
content = load(filename);
|
||||
}
|
||||
|
||||
@ -257,22 +250,18 @@ namespace ix
|
||||
|
||||
MsgPack msg(pdu);
|
||||
|
||||
auto serializedMsg = msg.dump();
|
||||
spdlog::info("ws_send: sending {} bytes", serializedMsg.size());
|
||||
Bench bench("Sending file through websocket");
|
||||
auto result = _webSocket.sendBinary(msg.dump(), [throttle](int current, int total) -> bool {
|
||||
spdlog::info("ws_send: Step {} out of {}", current, total);
|
||||
|
||||
Bench bench("ws_send: Sending file through websocket");
|
||||
auto result =
|
||||
_webSocket.sendBinary(serializedMsg, [this, throttle](int current, int total) -> bool {
|
||||
spdlog::info("ws_send: Step {} out of {}", current + 1, total);
|
||||
if (throttle)
|
||||
{
|
||||
std::chrono::duration<double, std::milli> duration(10);
|
||||
std::this_thread::sleep_for(duration);
|
||||
}
|
||||
|
||||
if (throttle)
|
||||
{
|
||||
std::chrono::duration<double, std::milli> duration(10);
|
||||
std::this_thread::sleep_for(duration);
|
||||
}
|
||||
|
||||
return _connected;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!result.success)
|
||||
{
|
||||
@ -280,37 +269,22 @@ namespace ix
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_connected)
|
||||
{
|
||||
spdlog::error("ws_send: Got disconnected from the server");
|
||||
return false;
|
||||
}
|
||||
|
||||
spdlog::info("ws_send: sent {} bytes", serializedMsg.size());
|
||||
|
||||
do
|
||||
{
|
||||
size_t bufferedAmount = _webSocket.bufferedAmount();
|
||||
spdlog::info("ws_send: {} bytes left to be sent", bufferedAmount);
|
||||
|
||||
std::chrono::duration<double, std::milli> duration(500);
|
||||
std::chrono::duration<double, std::milli> duration(10);
|
||||
std::this_thread::sleep_for(duration);
|
||||
} while (_webSocket.bufferedAmount() != 0 && _connected);
|
||||
} while (_webSocket.bufferedAmount() != 0);
|
||||
|
||||
if (_connected)
|
||||
{
|
||||
bench.report();
|
||||
auto duration = bench.getDuration();
|
||||
auto transferRate = 1000 * content.size() / duration;
|
||||
transferRate /= (1024 * 1024);
|
||||
spdlog::info("ws_send: Send transfer rate: {} MB/s", transferRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("ws_send: Got disconnected from the server");
|
||||
}
|
||||
bench.report();
|
||||
auto duration = bench.getDuration();
|
||||
auto transferRate = 1000 * content.size() / duration;
|
||||
transferRate /= (1024 * 1024);
|
||||
spdlog::info("ws_send: Send transfer rate: {} MB/s", transferRate);
|
||||
|
||||
return _connected;
|
||||
return true;
|
||||
}
|
||||
|
||||
void wsSend(const std::string& url,
|
||||
@ -330,10 +304,6 @@ namespace ix
|
||||
webSocketSender.waitForAck();
|
||||
spdlog::info("ws_send: Done !");
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("ws_send: Error sending file.");
|
||||
}
|
||||
|
||||
webSocketSender.stop();
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ namespace ix
|
||||
size_t bufferedAmount = client->bufferedAmount();
|
||||
|
||||
spdlog::info(
|
||||
"{}: [client {}]: has readystate {} bytes left to be sent {}",
|
||||
"{}: [client {}]: has readystate {} bytes left to be sent",
|
||||
"ws_transfer",
|
||||
id,
|
||||
readyStateString,
|
||||
|
Reference in New Issue
Block a user