diff options
Diffstat (limited to 'src/imports')
-rw-r--r-- | src/imports/qmlwebsockets/qmlwebsockets.pro | 6 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp | 4 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qmlwebsockets_plugin.h | 2 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocket.cpp | 31 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocket.h | 3 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocketserver.cpp | 284 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocketserver.h | 122 |
7 files changed, 442 insertions, 10 deletions
diff --git a/src/imports/qmlwebsockets/qmlwebsockets.pro b/src/imports/qmlwebsockets/qmlwebsockets.pro index 2d3353e..f7698d8 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets.pro +++ b/src/imports/qmlwebsockets/qmlwebsockets.pro @@ -3,10 +3,12 @@ QT = core websockets qml TARGETPATH = Qt/WebSockets HEADERS += qmlwebsockets_plugin.h \ - qqmlwebsocket.h + qqmlwebsocket.h \ + qqmlwebsocketserver.h SOURCES += qmlwebsockets_plugin.cpp \ - qqmlwebsocket.cpp + qqmlwebsocket.cpp \ + qqmlwebsocketserver.cpp OTHER_FILES += qmldir diff --git a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp index 9c7f2d6..07176da 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp +++ b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp @@ -43,6 +43,9 @@ #include <QtQml> +#include "qqmlwebsocket.h" +#include "qqmlwebsocketserver.h" + QT_BEGIN_NAMESPACE void QtWebSocketsDeclarativeModule::registerTypes(const char *uri) @@ -51,6 +54,7 @@ void QtWebSocketsDeclarativeModule::registerTypes(const char *uri) // @uri Qt.WebSockets qmlRegisterType<QQmlWebSocket>(uri, 1 /*major*/, 0 /*minor*/, "WebSocket"); + qmlRegisterType<QQmlWebSocketServer>(uri, 1 /*major*/, 0 /*minor*/, "WebSocketServer"); } QT_END_NAMESPACE diff --git a/src/imports/qmlwebsockets/qmlwebsockets_plugin.h b/src/imports/qmlwebsockets/qmlwebsockets_plugin.h index 9e64091..2c135f0 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets_plugin.h +++ b/src/imports/qmlwebsockets/qmlwebsockets_plugin.h @@ -44,8 +44,6 @@ #include <QQmlExtensionPlugin> -#include "qqmlwebsocket.h" - QT_BEGIN_NAMESPACE class QtWebSocketsDeclarativeModule : public QQmlExtensionPlugin diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.cpp b/src/imports/qmlwebsockets/qqmlwebsocket.cpp index d165260..9d10827 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.cpp +++ b/src/imports/qmlwebsockets/qqmlwebsocket.cpp @@ -120,6 +120,18 @@ QQmlWebSocket::QQmlWebSocket(QObject *parent) : { } +QQmlWebSocket::QQmlWebSocket(QWebSocket *socket, QObject *parent) : + QObject(parent), + m_status(Closed), + m_url(socket->requestUrl()), + m_isActive(true), + m_componentCompleted(true), + m_errorString(socket->errorString()) +{ + setSocket(socket); + onStateChanged(socket->state()); +} + QQmlWebSocket::~QQmlWebSocket() { } @@ -173,8 +185,19 @@ void QQmlWebSocket::classBegin() void QQmlWebSocket::componentComplete() { - m_webSocket.reset(new (std::nothrow) QWebSocket()); - if (Q_LIKELY(m_webSocket)) { + setSocket(new QWebSocket); + + m_componentCompleted = true; + + open(); +} + +void QQmlWebSocket::setSocket(QWebSocket *socket) +{ + m_webSocket.reset(socket); + if (m_webSocket) { + // explicit ownership via QScopedPointer + m_webSocket->setParent(Q_NULLPTR); connect(m_webSocket.data(), &QWebSocket::textMessageReceived, this, &QQmlWebSocket::textMessageReceived); typedef void (QWebSocket::* ErrorSignal)(QAbstractSocket::SocketError); @@ -182,10 +205,6 @@ void QQmlWebSocket::componentComplete() this, &QQmlWebSocket::onError); connect(m_webSocket.data(), &QWebSocket::stateChanged, this, &QQmlWebSocket::onStateChanged); - - m_componentCompleted = true; - - open(); } } diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.h b/src/imports/qmlwebsockets/qqmlwebsocket.h index 907506b..33d35e7 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.h +++ b/src/imports/qmlwebsockets/qqmlwebsocket.h @@ -64,6 +64,7 @@ class QQmlWebSocket : public QObject, public QQmlParserStatus public: explicit QQmlWebSocket(QObject *parent = 0); + explicit QQmlWebSocket(QWebSocket *socket, QObject *parent = 0); virtual ~QQmlWebSocket(); enum Status @@ -109,6 +110,8 @@ private: bool m_componentCompleted; QString m_errorString; + // takes ownership of the socket + void setSocket(QWebSocket *socket); void setStatus(Status status); void open(); void close(); diff --git a/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp b/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp new file mode 100644 index 0000000..af0be86 --- /dev/null +++ b/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebSocket module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlwebsocketserver.h" +#include "qqmlwebsocket.h" + +QT_USE_NAMESPACE + +/*! + \qmltype WebSocketServer + \instantiates QQmlWebSocketServer + + \inqmlmodule Qt.WebSockets + \ingroup websockets-qml + \brief QML interface to QWebSocketServer. +*/ + +/*! + \qmlproperty QUrl WebSocketServer::url + Server url that client WebSockets can connect to. The url uses the \e ws:// scheme and includes the + port the server listens to and the host address of the server. + */ + +/*! + \qmlproperty QString WebSocketServer::host + The host address of the server. By default, localhost is used. + */ + +/*! + \qmlproperty int WebSocketServer::port + The port this server is listening on. By default, a port is chosen automatically. + */ + +/*! + \qmlproperty QString WebSocketServer::name + The name of this server used during the http handshake phase. + */ + +/*! + \qmlproperty QString WebSocketServer::errorString + The stringified error message in case an error occurred. + */ + +/*! + \qmlproperty bool WebSocketServer::listen + Set to true when the server should listen to client connections or false otherwise. + When set to true, the server will listen on the specified url defined by host and port + and, when accept is true, accepts incoming client connections. Otherwise the server is closed. + By default, the server is not listening. + */ + +/*! + \qmlproperty bool WebSocketServer::accept + Set to true to accept incoming client connections when the server is listening. When set to false, + incoming connections are rejected. By default, connections are accepted. + */ + +/*! + \qmlsignal WebSocketServer::clientConnected(WebSocket webSocket) + This signal is emitted when a client connects to this server. + */ + +QQmlWebSocketServer::QQmlWebSocketServer(QObject *parent) + : QObject(parent) + , m_host(QHostAddress(QHostAddress::LocalHost).toString()) + , m_port(0) + , m_listen(false) + , m_accept(true) + , m_componentCompleted(true) +{ +} + +QQmlWebSocketServer::~QQmlWebSocketServer() +{ + +} + +void QQmlWebSocketServer::classBegin() +{ + m_componentCompleted = false; +} + +void QQmlWebSocketServer::componentComplete() +{ + init(); + m_componentCompleted = true; +} + +QUrl QQmlWebSocketServer::url() const +{ + QUrl url; + url.setPort(m_port); + url.setHost(m_host); + url.setScheme("ws"); + return url; +} + +QString QQmlWebSocketServer::host() const +{ + return m_host; +} + +void QQmlWebSocketServer::setHost(const QString &host) +{ + if (host == m_host) { + return; + } + + m_host = host; + emit hostChanged(host); + emit urlChanged(url()); + + updateListening(); +} + +quint16 QQmlWebSocketServer::port() const +{ + return m_port; +} + +void QQmlWebSocketServer::setPort(quint16 port) +{ + if (port == m_port) { + return; + } + + m_port = port; + emit portChanged(port); + emit urlChanged(url()); + + if (m_componentCompleted && m_server->isListening()) { + updateListening(); + } +} + +QString QQmlWebSocketServer::errorString() const +{ + return m_server ? m_server->errorString() : tr("QQmlWebSocketServer is not ready."); +} + +QString QQmlWebSocketServer::name() const +{ + return m_name; +} + +void QQmlWebSocketServer::setName(const QString &name) +{ + if (name == m_name) { + return; + } + + m_name = name; + emit nameChanged(name); + + if (m_componentCompleted) { + init(); + } +} + +bool QQmlWebSocketServer::listen() const +{ + return m_listen; +} + +void QQmlWebSocketServer::setListen(bool listen) +{ + if (listen == m_listen) { + return; + } + + m_listen = listen; + emit listenChanged(listen); + + updateListening(); +} + +bool QQmlWebSocketServer::accept() const +{ + return m_accept; +} + +void QQmlWebSocketServer::setAccept(bool accept) +{ + if (accept == m_accept) { + return; + } + + m_accept = accept; + emit acceptChanged(accept); + + if (m_componentCompleted) { + if (!accept) { + m_server->pauseAccepting(); + } else { + m_server->resumeAccepting(); + } + } +} + +void QQmlWebSocketServer::init() +{ + // TODO: add support for wss, requires ssl configuration to be set from QML - realistic? + m_server.reset(new QWebSocketServer(m_name, QWebSocketServer::NonSecureMode)); + + connect(m_server.data(), &QWebSocketServer::newConnection, + this, &QQmlWebSocketServer::newConnection); + connect(m_server.data(), &QWebSocketServer::serverError, + this, &QQmlWebSocketServer::serverError); + connect(m_server.data(), &QWebSocketServer::closed, + this, &QQmlWebSocketServer::closed); + + updateListening(); +} + +void QQmlWebSocketServer::updateListening() +{ + if (!m_server) { + return; + } + + if (m_server->isListening()) { + m_server->close(); + } + + if (!m_listen || !m_server->listen(QHostAddress(m_host), m_port)) { + return; + } + setPort(m_server->serverPort()); + setHost(m_server->serverAddress().toString()); +} + +void QQmlWebSocketServer::newConnection() +{ + emit clientConnected(new QQmlWebSocket(m_server->nextPendingConnection(), this)); +} + +void QQmlWebSocketServer::serverError() +{ + emit errorStringChanged(errorString()); +} + +void QQmlWebSocketServer::closed() +{ + setListen(false); +} + diff --git a/src/imports/qmlwebsockets/qqmlwebsocketserver.h b/src/imports/qmlwebsockets/qqmlwebsocketserver.h new file mode 100644 index 0000000..702725e --- /dev/null +++ b/src/imports/qmlwebsockets/qqmlwebsocketserver.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebSocket module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLWEBSOCKETSERVER_H +#define QQMLWEBSOCKETSERVER_H + +#include <QUrl> +#include <QQmlParserStatus> +#include <QtWebSockets/QWebSocketServer> + +QT_BEGIN_NAMESPACE + +class QQmlWebSocket; +class QQmlWebSocketServer : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_DISABLE_COPY(QQmlWebSocketServer) + Q_INTERFACES(QQmlParserStatus) + + Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) + Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged) + Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) + Q_PROPERTY(bool listen READ listen WRITE setListen NOTIFY listenChanged) + Q_PROPERTY(bool accept READ accept WRITE setAccept NOTIFY acceptChanged) + +public: + explicit QQmlWebSocketServer(QObject *parent = Q_NULLPTR); + virtual ~QQmlWebSocketServer(); + + void classBegin() Q_DECL_OVERRIDE; + void componentComplete() Q_DECL_OVERRIDE; + + QUrl url() const; + + QString host() const; + void setHost(const QString &host); + + quint16 port() const; + void setPort(quint16 port); + + QString name() const; + void setName(const QString &name); + + QString errorString() const; + + bool listen() const; + void setListen(bool listen); + + bool accept() const; + void setAccept(bool accept); + +Q_SIGNALS: + void clientConnected(QQmlWebSocket *webSocket); + + void errorStringChanged(const QString &errorString); + void urlChanged(const QUrl &url); + void portChanged(quint16 port); + void nameChanged(const QString &name); + void hostChanged(const QString &host); + void listenChanged(bool listen); + void acceptChanged(bool accept); + +private: + void init(); + void updateListening(); + void newConnection(); + void serverError(); + void closed(); + + QScopedPointer<QWebSocketServer> m_server; + QString m_host; + QString m_name; + quint16 m_port; + bool m_listen; + bool m_accept; + bool m_componentCompleted; + +}; + +QT_END_NAMESPACE + +#endif // QQMLWEBSOCKETSERVER_H |