diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ba8f418a..18f5b9d1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -96,4 +96,12 @@ if(WIN32) elseif(UNIX) find_package(Threads REQUIRED) target_link_libraries(webbinaryproxy pthread) -endif() \ No newline at end of file +endif() + +add_executable(chatwebsocket ChatWebsocket.cpp) +if(WIN32) + target_link_libraries(chatwebsocket ws2_32) +elseif(UNIX) + find_package(Threads REQUIRED) + target_link_libraries(chatwebsocket pthread) +endif() diff --git a/examples/ChatWebsocket.cpp b/examples/ChatWebsocket.cpp new file mode 100644 index 00000000..265607f3 --- /dev/null +++ b/examples/ChatWebsocket.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace brynet; +using namespace brynet::net; +using namespace brynet::net::http; + +std::string getBody() +{ + + return R""( + + + + + + +

Message received:

+

Message to send:

+ + + + )""; +} + + +int main(int argc, char **argv) +{ + if (argc != 3) + { + fprintf(stderr, "Usage: \n"); + exit(-1); + } + + std::mutex lockClients; + std::list clients; + + const auto port = std::atoi(argv[1]); + auto service = TcpService::Create(); + service->startWorkerThread(atoi(argv[2])); + + auto httpEnterCallback = [&port](const HTTPParser& httpParser, + const HttpSession::Ptr& session) { + (void)httpParser; + HttpResponse response; + auto body = std::regex_replace(getBody(), std::regex("_PORT_"), std::to_string(port)); + + response.setBody(body); + std::string result = response.getResult(); + session->send(result.c_str(), result.size(), [session]() { + session->postShutdown(); + }); + }; + + auto wsEnterCallback = [&clients, &lockClients](const HttpSession::Ptr& httpSession, + WebSocketFormat::WebSocketFrameType opcode, + const std::string& payload) { + std::cout << "frame enter of type:" << int(opcode) << std::endl; + std::cout << "payload is:" << payload << std::endl; + + switch (opcode) { + case WebSocketFormat::WebSocketFrameType::CLOSE_FRAME: + clients.remove(httpSession); + break; + case WebSocketFormat::WebSocketFrameType::TEXT_FRAME: + // send back the message to each connected client + for (auto client : clients) { + lockClients.lock(); + auto frame = std::make_shared(); + WebSocketFormat::wsFrameBuild(payload.c_str(), + payload.size(), + *frame, + WebSocketFormat::WebSocketFrameType::TEXT_FRAME, + true, + false); + client->send(frame); + lockClients.unlock(); + } + break; + case WebSocketFormat::WebSocketFrameType::ERROR_FRAME: + case WebSocketFormat::WebSocketFrameType::CONTINUATION_FRAME: + case WebSocketFormat::WebSocketFrameType::BINARY_FRAME: + case WebSocketFormat::WebSocketFrameType::PING_FRAME: + case WebSocketFormat::WebSocketFrameType::PONG_FRAME: + break; + } + }; + + auto wsConnectedCallback = [&clients, &lockClients](const HttpSession::Ptr& httpSession, + const HTTPParser&) { + lockClients.lock(); + clients.push_back(httpSession); + lockClients.unlock(); + }; + + auto closedCallback = [&clients, &lockClients](const HttpSession::Ptr& httpSession) { + clients.remove(httpSession); + }; + + wrapper::HttpListenerBuilder listenBuilder; + listenBuilder.configureService(service) + .configureSocketOptions({ + [](TcpSocket& socket) { + socket.setNodelay(); + }, + }) + .configureConnectionOptions({ + AddSocketOption::WithMaxRecvBufferSize(1024), + }) + .configureListen([port](wrapper::BuildListenConfig builder) { + builder.setAddr(false, "0.0.0.0", port); + }) + .configureEnterCallback([httpEnterCallback, wsEnterCallback, wsConnectedCallback, closedCallback] + (const HttpSession::Ptr& httpSession, HttpSessionHandlers& handlers) { + (void)httpSession; + handlers.setHttpCallback(httpEnterCallback); + handlers.setWSCallback(wsEnterCallback); + handlers.setWSConnected(wsConnectedCallback); + handlers.setClosedCallback(closedCallback); + }) + .asyncRun(); + + while(true) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (brynet::base::app_kbhit()) + { + break; + } + } + + return 0; +}