diff options
author | Topi Reinio <topi.reinio@digia.com> | 2014-08-13 14:14:49 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2014-08-13 14:43:24 +0200 |
commit | 62760f579b52fbd19d85d31fa90274f9b0dc5111 (patch) | |
tree | cb348241c606632ad9dbc575e28910e9302a2cc5 /examples/webchannel | |
parent | 150fba9166d0cd63079d8ed15af5f80a759e9549 (diff) | |
download | qtwebchannel-62760f579b52fbd19d85d31fa90274f9b0dc5111.tar.gz |
Doc: Fix example documentation and paths
To fix issues related to example documentation and to follow Qt
convention, do the following changes:
- Rename examples/qwebchannel to examples/webchannel
- Move example-specific documentation to correct location(s)
- Include generic 'Running the Example' instructions
- Add the module name to example title, fix links
This ensures that example docs are built and the example manifest
file generated correctly.
Change-Id: I284e0b13db95a6738d72258735018b59156cc7da
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'examples/webchannel')
-rw-r--r-- | examples/webchannel/exampleassets.pri | 31 | ||||
-rw-r--r-- | examples/webchannel/nodejs/README | 14 | ||||
-rw-r--r-- | examples/webchannel/nodejs/chatclient.js | 133 | ||||
-rw-r--r-- | examples/webchannel/nodejs/nodejs.pro | 7 | ||||
-rw-r--r-- | examples/webchannel/nodejs/package.json | 10 | ||||
-rw-r--r-- | examples/webchannel/standalone/dialog.ui | 48 | ||||
-rw-r--r-- | examples/webchannel/standalone/doc/images/standalone-screenshot.png | bin | 0 -> 30363 bytes | |||
-rw-r--r-- | examples/webchannel/standalone/doc/src/standalone.qdoc | 68 | ||||
-rw-r--r-- | examples/webchannel/standalone/index.html | 79 | ||||
-rw-r--r-- | examples/webchannel/standalone/main.cpp | 151 | ||||
-rw-r--r-- | examples/webchannel/standalone/standalone.pro | 22 | ||||
-rw-r--r-- | examples/webchannel/standalone/websocketclientwrapper.cpp | 80 | ||||
-rw-r--r-- | examples/webchannel/standalone/websocketclientwrapper.h | 71 | ||||
-rw-r--r-- | examples/webchannel/standalone/websockettransport.cpp | 108 | ||||
-rw-r--r-- | examples/webchannel/standalone/websockettransport.h | 68 | ||||
-rw-r--r-- | examples/webchannel/webchannel.pro | 7 |
16 files changed, 897 insertions, 0 deletions
diff --git a/examples/webchannel/exampleassets.pri b/examples/webchannel/exampleassets.pri new file mode 100644 index 0000000..035ca12 --- /dev/null +++ b/examples/webchannel/exampleassets.pri @@ -0,0 +1,31 @@ +# This adds the qwebchannel js library to an example, creating a self-contained bundle +QTDIR_build { + # Build from within Qt. Copy and install the reference lib. + jslib = $$dirname(_QMAKE_CONF_)/src/webchannel/qwebchannel.js + copyfiles = $$jslib +} else { + # This is what an actual 3rd party project would do. + jslib = qwebchannel.js +} + +# This installs all assets including qwebchannel.js, regardless of the source. +exampleassets.files += $$jslib +INSTALLS += exampleassets + +# This code ensures that all assets are present in the build directory. + +!equals(_PRO_FILE_PWD_, $$OUT_PWD) { + # Shadow build, copy all example assets. + copyfiles = $$exampleassets.files +} + +defineReplace(stripSrcDir) { + return($$basename(1)) +} + +assetcopy.input = copyfiles +assetcopy.output = $$OUT_PWD/${QMAKE_FUNC_FILE_IN_stripSrcDir} +assetcopy.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} +assetcopy.name = COPY ${QMAKE_FILE_IN} +assetcopy.CONFIG = no_link target_predeps +QMAKE_EXTRA_COMPILERS += assetcopy diff --git a/examples/webchannel/nodejs/README b/examples/webchannel/nodejs/README new file mode 100644 index 0000000..07f8fd8 --- /dev/null +++ b/examples/webchannel/nodejs/README @@ -0,0 +1,14 @@ +This is a small NodeJS implementation on how to connect to a QWebChannel. + +This example implements a small chat client using the command line. It connects +to the server provided by the other example 'examples/standalone/standalone'. Of +course the port the server listens on must be known. + +How to run it: + +- Install NodeJS (at least 0.10.x) (http://www.nodejs.org/download/) +- go to examples/nodejs and execute "npm install". This sets up the nodeJS + environment in this folder +- ensure examples/standalone/standalone is running +- execute the example with "node chatclient.js" + diff --git a/examples/webchannel/nodejs/chatclient.js b/examples/webchannel/nodejs/chatclient.js new file mode 100644 index 0000000..03ce214 --- /dev/null +++ b/examples/webchannel/nodejs/chatclient.js @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 basysKom GmbH, author Bernd Lamecker <bernd.lamecker@basyskom.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebChannel 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$ +** +****************************************************************************/ +'use strict'; + +var readline = require('readline'); +var QWebChannel = require('./qwebchannel.js').QWebChannel; +var websocket = require('faye-websocket'); + +var address = 'ws://127.0.0.1:12345'; +var socket = new websocket.Client(address); + +console.log('Chat client connecting to ' + address + ' (Ctrl-D to quit)'); + +var createReadlineInterface = function() { + var bye = function() { + console.log('Bye...'); + process.exit(0); + } + + var rlif = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + rlif.setPrompt('chat: '); + + // Handle Ctrl-D and Ctrl-C + rlif.on('close', bye); + rlif.on('SIGINT', bye); + + return rlif; +} + +var createWebChannel = function(transport, rlif) { + return new QWebChannel(transport, function(channel) { + // We connect to the 'sendText' signal of the remote QObject + // Be aware, that the signal is named for the remote side, + // i.e. the server wants to 'send text'. + // This can be confusing, as we connect to the signal + // to receive incoming messages on our side + channel.objects.dialog.sendText.connect(function(message) { + process.stdout.cursorTo(0); + process.stdout.clearLine(0); + console.log(' << ' + message); + rlif.prompt(); + // Go to end of existing input if any + rlif.write(null, {ctrl: true, name: 'e'}) + }); + + rlif.on('line', function(line) { + var l = line.trim(); + if (l !== '') { + process.stdout.moveCursor(0, -1); + process.stdout.cursorTo(0); + process.stdout.clearLine(0); + // The 'receiveText' slot of the remote QObject + // is called with our message. + // Again the naming is for the server side, + // i.e. the slot is used _by the server_ to receive text. + channel.objects.dialog.receiveText(l); + console.log(' >> ' + l); + } + rlif.prompt(); + }); + rlif.prompt(); + }); +} + +socket.on('open', function(event) { + console.log("info: Client connected"); + var transport = { + // We cant't do 'send: socket.send' here + // because 'send' wouldn't be bound to 'socket' + send: function(data) {socket.send(data)} + }; + + createWebChannel(transport, createReadlineInterface()); + + // QWebChannel has set up its onmessage handler + // on the transport in the constructor. + // Now we connect it to the websocket event. + socket.on('message', function(event) { + transport.onmessage(event); + }); +}); + +socket.on('error', function (error) { + console.log('Connection error: ' + error.message); + process.exit(1); +}); + +socket.on('close', function () { + console.log('Connection closed.'); + process.exit(1); +}); diff --git a/examples/webchannel/nodejs/nodejs.pro b/examples/webchannel/nodejs/nodejs.pro new file mode 100644 index 0000000..4df94d2 --- /dev/null +++ b/examples/webchannel/nodejs/nodejs.pro @@ -0,0 +1,7 @@ +TEMPLATE = aux + +exampleassets.files += \ + chatclient.js \ + package.json +exampleassets.path = $$[QT_INSTALL_EXAMPLES]/qwebchannel/nodejs +include(../exampleassets.pri) diff --git a/examples/webchannel/nodejs/package.json b/examples/webchannel/nodejs/package.json new file mode 100644 index 0000000..2d863cc --- /dev/null +++ b/examples/webchannel/nodejs/package.json @@ -0,0 +1,10 @@ +{ + "name": "Chatclient", + "description": "Chatclient example", + "author": "basysKom <info@basyskom.com>", + "version": "0.0.1", + "dependencies": { + "faye-websocket": "0.7.x" + }, + "engine": "node 0.10.x" +} diff --git a/examples/webchannel/standalone/dialog.ui b/examples/webchannel/standalone/dialog.ui new file mode 100644 index 0000000..056a3f5 --- /dev/null +++ b/examples/webchannel/standalone/dialog.ui @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QLineEdit" name="input"> + <property name="placeholderText"> + <string>Message Contents</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="send"> + <property name="text"> + <string>Send</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QPlainTextEdit" name="output"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="plainText"> + <string notr="true">Initializing WebChannel...</string> + </property> + <property name="backgroundVisible"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/webchannel/standalone/doc/images/standalone-screenshot.png b/examples/webchannel/standalone/doc/images/standalone-screenshot.png Binary files differnew file mode 100644 index 0000000..3c55e19 --- /dev/null +++ b/examples/webchannel/standalone/doc/images/standalone-screenshot.png diff --git a/examples/webchannel/standalone/doc/src/standalone.qdoc b/examples/webchannel/standalone/doc/src/standalone.qdoc new file mode 100644 index 0000000..46c09c3 --- /dev/null +++ b/examples/webchannel/standalone/doc/src/standalone.qdoc @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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$ +** +****************************************************************************/ + +/*! + \example standalone + \title Qt WebChannel Standalone Example + \ingroup qtwebchannel-examples + \image standalone-screenshot.png + \brief Shows how to use the QWebChannel C++ API to communicate with an external client. + + The standalone example is a simple chat between a pure C++/Qt application and a remote HTML + client running in your default browser. + + \include examples-run.qdocinc + + \section1 Overview + + The C++ application sets up a QWebChannel instance and publishes a Dialog object over it. + For the remote client side, \c index.html is opened. Both show a dialog with the list of + received messages and an input box to send messages to the other end. + + The Dialog emits the Dialog::sendText() signal when the user sends a message. The signal + automatically gets propagated to the HTML client. When the user enters a message on the HTML + side, Dialog::receiveText() is called. + + All communication between the HTML client and the C++/Qt server is done over a WebSocket. + The C++ side instantiates a QWebSocketServer and wraps incoming QWebSocket connections + in WebSocketTransport objects, which implement QWebChannelAbstractTransport. These objects are + then connected to the QWebChannel instance. +*/ diff --git a/examples/webchannel/standalone/index.html b/examples/webchannel/standalone/index.html new file mode 100644 index 0000000..778a502 --- /dev/null +++ b/examples/webchannel/standalone/index.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <script type="text/javascript" src="./qwebchannel.js"></script> + <script type="text/javascript"> + //BEGIN SETUP + function output(message) + { + var output = document.getElementById("output"); + output.innerHTML = output.innerHTML + message + "\n"; + } + window.onload = function() { + var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]); + output("Connecting to WebSocket server at " + baseUrl + "."); + var socket = new WebSocket(baseUrl); + + socket.onclose = function() + { + console.error("web channel closed"); + }; + socket.onerror = function(error) + { + console.error("web channel error: " + error); + }; + socket.onopen = function() + { + output("WebSocket connected, setting up QWebChannel."); + new QWebChannel(socket, function(channel) { + // make dialog object accessible globally + window.dialog = channel.objects.dialog; + + document.getElementById("send").onclick = function() { + var input = document.getElementById("input"); + var text = input.value; + if (!text) { + return; + } + + output("Sent message: " + text); + input.value = ""; + dialog.receiveText(text); + } + + dialog.sendText.connect(function(message) { + output("Received message: " + message); + }); + + dialog.receiveText("Client connected, ready to send/receive messages!"); + output("Connected to WebChannel, ready to send/receive messages!"); + }); + } + } + //END SETUP + </script> + <style type="text/css"> + html { + height: 100%; + width: 100%; + } + #input { + width: 400px; + margin: 0 10px 0 0; + } + #send { + width: 90px; + margin: 0; + } + #output { + width: 500px; + height: 300px; + } + </style> + </head> + <body> + <textarea id="output"></textarea><br /> + <input id="input" /><input type="submit" id="send" value="Send" onclick="javascript:click();" /> + </body> +</html> diff --git a/examples/webchannel/standalone/main.cpp b/examples/webchannel/standalone/main.cpp new file mode 100644 index 0000000..2cbc6b8 --- /dev/null +++ b/examples/webchannel/standalone/main.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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 "qwebchannel.h" + +#include <QApplication> +#include <QDialog> +#include <QVariantMap> +#include <QDesktopServices> +#include <QUrl> +#include <QDebug> + +#include <QtWebSockets/QWebSocketServer> + +#include "websocketclientwrapper.h" +#include "websockettransport.h" + +#include "ui_dialog.h" + +/*! + An instance of this class gets published over the WebChannel and is then accessible to HTML clients. +*/ +class Dialog : public QObject +{ + Q_OBJECT + +public: + explicit Dialog(QObject *parent = 0) + : QObject(parent) + { + ui.setupUi(&dialog); + dialog.show(); + + connect(ui.send, SIGNAL(clicked()), SLOT(clicked())); + } + + void displayMessage(const QString &message) + { + ui.output->appendPlainText(message); + } + +signals: + /*! + This signal is emitted from the C++ side and the text displayed on the HTML client side. + */ + void sendText(const QString &text); + +public slots: + /*! + This slot is invoked from the HTML client side and the text displayed on the server side. + */ + void receiveText(const QString &text) + { + displayMessage(tr("Received message: %1").arg(text)); + } + +private slots: + /*! + Note that this slot is private and thus not accessible to HTML clients. + */ + void clicked() + { + const QString text = ui.input->text(); + + if (text.isEmpty()) { + return; + } + + emit sendText(text); + displayMessage(tr("Sent message: %1").arg(text)); + + ui.input->clear(); + } + +private: + QDialog dialog; + Ui::Dialog ui; +}; + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + + // setup the QWebSocketServer + QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode); + if (!server.listen(QHostAddress::LocalHost, 12345)) { + qFatal("Failed to open web socket server."); + return 1; + } + + // wrap WebSocket clients in QWebChannelAbstractTransport objects + WebSocketClientWrapper clientWrapper(&server); + + // setup the channel + QWebChannel channel; + QObject::connect(&clientWrapper, &WebSocketClientWrapper::clientConnected, + &channel, &QWebChannel::connectTo); + + // setup the dialog and publish it to the QWebChannel + Dialog dialog; + channel.registerObject(QStringLiteral("dialog"), &dialog); + + // open a browser window with the client HTML page + QUrl url = QUrl::fromLocalFile(BUILD_DIR "/index.html"); + url.setQuery(QStringLiteral("webChannelBaseUrl=") + server.serverUrl().toString()); + QDesktopServices::openUrl(url); + + dialog.displayMessage(QObject::tr("Initialization complete, opening browser at %1.").arg(url.toDisplayString())); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/webchannel/standalone/standalone.pro b/examples/webchannel/standalone/standalone.pro new file mode 100644 index 0000000..fdeb87a --- /dev/null +++ b/examples/webchannel/standalone/standalone.pro @@ -0,0 +1,22 @@ +QT += gui webchannel widgets websockets + +CONFIG += warn_on + +SOURCES += \ + main.cpp \ + websockettransport.cpp \ + websocketclientwrapper.cpp + +HEADERS += \ + websockettransport.h \ + websocketclientwrapper.h + +FORMS += \ + dialog.ui + +DEFINES += "BUILD_DIR=\"\\\""$$OUT_PWD"\\\"\"" + +exampleassets.files += \ + index.html +exampleassets.path = $$[QT_INSTALL_EXAMPLES]/qwebchannel/standalone +include(../exampleassets.pri) diff --git a/examples/webchannel/standalone/websocketclientwrapper.cpp b/examples/webchannel/standalone/websocketclientwrapper.cpp new file mode 100644 index 0000000..0e776e1 --- /dev/null +++ b/examples/webchannel/standalone/websocketclientwrapper.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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 "websocketclientwrapper.h" + +#include <QtWebSockets/QWebSocketServer> + +#include "websockettransport.h" + +/*! + \brief Wrapps connected QWebSockets clients in WebSocketTransport objects. + + This code is all that is required to connect incoming WebSockets to the WebChannel. Any kind + of remote JavaScript client that supports WebSockets can thus receive messages and access the + published objects. +*/ + +QT_BEGIN_NAMESPACE + +/*! + Construct the client wrapper with the given parent. + + All clients connecting to the QWebSocketServer will be automatically wrapped + in WebSocketTransport objects. +*/ +WebSocketClientWrapper::WebSocketClientWrapper(QWebSocketServer *server, QObject *parent) + : QObject(parent) + , m_server(server) +{ + connect(server, &QWebSocketServer::newConnection, + this, &WebSocketClientWrapper::handleNewConnection); +} + +/*! + Wrap an incoming WebSocket connection in a WebSocketTransport object. +*/ +void WebSocketClientWrapper::handleNewConnection() +{ + emit clientConnected(new WebSocketTransport(m_server->nextPendingConnection())); +} + +QT_END_NAMESPACE diff --git a/examples/webchannel/standalone/websocketclientwrapper.h b/examples/webchannel/standalone/websocketclientwrapper.h new file mode 100644 index 0000000..1f742f7 --- /dev/null +++ b/examples/webchannel/standalone/websocketclientwrapper.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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 WEBSOCKETTRANSPORTSERVER_H +#define WEBSOCKETTRANSPORTSERVER_H + +#include <QObject> + +QT_BEGIN_NAMESPACE + +class QWebSocketServer; +class WebSocketTransport; + +class WebSocketClientWrapper : public QObject +{ + Q_OBJECT + +public: + WebSocketClientWrapper(QWebSocketServer *server, QObject *parent = 0); + +Q_SIGNALS: + void clientConnected(WebSocketTransport* client); + +private Q_SLOTS: + void handleNewConnection(); + +private: + QWebSocketServer *m_server; +}; + +QT_END_NAMESPACE + +#endif // WEBSOCKETTRANSPORTSERVER_H diff --git a/examples/webchannel/standalone/websockettransport.cpp b/examples/webchannel/standalone/websockettransport.cpp new file mode 100644 index 0000000..5714463 --- /dev/null +++ b/examples/webchannel/standalone/websockettransport.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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 "websockettransport.h" + +#include <QJsonDocument> +#include <QJsonObject> +#include <QDebug> + +#include <QtWebSockets/QWebSocket> + +/*! + \brief QWebChannelAbstractSocket implementation that uses a QWebSocket internally. + + The transport delegates all messages received over the QWebSocket over its + textMessageReceived signal. Analogously, all calls to sendTextMessage will + be send over the QWebSocket to the remote client. +*/ + +QT_BEGIN_NAMESPACE + +/*! + Construct the transport object and wrap the given socket. + + The socket is also set as the parent of the transport object. +*/ +WebSocketTransport::WebSocketTransport(QWebSocket *socket) +: QWebChannelAbstractTransport(socket) +, m_socket(socket) +{ + connect(socket, &QWebSocket::textMessageReceived, + this, &WebSocketTransport::textMessageReceived); +} + +/*! + Destroys the WebSocketTransport. +*/ +WebSocketTransport::~WebSocketTransport() +{ + +} + +/*! + Serialize the JSON message and send it as a text message via the WebSocket to the client. +*/ +void WebSocketTransport::sendMessage(const QJsonObject &message) +{ + QJsonDocument doc(message); + m_socket->sendTextMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact))); +} + +/*! + Deserialize the stringified JSON messageData and emit messageReceived. +*/ +void WebSocketTransport::textMessageReceived(const QString &messageData) +{ + QJsonParseError error; + QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error); + if (error.error) { + qWarning() << "Failed to parse text message as JSON object:" << messageData + << "Error is:" << error.errorString(); + return; + } else if (!message.isObject()) { + qWarning() << "Received JSON message that is not an object: " << messageData; + return; + } + emit messageReceived(message.object(), this); +} + +QT_END_NAMESPACE diff --git a/examples/webchannel/standalone/websockettransport.h b/examples/webchannel/standalone/websockettransport.h new file mode 100644 index 0000000..828ac00 --- /dev/null +++ b/examples/webchannel/standalone/websockettransport.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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 QtWebChannel 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 WEBSOCKETTRANSPORT_H +#define WEBSOCKETTRANSPORT_H + +#include <QtWebChannel/QWebChannelAbstractTransport> + +QT_BEGIN_NAMESPACE + +class QWebSocket; +class WebSocketTransport : public QWebChannelAbstractTransport +{ + Q_OBJECT +public: + explicit WebSocketTransport(QWebSocket *socket); + virtual ~WebSocketTransport(); + + void sendMessage(const QJsonObject &message) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void textMessageReceived(const QString &message); + +private: + QWebSocket *m_socket; +}; + +QT_END_NAMESPACE + +#endif // WEBSOCKETTRANSPORT_H diff --git a/examples/webchannel/webchannel.pro b/examples/webchannel/webchannel.pro new file mode 100644 index 0000000..de6b4b8 --- /dev/null +++ b/examples/webchannel/webchannel.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs + +qtHaveModule(widgets):qtHaveModule(websockets) { + SUBDIRS += standalone +} + +SUBDIRS += nodejs |