]> git.sesse.net Git - ultimatescore/blobdiff - client/ws_server.cpp
Change to communicating over WebSockets instead of over ACMP.
[ultimatescore] / client / ws_server.cpp
diff --git a/client/ws_server.cpp b/client/ws_server.cpp
new file mode 100644 (file)
index 0000000..914da38
--- /dev/null
@@ -0,0 +1,74 @@
+#include "ws_server.h"
+
+#include <functional>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "QtWebSockets/qwebsocketserver.h"
+#include "QtWebSockets/qwebsocket.h"
+
+using namespace std;
+
+WSServer::WSServer(const string &host, int port)
+       : ws_server(new QWebSocketServer("ACMP client", QWebSocketServer::NonSecureMode, this))
+{
+       if (ws_server->listen(QHostAddress::Any, port)) {
+               connect(ws_server, &QWebSocketServer::newConnection, this, &WSServer::on_new_connection);
+       }
+}
+
+void WSServer::change_port(int port)
+{
+       unordered_set<QWebSocket *> old_clients = move(clients);
+       for (QWebSocket *sock : old_clients) {
+               delete sock;
+       }
+       ws_server->close();
+       ws_server->listen(QHostAddress::Any, port);
+}
+
+void WSServer::add_init_command(const string &cmd)
+{
+       init_commands.push_back(cmd + "\r\n");
+}
+
+void WSServer::set_connection_callback(const std::function<void(bool)> &callback)
+{
+       connection_callback = callback;
+}
+
+void WSServer::send_command(const string &cmd)
+{
+       for (QWebSocket *sock : clients) {
+               sock->sendTextMessage(QString::fromStdString(cmd));
+       }
+}
+
+void WSServer::on_new_connection()
+{
+       QWebSocket *sock = ws_server->nextPendingConnection();
+       connect(sock, &QWebSocket::disconnected, this, &WSServer::disconnected);
+
+       for (const string &cmd : init_commands) {
+               sock->sendTextMessage(QString::fromStdString(cmd));
+       }
+       clients.insert(sock);
+       connection_callback(true);
+}
+
+void WSServer::disconnected()
+{
+       QWebSocket *sock = qobject_cast<QWebSocket *>(sender());
+       if (sock) {
+               clients.erase(sock);
+               sock->deleteLater();
+               connection_callback(!clients.empty());
+       }
+}