|
@ -88,6 +88,15 @@ namespace websockets { |
|
|
}; |
|
|
}; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct basic_websocket_info{ |
|
|
|
|
|
libwebsocket_context* context{nullptr}; |
|
|
|
|
|
libwebsocket* wsi{nullptr}; |
|
|
|
|
|
basic_websocket_info(libwebsocket_context* context, libwebsocket* wsi) |
|
|
|
|
|
: context(context) |
|
|
|
|
|
, wsi(wsi) |
|
|
|
|
|
{} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 4-function Protocol, provide functions to handle establishment, closing, receiving and writing (follows receiving)
|
|
|
// 4-function Protocol, provide functions to handle establishment, closing, receiving and writing (follows receiving)
|
|
|
// To let the callback return something non-zero (in case of error), use websockets::runtime_error
|
|
|
// To let the callback return something non-zero (in case of error), use websockets::runtime_error
|
|
|
// Only types with no-arg ctor are allowed (uses placement new, because libwebsockets allocates for us)
|
|
|
// Only types with no-arg ctor are allowed (uses placement new, because libwebsockets allocates for us)
|
|
@ -95,10 +104,10 @@ namespace websockets { |
|
|
struct TestProtocol { |
|
|
struct TestProtocol { |
|
|
typedef T user_type; |
|
|
typedef T user_type; |
|
|
|
|
|
|
|
|
std::function<void(user_type&)> establish_func; |
|
|
std::function<void(user_type&, basic_websocket_info)> establish_func; |
|
|
std::function<void(user_type&)> close_func; |
|
|
std::function<void(user_type&, basic_websocket_info)> close_func; |
|
|
std::function<std::string(user_type&)> write_func; |
|
|
std::function<std::string(user_type&, basic_websocket_info)> write_func; |
|
|
std::function<void(user_type&, std::string)> receive_func; |
|
|
std::function<void(user_type&, std::string, basic_websocket_info)> receive_func; |
|
|
|
|
|
|
|
|
bool verbose{false}; |
|
|
bool verbose{false}; |
|
|
|
|
|
|
|
@ -111,20 +120,21 @@ namespace websockets { |
|
|
|
|
|
|
|
|
int callback(libwebsocket_context* context, libwebsocket* wsi, libwebsocket_callback_reasons reason, void* user_ptr, void *in, size_t len){ |
|
|
int callback(libwebsocket_context* context, libwebsocket* wsi, libwebsocket_callback_reasons reason, void* user_ptr, void *in, size_t len){ |
|
|
user_type& user = *static_cast<user_type*>(user_ptr); |
|
|
user_type& user = *static_cast<user_type*>(user_ptr); |
|
|
|
|
|
basic_websocket_info binfo{context, wsi}; |
|
|
try{ |
|
|
try{ |
|
|
switch (reason) { |
|
|
switch (reason) { |
|
|
case LWS_CALLBACK_ESTABLISHED: |
|
|
case LWS_CALLBACK_ESTABLISHED: |
|
|
lwsl_notice("Connection established (%p, %p)\n", this, user_ptr); |
|
|
lwsl_notice("Connection established (%p, %p)\n", this, user_ptr); |
|
|
new (user_ptr) user_type(); |
|
|
new (user_ptr) user_type(); |
|
|
establish_func(user); |
|
|
establish_func(user, binfo); |
|
|
break; |
|
|
break; |
|
|
case LWS_CALLBACK_CLOSED: |
|
|
case LWS_CALLBACK_CLOSED: |
|
|
lwsl_notice("Connection closed (%p, %p)\n", this, user_ptr); |
|
|
lwsl_notice("Connection closed (%p, %p)\n", this, user_ptr); |
|
|
user.~user_type(); |
|
|
user.~user_type(); |
|
|
close_func(user); |
|
|
close_func(user, binfo); |
|
|
break; |
|
|
break; |
|
|
case LWS_CALLBACK_SERVER_WRITEABLE:{ |
|
|
case LWS_CALLBACK_SERVER_WRITEABLE:{ |
|
|
std::string string_to_send = write_func(user); |
|
|
std::string string_to_send = write_func(user, binfo); |
|
|
if(verbose) std::cout << string_to_send << std::endl; |
|
|
if(verbose) std::cout << string_to_send << std::endl; |
|
|
// we need the extra bytes padding on both sides :(
|
|
|
// we need the extra bytes padding on both sides :(
|
|
|
unsigned char * buf = new unsigned char [LWS_SEND_BUFFER_PRE_PADDING + string_to_send.size() + LWS_SEND_BUFFER_POST_PADDING]; |
|
|
unsigned char * buf = new unsigned char [LWS_SEND_BUFFER_PRE_PADDING + string_to_send.size() + LWS_SEND_BUFFER_POST_PADDING]; |
|
@ -135,7 +145,7 @@ namespace websockets { |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case LWS_CALLBACK_RECEIVE: |
|
|
case LWS_CALLBACK_RECEIVE: |
|
|
receive_func(user, std::string((char*)in, len)); |
|
|
receive_func(user, std::string((char*)in, len), binfo); |
|
|
libwebsocket_callback_on_writable(context, wsi); |
|
|
libwebsocket_callback_on_writable(context, wsi); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
@ -158,6 +168,6 @@ namespace websockets { |
|
|
#define WSstandard_protocol(name, protocol)\ |
|
|
#define WSstandard_protocol(name, protocol)\ |
|
|
{ name, WSprotocol_callback(protocol), sizeof(decltype(protocol)::user_type) } |
|
|
{ name, WSprotocol_callback(protocol), sizeof(decltype(protocol)::user_type) } |
|
|
|
|
|
|
|
|
int default_main(int argc, char **argv, libwebsocket_protocols* protocols); |
|
|
int default_main(int argc, char **argv, libwebsocket_protocols* protocols, std::function<void()> runloop_callback = nullptr); |
|
|
|
|
|
|
|
|
} // namespace websockets
|
|
|
} // namespace websockets
|
|
|