/** * Websocket interface to participant positions * $Id$ * $HeadURL$ * $Author$ * Created by Justus Hertel, SLSE, 2020-07-08 */ #include "web_socket_handler.h" #include #include #include #include namespace ParticipantManagement { WebSocketHandler::WebSocketHandler(QObject *parent) : QObject(parent) , m_webSocketServer(new QWebSocketServer(QStringLiteral("ParticipantPositionsSocket"), QWebSocketServer::NonSecureMode, this)) , m_logger(getLogger(QStringLiteral("WebSocketHandler"))) {} WebSocketHandler::~WebSocketHandler() { for (const auto& ws : qAsConst(m_webSockets)) { ws->disconnect(this); } m_webSockets.clear(); } bool WebSocketHandler::init(quint16 listenPort) { if (!m_webSocketServer->listen(QHostAddress::Any, listenPort)) { WARNING_LOG(m_logger) << "Can not listen on port " << listenPort << " - aborting"; return false; } connect(m_webSocketServer, &QWebSocketServer::newConnection, this, &WebSocketHandler::onNewConnection); INFO_LOG(m_logger) << "Listening on port " << m_webSocketServer->serverPort(); return true; } bool WebSocketHandler::init(const QPair &portRange) { for (quint16 currentPort = portRange.first; currentPort <= portRange.second; ++currentPort) { if (init(currentPort)) return true; } return init(); } bool WebSocketHandler::sendTelegramInternal(const ParticipantPosition &pos, int eqNo) const { QJsonObject obj; obj[QStringLiteral("participantId")] = pos.participantId(); obj[QStringLiteral("equipmentNumber")] = eqNo; obj[QStringLiteral("lat")] = pos.pos().lat(); obj[QStringLiteral("lon")] = pos.pos().lon(); obj[QStringLiteral("height")] = pos.pos().z(); const QString jsonStr = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)); bool ret = false; for (const auto &wsw : qAsConst(m_webSockets)) { if (wsw->sendTextMessage(jsonStr)) ret = true; } return ret; } void WebSocketHandler::onNewConnection() { QWebSocket *ws = m_webSocketServer->nextPendingConnection(); if (!ws) return; connect(ws, &QWebSocket::disconnected, this, &WebSocketHandler::onWebSocketDisconnected); m_webSockets += ws; INFO_LOG(m_logger) << "New websocket connected"; } void WebSocketHandler::onWebSocketDisconnected() { QWebSocket *ws = qobject_cast(sender()); if (!ws) return; m_webSockets.removeAll(ws); ws->deleteLater(); INFO_LOG(m_logger) << "A websocket disconnected"; } bool WebSocketHandler::sendPosition(const ParticipantPosition &participantPosition, int equipmentNumber) const { if (!isConnected() || m_webSockets.isEmpty()) return false; return sendTelegramInternal(participantPosition, equipmentNumber); } }