Getter to Class Connection Status
opened this issue · comments
Hi,
First of all, thank you for this great library !
I was wondering, how do I get the status of a Connection ?
Let me explain, in my program, each of the Server's Clients are linked with a User
, therefore when a Client connects to the WsServer
, I instantiate a new User and store the Connection
in it.
But when i need to clean my list of User
, I would like to know the status of the socket so that I can delete the User
when the connection is lost.
With that idea in mind, in my class User you can see that I had to create a boolean closed
, this variable is set to true
by the WsServer.on_close
function.
The User class looks like that:
class User{
std::shared_ptr<WsServer::Connection> connection;
Player* player;
bool closed;
//...
public:
User(std::shared_ptr<WsServer::Connection> co, Player* pl):
connection(co), player(pl), closed(false){}
~User(){
delete player;
}
bool closed(){
return closed;
}
};
Do you think it is possible to add a getter to the Connection
Class to get it's status ?
I would maybe do something like this:
#include "server_ws.hpp"
#include <unordered_map>
using namespace std;
typedef SimpleWeb::SocketServer<SimpleWeb::WS> WsServer;
class Player {
};
int main() {
WsServer server;
server.config.port = 8080;
unordered_map<std::shared_ptr<WsServer::Connection>, Player> connections;
auto &echo = server.endpoint["^/echo/?$"];
echo.on_message = [&server](shared_ptr<WsServer::Connection> connection, shared_ptr<WsServer::Message> message) {
};
echo.on_open = [&connections](shared_ptr<WsServer::Connection> connection) {
connections.emplace(connection, Player());
};
//See RFC 6455 7.4.1. for status codes
echo.on_close = [&connections](shared_ptr<WsServer::Connection> connection, int status, const string & /*reason*/) {
connections.erase(connection);
};
//See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference.html, Error Codes for error code meanings
echo.on_error = [&connections](shared_ptr<WsServer::Connection> connection, const boost::system::error_code &ec) {
connections.erase(connection);
};
server.start();
}
edit: decided to use shared_ptr in unordered_map<std::shared_ptr<WsServer::Connection>, Player> connections;
for simplicity
Of course the above example takes it for granted that you run the server in one thread. If more threads are used, you would need a connections_mutex
that needs to be locked whenever emplace or erase is called.
Thank you, that fast answer, i will try your solution.
And, out of curiosity, why don't you put any getter on the status ?
If it is needed, I'll add the getter. You mean a getter for socket::is_open I take it?
I was thinking something like the javascript implementation of WebSocket with a readyState that could be an enum
Constant | Value | Description |
---|---|---|
CONNECTING | 0 | The connection is not yet open. |
OPEN | 1 | The connection is open and ready to communicate. |
CLOSING | 2 | The connection is in the process of closing. |
CLOSED | 3 | The connection is closed or couldn't be opened. |
so we can have a:
socket::getReadyState;
I do not immediately see a need for this. Also, one can easily implement this oneself using the on_open, on_close/on_error, on_message handlers.
yes it's true but i think it will be nice if we can get the status of the socket somehow without having to redo the work twice.
if i have the time i'll try to do a pull request with a readyState and if you like it you can merge it.