Feature/connection state (#25)
* (cmake) add a warning about 32/64 conversion problems. * fix typo * New connection state for server code + fix OpenSSL double init bug * update README
This commit is contained in:
parent
0635313566
commit
eac611ab1e
@ -39,6 +39,7 @@ set( IXWEBSOCKET_SOURCES
|
|||||||
ixwebsocket/IXSelectInterrupt.cpp
|
ixwebsocket/IXSelectInterrupt.cpp
|
||||||
ixwebsocket/IXSelectInterruptPipe.cpp
|
ixwebsocket/IXSelectInterruptPipe.cpp
|
||||||
ixwebsocket/IXSelectInterruptFactory.cpp
|
ixwebsocket/IXSelectInterruptFactory.cpp
|
||||||
|
ixwebsocket/IXConnectionState.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set( IXWEBSOCKET_HEADERS
|
set( IXWEBSOCKET_HEADERS
|
||||||
@ -66,6 +67,7 @@ set( IXWEBSOCKET_HEADERS
|
|||||||
ixwebsocket/IXSelectInterrupt.h
|
ixwebsocket/IXSelectInterrupt.h
|
||||||
ixwebsocket/IXSelectInterruptPipe.h
|
ixwebsocket/IXSelectInterruptPipe.h
|
||||||
ixwebsocket/IXSelectInterruptFactory.h
|
ixwebsocket/IXSelectInterruptFactory.h
|
||||||
|
ixwebsocket/IXConnectionState.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# Platform specific code
|
# Platform specific code
|
||||||
|
17
README.md
17
README.md
@ -10,7 +10,7 @@ communication channels over a single TCP connection. *IXWebSocket* is a C++ libr
|
|||||||
* macOS
|
* macOS
|
||||||
* iOS
|
* iOS
|
||||||
* Linux
|
* Linux
|
||||||
* Android
|
* Android
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@ -63,10 +63,11 @@ Here is what the server API looks like. Note that server support is very recent
|
|||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
|
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server](std::shared_ptr<WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState, &server](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -77,6 +78,12 @@ server.setOnConnectionCallback(
|
|||||||
{
|
{
|
||||||
std::cerr << "New connection" << std::endl;
|
std::cerr << "New connection" << std::endl;
|
||||||
|
|
||||||
|
// A connection state object is available, and has a default id
|
||||||
|
// You can subclass ConnectionState and pass an alternate factory
|
||||||
|
// to override it. It is useful if you want to store custom
|
||||||
|
// attributes per connection (authenticated bool flag, attributes, etc...)
|
||||||
|
std::cerr << "id: " << connectionState->getId() << std::endl;
|
||||||
|
|
||||||
// The uri the client did connect to.
|
// The uri the client did connect to.
|
||||||
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
||||||
|
|
||||||
@ -223,13 +230,13 @@ Here is a simplistic diagram which explains how the code is structured in term o
|
|||||||
+-----------------------+ --- Public
|
+-----------------------+ --- Public
|
||||||
| | Start the receiving Background thread. Auto reconnection. Simple websocket Ping.
|
| | Start the receiving Background thread. Auto reconnection. Simple websocket Ping.
|
||||||
| IXWebSocket | Interface used by C++ test clients. No IX dependencies.
|
| IXWebSocket | Interface used by C++ test clients. No IX dependencies.
|
||||||
| |
|
| |
|
||||||
+-----------------------+
|
+-----------------------+
|
||||||
| |
|
| |
|
||||||
| IXWebSocketServer | Run a server and give each connections its own WebSocket object.
|
| IXWebSocketServer | Run a server and give each connections its own WebSocket object.
|
||||||
| | Each connection is handled in a new OS thread.
|
| | Each connection is handled in a new OS thread.
|
||||||
| |
|
| |
|
||||||
+-----------------------+ --- Private
|
+-----------------------+ --- Private
|
||||||
| |
|
| |
|
||||||
| IXWebSocketTransport | Low level websocket code, framing, managing raw socket. Adapted from easywsclient.
|
| IXWebSocketTransport | Low level websocket code, framing, managing raw socket. Adapted from easywsclient.
|
||||||
| |
|
| |
|
||||||
|
37
ixwebsocket/IXConnectionState.cpp
Normal file
37
ixwebsocket/IXConnectionState.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* IXConnectionState.cpp
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IXConnectionState.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
std::atomic<uint64_t> ConnectionState::_globalId(0);
|
||||||
|
|
||||||
|
ConnectionState::ConnectionState()
|
||||||
|
{
|
||||||
|
computeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionState::computeId()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << _globalId++;
|
||||||
|
_id = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& ConnectionState::getId() const
|
||||||
|
{
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ConnectionState> ConnectionState::createConnectionState()
|
||||||
|
{
|
||||||
|
return std::make_shared<ConnectionState>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
ixwebsocket/IXConnectionState.h
Normal file
33
ixwebsocket/IXConnectionState.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* IXConnectionState.h
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
class ConnectionState {
|
||||||
|
public:
|
||||||
|
ConnectionState();
|
||||||
|
virtual ~ConnectionState() = default;
|
||||||
|
|
||||||
|
virtual void computeId();
|
||||||
|
virtual const std::string& getId() const;
|
||||||
|
|
||||||
|
static std::shared_ptr<ConnectionState> createConnectionState();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string _id;
|
||||||
|
|
||||||
|
static std::atomic<uint64_t> _globalId;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
|||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
std::atomic<bool> SocketOpenSSL::_openSSLInitializationSuccessful(false);
|
std::atomic<bool> SocketOpenSSL::_openSSLInitializationSuccessful(false);
|
||||||
|
std::once_flag SocketOpenSSL::_openSSLInitFlag;
|
||||||
|
|
||||||
SocketOpenSSL::SocketOpenSSL(int fd) : Socket(fd),
|
SocketOpenSSL::SocketOpenSSL(int fd) : Socket(fd),
|
||||||
_ssl_connection(nullptr),
|
_ssl_connection(nullptr),
|
||||||
|
@ -50,7 +50,7 @@ namespace ix
|
|||||||
const SSL_METHOD* _ssl_method;
|
const SSL_METHOD* _ssl_method;
|
||||||
mutable std::mutex _mutex; // OpenSSL routines are not thread-safe
|
mutable std::mutex _mutex; // OpenSSL routines are not thread-safe
|
||||||
|
|
||||||
std::once_flag _openSSLInitFlag;
|
static std::once_flag _openSSLInitFlag;
|
||||||
static std::atomic<bool> _openSSLInitializationSuccessful;
|
static std::atomic<bool> _openSSLInitializationSuccessful;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ namespace ix
|
|||||||
_host(host),
|
_host(host),
|
||||||
_backlog(backlog),
|
_backlog(backlog),
|
||||||
_maxConnections(maxConnections),
|
_maxConnections(maxConnections),
|
||||||
_stop(false)
|
_stop(false),
|
||||||
|
_connectionStateFactory(&ConnectionState::createConnectionState)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -145,6 +146,12 @@ namespace ix
|
|||||||
::close(_serverFd);
|
::close(_serverFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketServer::setConnectionStateFactory(
|
||||||
|
const ConnectionStateFactory& connectionStateFactory)
|
||||||
|
{
|
||||||
|
_connectionStateFactory = connectionStateFactory;
|
||||||
|
}
|
||||||
|
|
||||||
void SocketServer::run()
|
void SocketServer::run()
|
||||||
{
|
{
|
||||||
// Set the socket to non blocking mode, so that accept calls are not blocking
|
// Set the socket to non blocking mode, so that accept calls are not blocking
|
||||||
@ -214,6 +221,12 @@ namespace ix
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ConnectionState> connectionState;
|
||||||
|
if (_connectionStateFactory)
|
||||||
|
{
|
||||||
|
connectionState = _connectionStateFactory();
|
||||||
|
}
|
||||||
|
|
||||||
// Launch the handleConnection work asynchronously in its own thread.
|
// Launch the handleConnection work asynchronously in its own thread.
|
||||||
//
|
//
|
||||||
// the destructor of a future returned by std::async blocks,
|
// the destructor of a future returned by std::async blocks,
|
||||||
@ -221,7 +234,8 @@ namespace ix
|
|||||||
f = std::async(std::launch::async,
|
f = std::async(std::launch::async,
|
||||||
&SocketServer::handleConnection,
|
&SocketServer::handleConnection,
|
||||||
this,
|
this,
|
||||||
clientFd);
|
clientFd,
|
||||||
|
connectionState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "IXConnectionState.h"
|
||||||
|
|
||||||
#include <utility> // pair
|
#include <utility> // pair
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -20,6 +22,8 @@ namespace ix
|
|||||||
{
|
{
|
||||||
class SocketServer {
|
class SocketServer {
|
||||||
public:
|
public:
|
||||||
|
using ConnectionStateFactory = std::function<std::shared_ptr<ConnectionState>()>;
|
||||||
|
|
||||||
SocketServer(int port = SocketServer::kDefaultPort,
|
SocketServer(int port = SocketServer::kDefaultPort,
|
||||||
const std::string& host = SocketServer::kDefaultHost,
|
const std::string& host = SocketServer::kDefaultHost,
|
||||||
int backlog = SocketServer::kDefaultTcpBacklog,
|
int backlog = SocketServer::kDefaultTcpBacklog,
|
||||||
@ -27,6 +31,8 @@ namespace ix
|
|||||||
virtual ~SocketServer();
|
virtual ~SocketServer();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
|
void setConnectionStateFactory(const ConnectionStateFactory& connectionStateFactory);
|
||||||
|
|
||||||
const static int kDefaultPort;
|
const static int kDefaultPort;
|
||||||
const static std::string kDefaultHost;
|
const static std::string kDefaultHost;
|
||||||
const static int kDefaultTcpBacklog;
|
const static int kDefaultTcpBacklog;
|
||||||
@ -60,9 +66,13 @@ namespace ix
|
|||||||
std::condition_variable _conditionVariable;
|
std::condition_variable _conditionVariable;
|
||||||
std::mutex _conditionVariableMutex;
|
std::mutex _conditionVariableMutex;
|
||||||
|
|
||||||
|
//
|
||||||
|
ConnectionStateFactory _connectionStateFactory;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void run();
|
void run();
|
||||||
virtual void handleConnection(int fd) = 0;
|
virtual void handleConnection(int fd,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState) = 0;
|
||||||
virtual size_t getConnectedClientsCount() = 0;
|
virtual size_t getConnectedClientsCount() = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,12 @@ namespace ix
|
|||||||
_onConnectionCallback = callback;
|
_onConnectionCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketServer::handleConnection(int fd)
|
void WebSocketServer::handleConnection(
|
||||||
|
int fd,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
auto webSocket = std::make_shared<WebSocket>();
|
auto webSocket = std::make_shared<WebSocket>();
|
||||||
_onConnectionCallback(webSocket);
|
_onConnectionCallback(webSocket, connectionState);
|
||||||
|
|
||||||
webSocket->disableAutomaticReconnection();
|
webSocket->disableAutomaticReconnection();
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
using OnConnectionCallback = std::function<void(std::shared_ptr<WebSocket>)>;
|
using OnConnectionCallback = std::function<void(std::shared_ptr<WebSocket>,
|
||||||
|
std::shared_ptr<ConnectionState>)>;
|
||||||
|
|
||||||
class WebSocketServer : public SocketServer {
|
class WebSocketServer : public SocketServer {
|
||||||
public:
|
public:
|
||||||
@ -49,7 +50,8 @@ namespace ix
|
|||||||
const static int kDefaultHandShakeTimeoutSecs;
|
const static int kDefaultHandShakeTimeoutSecs;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void handleConnection(int fd) final;
|
virtual void handleConnection(int fd,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState) final;
|
||||||
virtual size_t getConnectedClientsCount() final;
|
virtual size_t getConnectedClientsCount() final;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ namespace ix
|
|||||||
mutable std::mutex _lastSendTimePointMutex;
|
mutable std::mutex _lastSendTimePointMutex;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint;
|
std::chrono::time_point<std::chrono::steady_clock> _lastSendTimePoint;
|
||||||
|
|
||||||
// No data was send through the socket for longer that the heartbeat period
|
// No data was send through the socket for longer than the heartbeat period
|
||||||
bool heartBeatPeriodExceeded();
|
bool heartBeatPeriodExceeded();
|
||||||
|
|
||||||
void sendOnSocket();
|
void sendOnSocket();
|
||||||
|
@ -128,10 +128,11 @@ namespace
|
|||||||
{
|
{
|
||||||
// A dev/null server
|
// A dev/null server
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server, &receivedPingMessages](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server, &receivedPingMessages](std::shared_ptr<ix::WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server, &receivedPingMessages](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState, &server, &receivedPingMessages](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -141,6 +142,7 @@ namespace
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
Logger() << "New server connection";
|
Logger() << "New server connection";
|
||||||
|
Logger() << "id: " << connectionState->getId();
|
||||||
Logger() << "Uri: " << openInfo.uri;
|
Logger() << "Uri: " << openInfo.uri;
|
||||||
Logger() << "Headers:";
|
Logger() << "Headers:";
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
|
@ -18,13 +18,32 @@ using namespace ix;
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
bool startServer(ix::WebSocketServer& server)
|
// Test that we can override the connectionState impl to provide our own
|
||||||
|
class ConnectionStateCustom : public ConnectionState
|
||||||
{
|
{
|
||||||
|
void computeId()
|
||||||
|
{
|
||||||
|
// a very boring invariant id that we can test against in the unittest
|
||||||
|
_id = "foobarConnectionId";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool startServer(ix::WebSocketServer& server,
|
||||||
|
std::string& connectionId)
|
||||||
|
{
|
||||||
|
auto factory = []() -> std::shared_ptr<ConnectionState>
|
||||||
|
{
|
||||||
|
return std::make_shared<ConnectionStateCustom>();
|
||||||
|
};
|
||||||
|
server.setConnectionStateFactory(factory);
|
||||||
|
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server, &connectionId](std::shared_ptr<ix::WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState,
|
||||||
|
&connectionId, &server](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -34,12 +53,15 @@ namespace ix
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
Logger() << "New connection";
|
Logger() << "New connection";
|
||||||
|
Logger() << "id: " << connectionState->getId();
|
||||||
Logger() << "Uri: " << openInfo.uri;
|
Logger() << "Uri: " << openInfo.uri;
|
||||||
Logger() << "Headers:";
|
Logger() << "Headers:";
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
{
|
{
|
||||||
Logger() << it.first << ": " << it.second;
|
Logger() << it.first << ": " << it.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectionId = connectionState->getId();
|
||||||
}
|
}
|
||||||
else if (messageType == ix::WebSocket_MessageType_Close)
|
else if (messageType == ix::WebSocket_MessageType_Close)
|
||||||
{
|
{
|
||||||
@ -78,7 +100,8 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
{
|
{
|
||||||
int port = getFreePort();
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
std::string connectionId;
|
||||||
|
REQUIRE(startServer(server, connectionId));
|
||||||
|
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
bool tls = false;
|
bool tls = false;
|
||||||
@ -111,7 +134,8 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
{
|
{
|
||||||
int port = getFreePort();
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
std::string connectionId;
|
||||||
|
REQUIRE(startServer(server, connectionId));
|
||||||
|
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
bool tls = false;
|
bool tls = false;
|
||||||
@ -147,7 +171,8 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
{
|
{
|
||||||
int port = getFreePort();
|
int port = getFreePort();
|
||||||
ix::WebSocketServer server(port);
|
ix::WebSocketServer server(port);
|
||||||
REQUIRE(startServer(server));
|
std::string connectionId;
|
||||||
|
REQUIRE(startServer(server, connectionId));
|
||||||
|
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
bool tls = false;
|
bool tls = false;
|
||||||
@ -178,6 +203,8 @@ TEST_CASE("Websocket_server", "[websocket_server]")
|
|||||||
// Give us 500ms for the server to notice that clients went away
|
// Give us 500ms for the server to notice that clients went away
|
||||||
ix::msleep(500);
|
ix::msleep(500);
|
||||||
|
|
||||||
|
REQUIRE(connectionId == "foobarConnectionId");
|
||||||
|
|
||||||
server.stop();
|
server.stop();
|
||||||
REQUIRE(server.getClients().size() == 0);
|
REQUIRE(server.getClients().size() == 0);
|
||||||
}
|
}
|
||||||
|
@ -217,10 +217,11 @@ namespace
|
|||||||
bool startServer(ix::WebSocketServer& server)
|
bool startServer(ix::WebSocketServer& server)
|
||||||
{
|
{
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server](std::shared_ptr<ix::WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState, &server](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -230,6 +231,7 @@ namespace
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
Logger() << "New connection";
|
Logger() << "New connection";
|
||||||
|
Logger() << "id: " << connectionState->getId();
|
||||||
Logger() << "Uri: " << openInfo.uri;
|
Logger() << "Uri: " << openInfo.uri;
|
||||||
Logger() << "Headers:";
|
Logger() << "Headers:";
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
|
1
third_party/remote_trailing_whitespaces.sh
vendored
1
third_party/remote_trailing_whitespaces.sh
vendored
@ -1,2 +1,3 @@
|
|||||||
find . -type f -name '*.cpp' -exec sed -i '' 's/[[:space:]]*$//' {} \+
|
find . -type f -name '*.cpp' -exec sed -i '' 's/[[:space:]]*$//' {} \+
|
||||||
find . -type f -name '*.h' -exec sed -i '' 's/[[:space:]]*$//' {} \+
|
find . -type f -name '*.h' -exec sed -i '' 's/[[:space:]]*$//' {} \+
|
||||||
|
find . -type f -name '*.md' -exec sed -i '' 's/[[:space:]]*$//' {} \+
|
||||||
|
@ -114,7 +114,7 @@ namespace ix
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first line of the response describe the return type,
|
// The first line of the response describe the return type,
|
||||||
// => *3 (an array of 3 elements)
|
// => *3 (an array of 3 elements)
|
||||||
auto lineResult = _socket->readLine(nullptr);
|
auto lineResult = _socket->readLine(nullptr);
|
||||||
auto lineValid = lineResult.first;
|
auto lineValid = lineResult.first;
|
||||||
|
@ -29,7 +29,7 @@ Subcommands:
|
|||||||
ws transfer # running on port 8080.
|
ws transfer # running on port 8080.
|
||||||
|
|
||||||
# Start receiver first
|
# Start receiver first
|
||||||
ws receive ws://localhost:8080
|
ws receive ws://localhost:8080
|
||||||
|
|
||||||
# Then send a file. File will be received and written to disk by the receiver process
|
# Then send a file. File will be received and written to disk by the receiver process
|
||||||
ws send ws://localhost:8080 /file/to/path
|
ws send ws://localhost:8080 /file/to/path
|
||||||
|
@ -17,10 +17,11 @@ namespace ix
|
|||||||
ix::WebSocketServer server(port, hostname);
|
ix::WebSocketServer server(port, hostname);
|
||||||
|
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server](std::shared_ptr<WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState, &server](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -30,6 +31,7 @@ namespace ix
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
std::cerr << "New connection" << std::endl;
|
std::cerr << "New connection" << std::endl;
|
||||||
|
std::cerr << "id: " << connectionState->getId() << std::endl;
|
||||||
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
||||||
std::cerr << "Headers:" << std::endl;
|
std::cerr << "Headers:" << std::endl;
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
|
@ -17,10 +17,11 @@ namespace ix
|
|||||||
ix::WebSocketServer server(port, hostname);
|
ix::WebSocketServer server(port, hostname);
|
||||||
|
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[](std::shared_ptr<ix::WebSocket> webSocket)
|
[](std::shared_ptr<ix::WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -30,6 +31,7 @@ namespace ix
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
std::cerr << "New connection" << std::endl;
|
std::cerr << "New connection" << std::endl;
|
||||||
|
std::cerr << "id: " << connectionState->getId() << std::endl;
|
||||||
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
||||||
std::cerr << "Headers:" << std::endl;
|
std::cerr << "Headers:" << std::endl;
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
|
@ -17,10 +17,11 @@ namespace ix
|
|||||||
ix::WebSocketServer server(port, hostname);
|
ix::WebSocketServer server(port, hostname);
|
||||||
|
|
||||||
server.setOnConnectionCallback(
|
server.setOnConnectionCallback(
|
||||||
[&server](std::shared_ptr<ix::WebSocket> webSocket)
|
[&server](std::shared_ptr<ix::WebSocket> webSocket,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
{
|
{
|
||||||
webSocket->setOnMessageCallback(
|
webSocket->setOnMessageCallback(
|
||||||
[webSocket, &server](ix::WebSocketMessageType messageType,
|
[webSocket, connectionState, &server](ix::WebSocketMessageType messageType,
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
size_t wireSize,
|
size_t wireSize,
|
||||||
const ix::WebSocketErrorInfo& error,
|
const ix::WebSocketErrorInfo& error,
|
||||||
@ -30,6 +31,7 @@ namespace ix
|
|||||||
if (messageType == ix::WebSocket_MessageType_Open)
|
if (messageType == ix::WebSocket_MessageType_Open)
|
||||||
{
|
{
|
||||||
std::cerr << "New connection" << std::endl;
|
std::cerr << "New connection" << std::endl;
|
||||||
|
std::cerr << "id: " << connectionState->getId() << std::endl;
|
||||||
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
std::cerr << "Uri: " << openInfo.uri << std::endl;
|
||||||
std::cerr << "Headers:" << std::endl;
|
std::cerr << "Headers:" << std::endl;
|
||||||
for (auto it : openInfo.headers)
|
for (auto it : openInfo.headers)
|
||||||
|
Loading…
Reference in New Issue
Block a user