2024-10-25 15:20:26 +02:00
|
|
|
#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 <cstring>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <memory>
|
|
|
|
#include <map>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/epoll.h>
|
|
|
|
|
|
|
|
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<WsClient*>(ptr);
|
|
|
|
if (dz) dz->receive();
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
int & _epollFd;
|
|
|
|
std::map<WebSocket*, WsClient*> _connections;
|
|
|
|
};
|
|
|
|
int main (int /*argc*/, const char * /*argv*/[]) {
|
|
|
|
auto logger = std::make_shared<PrintfLogger> (Logger::Level::Info);
|
|
|
|
int myEpoll = epoll_create (10);
|
|
|
|
Server server (logger);
|
|
|
|
|
|
|
|
auto handler = std::make_shared<WsHandler> (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) {
|
2024-10-25 19:58:06 +02:00
|
|
|
constexpr auto maxEvents = 10;
|
2024-10-25 15:20:26 +02:00
|
|
|
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;
|
|
|
|
}
|