diff options
author | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-11-17 15:20:08 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-25 01:10:23 +0100 |
commit | 7c8d645c4759f7290fd31fe439abf0a99aac9161 (patch) | |
tree | 4d2630238d010c5e123b6053569e9853e4a954ac /src | |
parent | 12a415503ed2579f8d9773a983ef34b1b0817caa (diff) | |
download | qtwebsockets-7c8d645c4759f7290fd31fe439abf0a99aac9161.tar.gz |
Add QML websockets plugin
Change-Id: I9454cf339f8af5515d3a91667d8c8ded3659d18b
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/imports/qmlwebsockets/plugins.qmltypes | 46 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qmldir | 4 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qmlwebsockets.pro | 14 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp | 10 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocket.cpp | 162 | ||||
-rw-r--r-- | src/imports/qmlwebsockets/qqmlwebsocket.h | 55 |
6 files changed, 275 insertions, 16 deletions
diff --git a/src/imports/qmlwebsockets/plugins.qmltypes b/src/imports/qmlwebsockets/plugins.qmltypes new file mode 100644 index 0000000..8116fce --- /dev/null +++ b/src/imports/qmlwebsockets/plugins.qmltypes @@ -0,0 +1,46 @@ +import QtQuick.tooling 1.1 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump -notrelocatable Qt.WebSockets 1.0' + +Module { + Component { + name: "QQmlWebSocket" + prototype: "QObject" + exports: ["Qt.WebSockets/WebSocket 1.0"] + exportMetaObjectRevisions: [0] + Enum { + name: "Status" + values: { + "Connecting": 0, + "Open": 1, + "Closing": 2, + "Closed": 3, + "Error": 4 + } + } + Property { name: "url"; type: "QUrl" } + Property { name: "status"; type: "Status"; isReadonly: true } + Property { name: "errorString"; type: "string"; isReadonly: true } + Property { name: "active"; type: "bool" } + Signal { + name: "textMessageReceived" + Parameter { name: "message"; type: "string" } + } + Signal { + name: "statusChanged" + Parameter { name: "status"; type: "Status" } + } + Signal { + name: "activeChanged" + Parameter { name: "isActive"; type: "bool" } + } + Method { + name: "sendTextMessage" + Parameter { name: "message"; type: "string" } + } + } +} diff --git a/src/imports/qmlwebsockets/qmldir b/src/imports/qmlwebsockets/qmldir index 549c286..4ae1035 100644 --- a/src/imports/qmlwebsockets/qmldir +++ b/src/imports/qmlwebsockets/qmldir @@ -1,3 +1,3 @@ -module Qt.Playground.WebSockets - +module Qt.WebSockets plugin declarative_qmlwebsockets +typeinfo plugins.qmltypes diff --git a/src/imports/qmlwebsockets/qmlwebsockets.pro b/src/imports/qmlwebsockets/qmlwebsockets.pro index 18d3713..2d3353e 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets.pro +++ b/src/imports/qmlwebsockets/qmlwebsockets.pro @@ -1,11 +1,15 @@ QT = core websockets qml -TARGETPATH = Qt/Playground/WebSockets +TARGETPATH = Qt/WebSockets -HEADERS += qmlwebsockets_plugin.h \ - qqmlwebsocket.h +HEADERS += qmlwebsockets_plugin.h \ + qqmlwebsocket.h -SOURCES += qmlwebsockets_plugin.cpp \ - qqmlwebsocket.cpp +SOURCES += qmlwebsockets_plugin.cpp \ + qqmlwebsocket.cpp + +OTHER_FILES += qmldir + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 load(qml_plugin) diff --git a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp index ea2d1b3..c8d2cd6 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp +++ b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp @@ -45,12 +45,8 @@ void QmlWebsocket_plugin::registerTypes(const char *uri) { - Q_ASSERT(uri == QLatin1String("Qt.Playground.WebSockets")); + Q_ASSERT(uri == QLatin1String("Qt.WebSockets")); - int major = 1; - int minor = 0; - - // @uri Qt.Playground.WebSockets - - qmlRegisterType<QQmlWebSocket>(uri, major, minor, "WebSocket"); + // @uri Qt.WebSockets + qmlRegisterType<QQmlWebSocket>(uri, 1 /*major*/, 0 /*minor*/, "WebSocket"); } diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.cpp b/src/imports/qmlwebsockets/qqmlwebsocket.cpp index 8858f24..49b1dfd 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.cpp +++ b/src/imports/qmlwebsockets/qqmlwebsocket.cpp @@ -40,18 +40,176 @@ ****************************************************************************/ #include "qqmlwebsocket.h" +#include <QtWebSockets/QWebSocket> QQmlWebSocket::QQmlWebSocket(QObject *parent) : - QObject(parent) + QObject(parent), + m_webSocket(), + m_status(Closed), + m_url(), + m_isActive(false), + m_componentCompleted(true), + m_errorString() { } -void QQmlWebSocket::classBegin() +QQmlWebSocket::~QQmlWebSocket() +{ +} + +void QQmlWebSocket::sendTextMessage(const QString &message) +{ + if (m_status != Open) { + setErrorString(tr("Messages can only be send when the socket has Open status.")); + setStatus(Error); + return; + } + m_webSocket->write(message); +} + +QUrl QQmlWebSocket::url() const +{ + return m_url; +} + +void QQmlWebSocket::setUrl(const QUrl &url) +{ + if (m_url == url) { + return; + } + if (m_webSocket && (m_status == Open)) { + m_webSocket->close(); + } + m_url = url; + Q_EMIT urlChanged(); + if (m_webSocket) { + m_webSocket->open(m_url); + } +} + +QQmlWebSocket::Status QQmlWebSocket::status() const { + return m_status; +} +QString QQmlWebSocket::errorString() const +{ + return m_errorString; +} + +void QQmlWebSocket::classBegin() +{ + m_componentCompleted = false; + m_errorString = tr("QQmlWebSocket is not ready."); + m_status = Closed; } void QQmlWebSocket::componentComplete() { + m_webSocket.reset(new QWebSocket()); + connect(m_webSocket.data(), SIGNAL(textMessageReceived(QString)), this, SIGNAL(textMessageReceived(QString))); + connect(m_webSocket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); + connect(m_webSocket.data(), SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState))); + + m_componentCompleted = true; + + open(); +} + +void QQmlWebSocket::onError(QAbstractSocket::SocketError error) +{ + Q_UNUSED(error) + setErrorString(m_webSocket->errorString()); + setStatus(Error); +} + +void QQmlWebSocket::onStateChanged(QAbstractSocket::SocketState state) +{ + switch (state) + { + case QAbstractSocket::ConnectingState: + case QAbstractSocket::BoundState: + case QAbstractSocket::HostLookupState: + { + setStatus(Connecting); + break; + } + case QAbstractSocket::UnconnectedState: + { + setStatus(Closed); + break; + } + case QAbstractSocket::ConnectedState: + { + setStatus(Open); + break; + } + case QAbstractSocket::ClosingState: + { + setStatus(Closing); + break; + } + default: + { + setStatus(Connecting); + break; + } + } +} + +void QQmlWebSocket::setStatus(QQmlWebSocket::Status status) +{ + if (m_status == status) { + return; + } + m_status = status; + if (status != Error) { + setErrorString(); + } + Q_EMIT statusChanged(m_status); +} + +void QQmlWebSocket::setActive(bool active) +{ + if (m_isActive == active) { + return; + } + m_isActive = active; + Q_EMIT activeChanged(m_isActive); + if (!m_componentCompleted) { + return; + } + if (m_isActive) { + open(); + } else { + close(); + } +} + +bool QQmlWebSocket::isActive() const +{ + return m_isActive; +} +void QQmlWebSocket::open() +{ + if (m_componentCompleted && m_isActive && m_url.isValid() && m_webSocket) { + m_webSocket->open(m_url); + } +} + +void QQmlWebSocket::close() +{ + if (m_componentCompleted && m_webSocket) { + m_webSocket->close(); + } +} + +void QQmlWebSocket::setErrorString(QString errorString) +{ + if (m_errorString == errorString) { + return; + } + m_errorString = errorString; + Q_EMIT errorStringChanged(m_errorString); } diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.h b/src/imports/qmlwebsockets/qqmlwebsocket.h index 20718c3..47cf6fa 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.h +++ b/src/imports/qmlwebsockets/qqmlwebsocket.h @@ -44,6 +44,9 @@ #include <QObject> #include <QQmlParserStatus> +#include <QtQml> +#include <QScopedPointer> +#include <QWebSocket> class QQmlWebSocket : public QObject, public QQmlParserStatus { @@ -51,12 +54,64 @@ class QQmlWebSocket : public QObject, public QQmlParserStatus Q_DISABLE_COPY(QQmlWebSocket) Q_INTERFACES(QQmlParserStatus) + Q_ENUMS(Status) + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) + public: explicit QQmlWebSocket(QObject *parent = Q_NULLPTR); + virtual ~QQmlWebSocket(); + + enum Status + { + Connecting = 0, + Open = 1, + Closing = 2, + Closed = 3, + Error = 4 + }; + + QUrl url() const; + void setUrl(const QUrl &url); + Status status() const; + QString errorString() const; + + void setActive(bool active); + bool isActive() const; + +public Q_SLOTS: + void sendTextMessage(const QString &message); + + +Q_SIGNALS: + void textMessageReceived(QString message); + void statusChanged(Status status); + void activeChanged(bool isActive); + void errorStringChanged(QString errorString); + void urlChanged(); public: void classBegin() Q_DECL_OVERRIDE; void componentComplete() Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onError(QAbstractSocket::SocketError error); + void onStateChanged(QAbstractSocket::SocketState state); + +private: + QScopedPointer<QWebSocket> m_webSocket; + Status m_status; + QUrl m_url; + bool m_isActive; + bool m_componentCompleted; + QString m_errorString; + + void setStatus(Status status); + void open(); + void close(); + void setErrorString(QString errorString = QString()); }; #endif // QQMLWEBSOCKET_H |