(ixwebsocket server) change legacy api with 2 nested callbacks, so that the first api takes a weak_ptr<WebSocket> as its first argument

This commit is contained in:
Benjamin Sergeant 2020-07-25 11:42:07 -07:00
parent 0388459bd0
commit 847fc142d1
5 changed files with 70 additions and 48 deletions

View File

@ -1,6 +1,10 @@
# Changelog # Changelog
All changes to this project will be documented in this file. All changes to this project will be documented in this file.
## [10.0.0] - 2020-07-25
(ixwebsocket server) change legacy api with 2 nested callbacks, so that the first api takes a weak_ptr<WebSocket> as its first argument
## [9.10.7] - 2020-07-25 ## [9.10.7] - 2020-07-25
(ixwebsocket) add WebSocketProxyServer, from ws. Still need to make the interface better. (ixwebsocket) add WebSocketProxyServer, from ws. Still need to make the interface better.

View File

@ -248,6 +248,8 @@ uint32_t m = webSocket.getMaxWaitBetweenReconnectionRetries();
### Legacy api ### Legacy api
This api was actually changed to take a weak_ptr<WebSocket> as the first argument to setOnConnectionCallback ; previously it would take a shared_ptr<WebSocket> which was creating cycles and then memory leaks problems.
```cpp ```cpp
#include <ixwebsocket/IXWebSocketServer.h> #include <ixwebsocket/IXWebSocketServer.h>
@ -258,41 +260,49 @@ uint32_t m = webSocket.getMaxWaitBetweenReconnectionRetries();
ix::WebSocketServer server(port); ix::WebSocketServer server(port);
server.setOnConnectionCallback( server.setOnConnectionCallback(
[&server](std::shared_ptr<WebSocket> webSocket, [&server](std::weak_ptr<WebSocket> webSocket,
std::shared_ptr<ConnectionState> connectionState, std::shared_ptr<ConnectionState> connectionState,
std::unique_ptr<ConnectionInfo> connectionInfo) std::unique_ptr<ConnectionInfo> connectionInfo)
{ {
std::cout << "Remote ip: " << connectionInfo->remoteIp << std::endl; std::cout << "Remote ip: " << connectionInfo->remoteIp << std::endl;
webSocket->setOnMessageCallback( auto ws = webSocket.lock();
[webSocket, connectionState, &server](const ix::WebSocketMessagePtr msg) if (ws)
{ {
if (msg->type == ix::WebSocketMessageType::Open) ws->setOnMessageCallback(
[webSocket, connectionState, &server](const ix::WebSocketMessagePtr msg)
{ {
std::cout << "New connection" << std::endl; if (msg->type == ix::WebSocketMessageType::Open)
// 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::cout << "id: " << connectionState->getId() << std::endl;
// The uri the client did connect to.
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{ {
std::cout << it.first << ": " << it.second << std::endl; std::cout << "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::cout << "id: " << connectionState->getId() << std::endl;
// The uri the client did connect to.
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
std::cout << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
// For an echo server, we just send back to the client whatever was received by the server
// All connected clients are available in an std::set. See the broadcast cpp example.
// Second parameter tells whether we are sending the message in binary or text mode.
// Here we send it in the same mode as it was received.
auto ws = webSocket.lock();
if (ws)
{
ws->send(msg->str, msg->binary);
}
} }
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
// For an echo server, we just send back to the client whatever was received by the server
// All connected clients are available in an std::set. See the broadcast cpp example.
// Second parameter tells whether we are sending the message in binary or text mode.
// Here we send it in the same mode as it was received.
webSocket->send(msg->str, msg->binary);
} }
} }
); );

View File

@ -53,28 +53,35 @@ namespace ix
}; };
server.setConnectionStateFactory(factory); server.setConnectionStateFactory(factory);
server.setOnConnectionCallback( server.setOnConnectionCallback([remoteUrl,
[remoteUrl, verbose](std::shared_ptr<ix::WebSocket> webSocket, verbose](std::weak_ptr<ix::WebSocket> webSocket,
std::shared_ptr<ConnectionState> connectionState, std::shared_ptr<ConnectionState> connectionState,
std::unique_ptr<ConnectionInfo> connectionInfo) { std::unique_ptr<ConnectionInfo> connectionInfo) {
auto state = std::dynamic_pointer_cast<ProxyConnectionState>(connectionState); auto state = std::dynamic_pointer_cast<ProxyConnectionState>(connectionState);
auto remoteIp = connectionInfo->remoteIp; auto remoteIp = connectionInfo->remoteIp;
// Server connection // Server connection
state->webSocket().setOnMessageCallback( state->webSocket().setOnMessageCallback(
[webSocket, state, remoteIp, verbose](const WebSocketMessagePtr& msg) { [webSocket, state, remoteIp, verbose](const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Close) if (msg->type == ix::WebSocketMessageType::Close)
{
state->setTerminated();
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
auto ws = webSocket.lock();
if (ws)
{ {
state->setTerminated(); ws->send(msg->str, msg->binary);
} }
else if (msg->type == ix::WebSocketMessageType::Message) }
{ });
webSocket->send(msg->str, msg->binary);
}
});
// Client connection // Client connection
webSocket->setOnMessageCallback( auto ws = webSocket.lock();
if (ws)
{
ws->setOnMessageCallback(
[state, remoteUrl, verbose](const WebSocketMessagePtr& msg) { [state, remoteUrl, verbose](const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open) if (msg->type == ix::WebSocketMessageType::Open)
{ {
@ -101,7 +108,8 @@ namespace ix
state->webSocket().send(msg->str, msg->binary); state->webSocket().send(msg->str, msg->binary);
} }
}); });
}); }
});
auto res = server.listen(); auto res = server.listen();
if (!res.first) if (!res.first)

View File

@ -23,7 +23,7 @@ namespace ix
{ {
public: public:
using OnConnectionCallback = using OnConnectionCallback =
std::function<void(std::shared_ptr<WebSocket>, std::function<void(std::weak_ptr<WebSocket>,
std::shared_ptr<ConnectionState>, std::shared_ptr<ConnectionState>,
std::unique_ptr<ConnectionInfo> connectionInfo)>; std::unique_ptr<ConnectionInfo> connectionInfo)>;

View File

@ -6,4 +6,4 @@
#pragma once #pragma once
#define IX_WEBSOCKET_VERSION "9.10.7" #define IX_WEBSOCKET_VERSION "10.0.0"