#include "seasocks/PrintfLogger.h" #include "seasocks/Server.h" #include "seasocks/StringUtil.h" #include "seasocks/WebSocket.h" #include "seasocks/PageHandler.h" #include "seasocks/SimpleResponse.h" #include "seasocks/util/Json.h" #include "wsclient.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace seasocks; class WsHandler : public WebSocket::Handler { public: explicit WsHandler (int & epollFd) : _epollFd (epollFd) { } void onConnect (WebSocket * connection) override { WsClient * dz = new WsClient (connection, _epollFd); _connections.insert ( {connection, dz}); if (dz->start()) printf ("WsClient started\r\n"); std::cout << "Connected: " << connection->getRequestUri() << " : " << formatAddress (connection->getRemoteAddress()) << "\r\nCredentials: " << * (connection->credentials()) << "\r\n"; } void onData (WebSocket * connection, const char * data) override { WsClient * dz = _connections.at (connection); dz->send (data); } void onDisconnect (WebSocket * connection) override { WsClient * dz = _connections.at (connection); dz->stop(); delete dz; _connections.erase (connection); std::cout << "Disconnected: " << connection->getRequestUri() << " : " << formatAddress (connection->getRemoteAddress()) << "\r\n"; } void poll (void * ptr) { WsClient * dz = static_cast(ptr); if (dz) dz->receive(); } private: int & _epollFd; std::map _connections; }; int main (int /*argc*/, const char * /*argv*/[]) { auto logger = std::make_shared (Logger::Level::Info); int myEpoll = epoll_create (10); Server server (logger); auto handler = std::make_shared (myEpoll); server.addWebSocketHandler ("/ws", handler); server.setStaticPath ("."); if (!server.startListening (8080)) { std::cerr << "couldn't start listening\n"; return 1; } epoll_event wakeSeasocks = {EPOLLIN | EPOLLOUT | EPOLLERR, {&server}}; epoll_ctl (myEpoll, EPOLL_CTL_ADD, server.fd(), &wakeSeasocks); while (true) { constexpr auto maxEvents = 10; epoll_event events[maxEvents]; auto res = epoll_wait (myEpoll, events, maxEvents, -1); if (res < 0) { std::cerr << "epoll returned an error\n"; return 1; } for (auto i = 0; i < res; ++i) { if (events[i].data.ptr == &server) { auto seasocksResult = server.poll (0); if (seasocksResult == Server::PollResult::Terminated) { return 0; } if (seasocksResult == Server::PollResult::Error) return 1; } else { handler->poll (events[i].data.ptr); } } } return 0; }