/** * Websocket interface for building control unit * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2017-01-30 */ #include "web_socket_handler.h" #include "web_socket_telegrams.h" #include #include namespace BuildingControlUnit { namespace Json { WebSocketHandler::WebSocketHandler(QObject *parent) : QObject(parent) , m_webSocketServer(new QWebSocketServer(QStringLiteral("BCU"), QWebSocketServer::NonSecureMode, this)) , m_logger(getLogger("Json.WebSocketHandler")) {} WebSocketHandler::~WebSocketHandler() { for (QWebSocket *s : qAsConst(m_webSockets)) { s->disconnect(this); s->close(); } qDeleteAll(m_webSockets); } 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; } // inform calling process via stdout about the port/url std::cout << "web socket listen port: " << m_webSocketServer->serverPort() << std::endl; std::cout << "web socket url: " << m_webSocketServer->serverUrl().toString() << std::endl; connect(m_webSocketServer, &QWebSocketServer::newConnection, this, &WebSocketHandler::onNewConnection); return true; } bool WebSocketHandler::sendTelegram(const Telegrams::BaseTelegram *tele, QWebSocket *wsDirect) { if (!isConnected() || !tele) return false; const QString jsonStr = QString::fromUtf8(tele->toJson()); DEBUG_LOG(m_logger) << "jsonStr" << jsonStr; bool bOk = false; for (QWebSocket *ws : qAsConst(m_webSockets)) { if (wsDirect != nullptr && wsDirect != ws) continue; if (ws->sendTextMessage(jsonStr)) bOk = true; } return bOk; } void WebSocketHandler::onNewConnection() { QWebSocket *ws = m_webSocketServer->nextPendingConnection(); if (!ws) return; DEBUG_LOG(m_logger) << "New websocket connection from " << ws->peerAddress().toString() << ":" << ws->peerPort(); connect(ws, &QWebSocket::textMessageReceived, this, &WebSocketHandler::onTextMessageReceived); connect(ws, &QWebSocket::disconnected, this, &WebSocketHandler::onWebSocketDisconnected); m_webSockets += ws; emit webSocketConnected(ws); } void WebSocketHandler::onTextMessageReceived(const QString &msg) { DEBUG_LOG(m_logger) << "new text message: " << msg; auto tele = std::shared_ptr(Telegrams::BaseTelegram::telegramFromJson(msg.toUtf8())); if (!tele) { WARNING_LOG(m_logger) << "Error parsing incoming json data: '" << msg << "'"; return; } emit telegramReceived(tele); } void WebSocketHandler::onWebSocketDisconnected() { QWebSocket *ws = qobject_cast(sender()); if (!ws) return; m_webSockets.remove(ws); ws->deleteLater(); } } // namespace Json } // namespace BuildingControlUnit