SlideShare a Scribd company logo
1 of 67
Download to read offline
Give a Push to 
Your Qt 
Application with Qt 
Cloud Services 
and WebSockets
About me
Lauri Nevala 
nevalau nevalla nevalla 
• Working in Qt Cloud Services team at The Qt 
Company 
• Over ten years of experience in creating web and 
mobile based applications
Our Goal 
Understand how to use Qt Cloud Services 
in order to send and receive WebSocket 
messages
What is Qt Cloud Services 
Enginio 
Data 
Storage 
Storage 
for 
Applica/on 
Data 
Use 
with 
QtEnginio 
Library 
Managed 
Applica3on 
Run3me 
Applica/on 
Pla<orm 
as 
a 
Service 
Support 
for 
Qt/C++, 
NodeJS, 
Apache, 
PHP, 
MongoDB, 
MySQL, 
Redis… 
Managed 
WebSocket 
Real-­‐Time 
Socket 
Connec/ons 
with 
virtually 
unlimited 
scalability 
Use 
with 
SDK’s 
and 
Qt 
WebSocket 
Client 
Library
Enginio Data Storage (EDS) 
Flexible and powerful 
cloud data storage 
with built-in user and 
data access control
Managed Application Runtime (MAR) 
Scalable," 
Multi-language," 
Multi-database," 
Application Platform as a Service
Managed Application Runtimes 
How does it work?
Supported Frameworks 
Supported frameworks by 3rd party build packs 
Scala, Clojure, Play, Gradle, Grails, PHP, Go, Meteorite, Perl, Dart, Nginx, Apache, Jekyll
Built-in Services 
or choose from our cloud based services 
Enginio Data Storage" 
Managed WebSocket 
or choose anything with SDK 
... Amazon, Azure, Google ...
Developer Friendly 
Deployment 
Deploy using Git – the most common VCS 
among developers 
> 
git 
push 
qtc 
master
Managed WebSocket (MWS) 
Fully managed 
service implementing 
a bi-directional, real-time 
communication 
gateway for 
WebSockets.
Managed WebSocket 
How does it work?
3. send WebSocket message 
1. get WebSocket URI 
4. deliver WebSocket message 2. open WebSocket 
connection 
{ 
data: 
'{ 
"object":{ 
"id":"541df1c1e5bde554a805b213", 
"createdAt":"2014-­‐09 
20T21:29:37.849Z", 
"device":"FZXC0wg0LvaJ", 
"done":false, 
"objectType":"objects.todos", 
"text":"testi2", 
"updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", 
"userId":"user:54196f3f5a3d8b61860381a4" 
}, 
"meta":{ 
"backendId":"5417e5485a3d8b418a01adb7", 
"eventName":"create", 
"requestId":"a671f67b4f41c20b53988a6057b32539", 
"userId":null} 
}', 
receivers: 
{ 
sockets: 
['*'], 
tags: 
[] 
} 
}
WebSockets 
Consider using WebSockets for instantaneous data 
without the browser refresh
Where to use? 
• Chats 
• Social feeds 
• Multiplayer games 
• Collaborative editing 
• Sport updates 
• Location based apps 
• Your killer app
Why WebSockets are so great? 
• WebSockets defines an API establishing “socket” 
connections between web clients and a server 
• TCP-based protocol 
• Full-duplex, simultaneous bi-directional messaging 
• Uri scheme ws: and wss:
WebSockets and Qt Cloud 
Services 
1. + 
➡ public socket 
2. + + 
➡ private socket 
3. 
➡ do anything you want
Public sockets 
https://flic.kr/p/dUtbk5
+
WebSocket server 
Create EDS instance 
Create MWS instance 
Create EDS Webhook
WebSocket server 
Create EDS instance 
Create MWS instance 
Create EDS Webhook
WebSocket server 
Create EDS instance 
Create MWS instance 
Create EDS Webhook
Create EDS Webhook 
http://bit.ly/eds-mws-webhook
EDS MWS 
{ 
data: 
'{ 
"object":{ 
"id":"541df1c1e5bde554a805b213", 
"createdAt":"2014-­‐09 
20T21:29:37.849Z", 
"device":"FZXC0wg0LvaJ", 
"done":false, 
"objectType":"objects.todos", 
"text":"testi2", 
"updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", 
"userId":"user:54196f3f5a3d8b61860381a4" 
}, 
"meta":{ 
"backendId":"5417e5485a3d8b418a01adb7", 
"eventName":"create", 
"requestId":"a671f67b4f41c20b53988a6057b32539", 
"userId":null} 
}', 
receivers: 
{ 
sockets: 
['*'], 
tags: 
[] 
} 
} 
HTTP POST 
https://mws-eu-1.qtc.io/v1/gateways/MWS_GATEWAY_ID/webhook_receivers/enginio 
App 
{ 
"object":{ 
"id":"541df1c1e5bde554a805b213", 
"createdAt":"2014-­‐09 
20T21:29:37.849Z", 
"device":"FZXC0wg0LvaJ", 
"done":false, 
"objectType":"objects.todos", 
"text":"testi2", 
"updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", 
"userId":"user:54196f3f5a3d8b61860381a4" 
}, 
"meta":{ 
"backendId":"5417e5485a3d8b418a01adb7", 
"eventName":"create", 
"requestId":"a671f67b4f41c20b53988a6057b32539", 
"userId":null} 
} 
} 
send WebSocket message to all sockets
WebSocket server 
Create a EDS instance 
Create a MWS instance 
Create EDS Webhook
Enginio Todo 
http://bit.ly/qtc-todo
2. create Todo 
3. trigger Webhook 
4. send WebSocket message 
5. refresh UI 
1. connect to WebSocket
websocketclient.cpp 
#include 
"websocketclient.h" 
#include 
<QtCore/QDebug> 
" 
QT_USE_NAMESPACE 
" 
WebSocketClient::WebSocketClient(const 
QUrl 
&url, 
QObject 
*parent) 
: 
QObject(parent), 
m_url(url) 
{ 
connect(&m_webSocket, 
&QWebSocket::connected, 
this, 
&WebSocketClient::onConnected); 
connect(&m_webSocket, 
&QWebSocket::disconnected, 
this, 
&WebSocketClient::closed); 
m_webSocket.open(QUrl(url)); 
} 
" 
void 
WebSocketClient::onConnected() 
{ 
qDebug() 
<< 
"WebSocket 
connected"; 
connect(&m_webSocket, 
&QWebSocket::textMessageReceived, 
this, 
&WebSocketClient::onTextMessageReceived); 
} 
" 
void 
WebSocketClient::onTextMessageReceived(QString 
message) 
{ 
emit 
onMessageReceived(message); 
}
mainwindow.cpp 
#define 
REQUEST_URL 
“https://mws-­‐eu-­‐1.qtc.io/v1/gateways/MWS_GATEWAY_ID/websocket_uri” 
" 
MainWindow::MainWindow(QWidget 
*parent) 
: 
QMainWindow(parent) 
{ 
… 
m_networkManager 
= 
new 
QNetworkAccessManager(this); 
QObject::connect(m_networkManager, 
&QNetworkAccessManager::finished, 
this, 
&MainWindow::requestFinished); 
getWebSocketUrl(); 
… 
} 
QNetworkReply* 
MainWindow::getWebSocketUrl() 
{ 
QNetworkRequest 
request; 
request.setUrl(QUrl(QString("%1").arg(REQUEST_URL))); 
request.setHeader(QNetworkRequest::ContentTypeHeader, 
"application/json"); 
" 
QNetworkReply 
*reply 
= 
m_networkManager-­‐>get(request); 
return 
reply; 
} 
void 
MainWindow::requestFinished(QNetworkReply 
*reply) 
{ 
QJsonDocument 
replyData 
= 
QJsonDocument::fromJson(reply-­‐>readAll()); 
QJsonObject 
data 
= 
replyData.object(); 
" 
m_mwsClient 
= 
new 
WebSocketClient(QUrl(data.value("uri").toString()), 
this); 
" 
QObject::connect(m_mwsClient, 
&WebSocketClient::onMessageReceived, 
this, 
&MainWindow::messageReceived); 
}
void 
MainWindow::messageReceived(QString 
message) 
{ 
qDebug() 
<< 
"Message 
received:" 
<< 
message; 
QJsonDocument 
messageJson 
= 
QJsonDocument::fromJson(message.toUtf8()); 
QJsonObject 
enginioObject 
= 
messageJson.object().value("object").toObject(); 
QJsonObject 
metaObject 
= 
messageJson.object().value("meta").toObject(); 
QString 
event 
= 
metaObject.value("eventName").toString(); 
if(event 
== 
"delete" 
|| 
enginioObject.value("device_id").toString() 
!= 
m_device) 
{ 
qDebug() 
<< 
"Refresh 
todos"; 
QJsonObject 
query; 
// 
reload 
todos 
from 
Enginio 
m_model-­‐>setQuery(query); 
" 
query["objectType"] 
= 
QString::fromUtf8("objects.todos"); 
m_model-­‐>setQuery(query); 
" 
} 
}
Demo
Private sockets 
https://flic.kr/p/89crWV
+ +
Server-side app 
// 
Qt 
Cloud 
Services 
package 
var 
qtc 
= 
require('qtc'); 
var 
qtcConfig 
= 
require('../config/qtc-­‐conf'); 
var 
mws 
= 
new 
qtc.Mws(qtcConfig.mws); 
module.exports 
= 
function(app) 
{ 
app.post('/api/websocket/messages', 
function(req, 
res) 
{ 
var 
payload 
= 
req.body.payload; 
console.log('got 
websocket 
request:') 
console.log(payload) 
" 
mws.send(JSON.stringify(payload), 
{ 
sockets: 
null, 
tags: 
[payload.object.userId] 
}, 
function(e, 
mwsResponse) 
{ 
console.log('send 
websocket 
message:'); 
console.log(mwsResponse); 
res.json(mwsResponse); 
}) 
}); 
… 
} 
app.get('/api/websocket', 
function(req, 
res) 
{ 
authenticateRequest(req, 
function(e, 
session){ 
if(!e){ 
mws.createSocket(["user:"+session.userId], 
function(e, 
mwsResponse) 
{ 
res.json(mwsResponse); 
}); 
} 
else 
{ 
res.json(error(403, 
"Access 
Denied!")); 
} 
}); 
});
QML Client 
http://bit.ly/qtc-mar-todo
2. create Todo 
4. trigger Webhook 
5. send WebSocket message 
6. refresh UI 
3. insert Todo 
1. connect to WebSocket
main.qml 
import 
QtQuick 
2.2 
import 
QtQuick.Controls 
1.1 
import 
Qt.WebSockets 
1.0 
import 
"Storage.js" 
as 
Storage 
" 
Item 
{ 
id: 
app 
width: 
480 
height: 
800 
… 
" 
WebSocket 
{ 
id: 
socket 
active: 
true 
onTextMessageReceived: 
{ 
console.log(message) 
Storage.handleWebsocketMessage(message) 
} 
onStatusChanged: 
{ 
if 
(socket.status 
== 
WebSocket.Error) 
{ 
console.log("Error: 
" 
+ 
socket.errorString) 
} 
else 
if 
(socket.status 
== 
WebSocket.Open) 
{ 
console.log("Open") 
} 
else 
if 
(socket.status 
== 
WebSocket.Closed) 
{ 
console.log("Socket 
closed") 
} 
} 
} 
… 
}
storage.js 
var 
REQUEST_URL 
= 
"http://qtc-­‐tutorial-­‐todo.qtcloudapp.com" 
function 
connectToWebSocket() 
{ 
var 
doc 
= 
new 
XMLHttpRequest(); 
doc.open("GET", 
REQUEST_URL 
+ 
"/api/websocket", 
true); 
doc.setRequestHeader('x-­‐todo-­‐session', 
sessionId); 
doc.setRequestHeader('Content-­‐Type', 
'application/json'); 
doc.onreadystatechange 
= 
function() 
{ 
// 
When 
ready 
if 
(doc.readyState 
=== 
4) 
{ 
// 
If 
OK 
if 
(doc.status 
=== 
200) 
{ 
var 
data 
= 
JSON.parse(doc.responseText); 
console.log(doc.responseText) 
socket.url 
= 
data.uri 
} 
} 
} 
doc.send() 
}
function 
handleWebsocketMessage(message) 
{ 
message 
= 
JSON.parse(message) 
var 
event 
= 
message.meta.eventName 
var 
object 
= 
message.object 
if(object.device 
!== 
device) 
{ 
// 
ignore 
events 
created 
by 
this 
app 
var 
i 
if(event 
=== 
"create") 
{ 
addItem(object.text, 
object.id) 
} 
else 
if(event 
=== 
"update") 
{ 
for 
(i=itemModel.count; 
i-­‐-­‐;) 
{ 
if( 
object.id 
=== 
itemModel.get(i).itemId) 
{ 
finishItem(i, 
false) 
break; 
} 
} 
} 
} 
if(event 
=== 
"delete") 
{ 
for 
(i=itemModel.count; 
i-­‐-­‐;) 
{ 
if( 
object.id 
=== 
itemModel.get(i).itemId) 
{ 
deleteItem(i, 
false) 
break; 
} 
} 
} 
}
Demo 
• Try it yourself! 
• http://bit.ly/qtc-todo-demo 
• username: qtincloud 
password: qtincloud
https://flic.kr/p/cT2gqu 
Custom WebSocket Server
em-websocket 
… etc …
I want to use !!!1
Using WebSockets with 
MAR 
• Server must listen to a port that MAR gives to the 
app 
• To keep idle socket connections alive, the 
WebSocket server must send a ping control frame 
to every client at least once in < 60s
Qt WebSocket EchoServer 
http://bit.ly/qt-echoserver 
• Example can be found from Qt 5.3 examples 
• Bug in Qt 5.3 that prevents deploying it to MAR 
• Fixed in Qt 5.4 
• Qt 5.4 beta in MAR allows us to test it out
main.cpp 
#include 
<QtCore/QCoreApplication> 
#include 
"echoserver.h" 
" 
int 
main(int 
argc, 
char 
*argv[]) 
{ 
QCoreApplication 
a(argc, 
argv); 
int 
port 
= 
1234; 
if(qEnvironmentVariableIsSet("PORT") 
&& 
!qEnvironmentVariableIsEmpty("PORT")) 
{ 
port 
= 
qgetenv("PORT").toInt(); 
} 
EchoServer 
*server 
= 
new 
EchoServer(port); 
QObject::connect(server, 
&EchoServer::closed, 
&a, 
&QCoreApplication::quit); 
" 
return 
a.exec(); 
}
echoserver.cpp 
EchoServer::EchoServer(quint16 
port, 
QObject 
*parent) 
: 
QObject(parent), 
m_pWebSocketServer(new 
QWebSocketServer(QStringLiteral("Echo 
Server"), 
QWebSocketServer::NonSecureMode, 
this)), 
m_clients() 
{ 
if 
(m_pWebSocketServer-­‐>listen(QHostAddress::Any, 
port)) 
{ 
… 
QTimer 
*timer 
= 
new 
QTimer(this); 
connect(timer, 
&QTimer::timeout, 
this, 
&EchoServer::pingClients); 
timer-­‐>start(50000); 
} 
} 
void 
EchoServer::pingClients() 
{ 
if(m_clients.length() 
> 
0) 
{ 
qDebug() 
<< 
"Ping 
clients 
" 
<< 
m_clients.length(); 
for(int 
i 
= 
0; 
i< 
m_clients.length(); 
i++) 
{ 
m_clients[i]-­‐>ping(); 
} 
} 
" 
}
Demo
How to Use With Qt? 
lanevala@it-l-m0015 ~/Development/qtwebsockets-echoserver-example[master*]$ git push qtc master 
Counting objects: 1, done. 
Writing objects: 100% (1/1), 186 bytes | 0 bytes/s, done. 
Total 1 (delta 0), reused 0 (delta 0) 
-----> Qt app detected 
Installing Qt 5.4.0-beta-2014-09-25_25 
-----> Setting up Qt 5.4.0-beta-2014-09-25_25 
-----> Configuring with qmake 
-----> Compiling with make 
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - 
I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - 
I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o main.o main.cpp 
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - 
I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - 
I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o echoserver.o echoserver.cpp 
/app/.qtcs/Qt/5.4/gcc_64/bin/moc -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I/app/.qtcs/Qt/ 
5.4/gcc_64/mkspecs/linux-g++ -I/tmp/build -I/app/.qtcs/Qt/5.4/gcc_64/include -I/app/.qtcs/Qt/5.4/gcc_64/include/ 
QtWebSockets -I/app/.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I/app/.qtcs/Qt/5.4/gcc_64/include/QtCore echoserver.h -o 
moc_echoserver.cpp 
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - 
I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - 
I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o moc_echoserver.o moc_echoserver.cpp 
g++ -Wl,-O1 -Wl,-rpath,/app/.qtcs/Qt/5.4/gcc_64 -Wl,-rpath,/app/.qtcs/Qt/5.4/gcc_64/lib -o echoserver main.o 
echoserver.o moc_echoserver.o -L/app/.qtcs/Qt/5.4/gcc_64/lib -lQt5WebSockets -lQt5Network -lQt5Core -lpthread 
-----> Discovering process types 
Procfile declares types -> web 
-----> Compiled slug size is 108M 
-----> Deploying app 
Uploading app container ...... done. 
mar-eu-1-twwto7g0 deployed to http://mar-eu-1-twwto8g1.qtcloudapp.com
CONNECTED 
Does it echo? 
Does it echo? 
Echoserver listening on port 5000 
Echoserver got new connection 
Ping clients 1 
Echoserver got new pong 
Echoserver got new message "Does it echo?"
Qt WebChannel 
• The Qt WebChannel module provides a library for 
seamless integration of C++ and QML applications 
with HTML/JavaScript clients. 
• Any QObject can be published to remote clients, 
where its public API becomes available.
Example 
http://bit.ly/qtc-webchannel 
• Qt WebChannel Standalone example from Qt 5.4 
examples 
• Instead of local WebSocket server, we are using 
WebSocket server running on MAR
WebSocketClientWrapper.cpp 
/*! 
Construct 
the 
client 
wrapper 
with 
the 
given 
url. 
" 
All 
clients 
connecting 
to 
the 
QWebSocketServer 
will 
be 
automatically 
wrapped 
in 
WebSocketTransport 
objects. 
*/ 
WebSocketClientWrapper::WebSocketClientWrapper(const 
QUrl 
&url, 
QObject 
*parent) 
: 
QObject(parent) 
, 
m_url(url) 
{ 
qWarning() 
<< 
"Open 
WebSocket 
connection: 
" 
<< 
m_url; 
connect(&m_webSocket, 
&QWebSocket::connected, 
this, 
&WebSocketClientWrapper::handleNewConnection); 
m_webSocket.open(url); 
} 
" 
/*! 
Wrap 
an 
incoming 
WebSocket 
connection 
in 
a 
WebSocketTransport 
object. 
*/ 
void 
WebSocketClientWrapper::handleNewConnection() 
{ 
qWarning() 
<< 
"WebSocket 
connected: 
" 
<< 
m_url; 
emit 
clientConnected(new 
WebSocketTransport(&m_webSocket)); 
}
main.cpp 
// 
wrap 
WebSocket 
clients 
in 
QWebChannelAbstractTransport 
objects 
WebSocketClientWrapper 
clientWrapper(QUrl("wss://mar-­‐eu-­‐1-­‐twwto7g0.qtcloudapp.com")); 
" 
// 
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);
index.html 
window.onload 
= 
function() 
{ 
var 
baseUrl 
= 
"wss://mar-­‐eu-­‐1-­‐twwto7g0.qtcloudapp.com"; 
output("Connecting 
to 
WebSocket 
server 
at 
" 
+ 
baseUrl 
+ 
"."); 
var 
socket 
= 
new 
WebSocket(baseUrl); 
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!"); 
}); 
} 
}
Demo
QML HTML 
Initializing WebChannel... 
Initialization complete, opening browser at file:/// 
Users/lanevala/Qt5.4.0/Examples/Qt-5.4/ 
webchannel/build-standalone- 
Desktop_Qt_5_4_clang_64bit-Debug/index.html. 
Received message: Client connected, ready to 
send/receive messages! 
Text Message 
Connecting to WebSocket server at wss://mar-eu-1- 
twwto7g0.qtcloudapp.com. 
WebSocket connected, setting up QWebChannel. 
Connected to WebChannel, ready to send/receive messages! 
Sent message: Test message 
Received message: Test message
Summary 
• WebSockets are great 
• Using WebSockets with Qt and Qt Cloud Services is 
super easy and fast 
• There are multiple levels on you can utilise Qt Cloud 
Services to send and receive WebSocket messages 
• Use Managed WebSocket service 
• Deploy your own solution to MAR
Further actions 
• Visit qtcloudservices.com 
• Sign-up 
• Use it 
• Give us feedback 
• Qt forum 
• info@qtcloudservices.com
Thank you! 
Source Codes: 
• Enginio Todo: 
http://bit.ly/qtc-todo 
• Qt Cloud Services Todo: 
http://bit.ly/qtc-mar-todo 
• Qt WebSocket Echo Server: 
http://bit.ly/qt-echoserver

More Related Content

Viewers also liked

Everybody Polyglot! - Cross-Language RPC with Erlang
Everybody Polyglot! - Cross-Language RPC with ErlangEverybody Polyglot! - Cross-Language RPC with Erlang
Everybody Polyglot! - Cross-Language RPC with ErlangRusty Klophaus
 
Sulucionario electromagnetismo cheng
Sulucionario electromagnetismo cheng Sulucionario electromagnetismo cheng
Sulucionario electromagnetismo cheng Saku Garcia
 
Tarif jne-reg-2013-bdg-1-juni-2013
Tarif jne-reg-2013-bdg-1-juni-2013Tarif jne-reg-2013-bdg-1-juni-2013
Tarif jne-reg-2013-bdg-1-juni-2013ridwansf2
 
CV Roy Basoeki
CV Roy BasoekiCV Roy Basoeki
CV Roy Basoekitime4web
 
Say little, do more.
Say little, do more.Say little, do more.
Say little, do more.SURAJ MISHRA
 
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octaviana
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri OctavianaAplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octaviana
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octavianasutrioctavianasitorus
 
Microorganisms
MicroorganismsMicroorganisms
Microorganismssunilbhil
 
Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015ResearchInChina
 
Book4 unit1-lesson5
Book4 unit1-lesson5Book4 unit1-lesson5
Book4 unit1-lesson5stthomas8
 
Monografia fic
Monografia ficMonografia fic
Monografia ficromercen
 
Aspire one series service guide
Aspire one series service guideAspire one series service guide
Aspire one series service guideSetyo Prasadja
 

Viewers also liked (17)

Everybody Polyglot! - Cross-Language RPC with Erlang
Everybody Polyglot! - Cross-Language RPC with ErlangEverybody Polyglot! - Cross-Language RPC with Erlang
Everybody Polyglot! - Cross-Language RPC with Erlang
 
Yg Ini 1
Yg Ini 1Yg Ini 1
Yg Ini 1
 
Sulucionario electromagnetismo cheng
Sulucionario electromagnetismo cheng Sulucionario electromagnetismo cheng
Sulucionario electromagnetismo cheng
 
33 Period week
33 Period week33 Period week
33 Period week
 
Tarif jne-reg-2013-bdg-1-juni-2013
Tarif jne-reg-2013-bdg-1-juni-2013Tarif jne-reg-2013-bdg-1-juni-2013
Tarif jne-reg-2013-bdg-1-juni-2013
 
Hwswb
HwswbHwswb
Hwswb
 
CV Roy Basoeki
CV Roy BasoekiCV Roy Basoeki
CV Roy Basoeki
 
Say little, do more.
Say little, do more.Say little, do more.
Say little, do more.
 
Poor Pigs
Poor PigsPoor Pigs
Poor Pigs
 
англійська мова 3 кл підручник
англійська мова 3 кл підручниканглійська мова 3 кл підручник
англійська мова 3 кл підручник
 
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octaviana
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri OctavianaAplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octaviana
Aplikom_Unsri_1. MyBiodata dan keunikan Matematika_Sutri Octaviana
 
Microorganisms
MicroorganismsMicroorganisms
Microorganisms
 
Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015Global and china obd telematics industry report, 2014 2015
Global and china obd telematics industry report, 2014 2015
 
Book4 unit1-lesson5
Book4 unit1-lesson5Book4 unit1-lesson5
Book4 unit1-lesson5
 
Monografia fic
Monografia ficMonografia fic
Monografia fic
 
Aspire one series service guide
Aspire one series service guideAspire one series service guide
Aspire one series service guide
 
Inside sina weibo
Inside sina weiboInside sina weibo
Inside sina weibo
 

Recently uploaded

Pvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan
 
Statistical Analysis of DNS Latencies.pdf
Statistical Analysis of DNS Latencies.pdfStatistical Analysis of DNS Latencies.pdf
Statistical Analysis of DNS Latencies.pdfOndejSur
 
Reggie miller choke t shirtsReggie miller choke t shirts
Reggie miller choke t shirtsReggie miller choke t shirtsReggie miller choke t shirtsReggie miller choke t shirts
Reggie miller choke t shirtsReggie miller choke t shirtsrahman018755
 
iThome_CYBERSEC2024_Drive_Into_the_DarkWeb
iThome_CYBERSEC2024_Drive_Into_the_DarkWebiThome_CYBERSEC2024_Drive_Into_the_DarkWeb
iThome_CYBERSEC2024_Drive_Into_the_DarkWebJie Liau
 
Premier Mobile App Development Agency in USA.pdf
Premier Mobile App Development Agency in USA.pdfPremier Mobile App Development Agency in USA.pdf
Premier Mobile App Development Agency in USA.pdfappinfoedgeca
 
Bug Bounty Blueprint : A Beginner's Guide
Bug Bounty Blueprint : A Beginner's GuideBug Bounty Blueprint : A Beginner's Guide
Bug Bounty Blueprint : A Beginner's GuideVarun Mithran
 
Cyber Security Services Unveiled: Strategies to Secure Your Digital Presence
Cyber Security Services Unveiled: Strategies to Secure Your Digital PresenceCyber Security Services Unveiled: Strategies to Secure Your Digital Presence
Cyber Security Services Unveiled: Strategies to Secure Your Digital PresencePC Doctors NET
 
Topology of the Network class 8 .ppt pdf
Topology of the Network class 8 .ppt pdfTopology of the Network class 8 .ppt pdf
Topology of the Network class 8 .ppt pdfAnushkaTripathi61
 
I’ll See Y’All Motherfuckers In Game 7 Shirt
I’ll See Y’All Motherfuckers In Game 7 ShirtI’ll See Y’All Motherfuckers In Game 7 Shirt
I’ll See Y’All Motherfuckers In Game 7 Shirtrahman018755
 
Production 2024 sunderland culture final - Copy.pptx
Production 2024 sunderland culture final - Copy.pptxProduction 2024 sunderland culture final - Copy.pptx
Production 2024 sunderland culture final - Copy.pptxChloeMeadows1
 
Thank You Luv I’ll Never Walk Alone Again T shirts
Thank You Luv I’ll Never Walk Alone Again T shirtsThank You Luv I’ll Never Walk Alone Again T shirts
Thank You Luv I’ll Never Walk Alone Again T shirtsrahman018755
 
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.Tortogel
 
How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?Linksys Velop Login
 
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkk
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkkaudience research (emma) 1.pptxkkkkkkkkkkkkkkkkk
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkklolsDocherty
 
The Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyThe Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyDamar Juniarto
 
Development Lifecycle.pptx for the secure development of apps
Development Lifecycle.pptx for the secure development of appsDevelopment Lifecycle.pptx for the secure development of apps
Development Lifecycle.pptx for the secure development of appscristianmanaila2
 

Recently uploaded (16)

Pvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdf
 
Statistical Analysis of DNS Latencies.pdf
Statistical Analysis of DNS Latencies.pdfStatistical Analysis of DNS Latencies.pdf
Statistical Analysis of DNS Latencies.pdf
 
Reggie miller choke t shirtsReggie miller choke t shirts
Reggie miller choke t shirtsReggie miller choke t shirtsReggie miller choke t shirtsReggie miller choke t shirts
Reggie miller choke t shirtsReggie miller choke t shirts
 
iThome_CYBERSEC2024_Drive_Into_the_DarkWeb
iThome_CYBERSEC2024_Drive_Into_the_DarkWebiThome_CYBERSEC2024_Drive_Into_the_DarkWeb
iThome_CYBERSEC2024_Drive_Into_the_DarkWeb
 
Premier Mobile App Development Agency in USA.pdf
Premier Mobile App Development Agency in USA.pdfPremier Mobile App Development Agency in USA.pdf
Premier Mobile App Development Agency in USA.pdf
 
Bug Bounty Blueprint : A Beginner's Guide
Bug Bounty Blueprint : A Beginner's GuideBug Bounty Blueprint : A Beginner's Guide
Bug Bounty Blueprint : A Beginner's Guide
 
Cyber Security Services Unveiled: Strategies to Secure Your Digital Presence
Cyber Security Services Unveiled: Strategies to Secure Your Digital PresenceCyber Security Services Unveiled: Strategies to Secure Your Digital Presence
Cyber Security Services Unveiled: Strategies to Secure Your Digital Presence
 
Topology of the Network class 8 .ppt pdf
Topology of the Network class 8 .ppt pdfTopology of the Network class 8 .ppt pdf
Topology of the Network class 8 .ppt pdf
 
I’ll See Y’All Motherfuckers In Game 7 Shirt
I’ll See Y’All Motherfuckers In Game 7 ShirtI’ll See Y’All Motherfuckers In Game 7 Shirt
I’ll See Y’All Motherfuckers In Game 7 Shirt
 
Production 2024 sunderland culture final - Copy.pptx
Production 2024 sunderland culture final - Copy.pptxProduction 2024 sunderland culture final - Copy.pptx
Production 2024 sunderland culture final - Copy.pptx
 
Thank You Luv I’ll Never Walk Alone Again T shirts
Thank You Luv I’ll Never Walk Alone Again T shirtsThank You Luv I’ll Never Walk Alone Again T shirts
Thank You Luv I’ll Never Walk Alone Again T shirts
 
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.
TORTOGEL TELAH MENJADI SALAH SATU PLATFORM PERMAINAN PALING FAVORIT.
 
How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?
 
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkk
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkkaudience research (emma) 1.pptxkkkkkkkkkkkkkkkkk
audience research (emma) 1.pptxkkkkkkkkkkkkkkkkk
 
The Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyThe Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case Study
 
Development Lifecycle.pptx for the secure development of apps
Development Lifecycle.pptx for the secure development of appsDevelopment Lifecycle.pptx for the secure development of apps
Development Lifecycle.pptx for the secure development of apps
 

Give a Push to Your Qt Application with Websockets

  • 1. Give a Push to Your Qt Application with Qt Cloud Services and WebSockets
  • 3. Lauri Nevala nevalau nevalla nevalla • Working in Qt Cloud Services team at The Qt Company • Over ten years of experience in creating web and mobile based applications
  • 4. Our Goal Understand how to use Qt Cloud Services in order to send and receive WebSocket messages
  • 5.
  • 6. What is Qt Cloud Services Enginio Data Storage Storage for Applica/on Data Use with QtEnginio Library Managed Applica3on Run3me Applica/on Pla<orm as a Service Support for Qt/C++, NodeJS, Apache, PHP, MongoDB, MySQL, Redis… Managed WebSocket Real-­‐Time Socket Connec/ons with virtually unlimited scalability Use with SDK’s and Qt WebSocket Client Library
  • 7. Enginio Data Storage (EDS) Flexible and powerful cloud data storage with built-in user and data access control
  • 8. Managed Application Runtime (MAR) Scalable," Multi-language," Multi-database," Application Platform as a Service
  • 9. Managed Application Runtimes How does it work?
  • 10. Supported Frameworks Supported frameworks by 3rd party build packs Scala, Clojure, Play, Gradle, Grails, PHP, Go, Meteorite, Perl, Dart, Nginx, Apache, Jekyll
  • 11. Built-in Services or choose from our cloud based services Enginio Data Storage" Managed WebSocket or choose anything with SDK ... Amazon, Azure, Google ...
  • 12. Developer Friendly Deployment Deploy using Git – the most common VCS among developers > git push qtc master
  • 13. Managed WebSocket (MWS) Fully managed service implementing a bi-directional, real-time communication gateway for WebSockets.
  • 14. Managed WebSocket How does it work?
  • 15. 3. send WebSocket message 1. get WebSocket URI 4. deliver WebSocket message 2. open WebSocket connection { data: '{ "object":{ "id":"541df1c1e5bde554a805b213", "createdAt":"2014-­‐09 20T21:29:37.849Z", "device":"FZXC0wg0LvaJ", "done":false, "objectType":"objects.todos", "text":"testi2", "updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", "userId":"user:54196f3f5a3d8b61860381a4" }, "meta":{ "backendId":"5417e5485a3d8b418a01adb7", "eventName":"create", "requestId":"a671f67b4f41c20b53988a6057b32539", "userId":null} }', receivers: { sockets: ['*'], tags: [] } }
  • 16. WebSockets Consider using WebSockets for instantaneous data without the browser refresh
  • 17. Where to use? • Chats • Social feeds • Multiplayer games • Collaborative editing • Sport updates • Location based apps • Your killer app
  • 18. Why WebSockets are so great? • WebSockets defines an API establishing “socket” connections between web clients and a server • TCP-based protocol • Full-duplex, simultaneous bi-directional messaging • Uri scheme ws: and wss:
  • 19. WebSockets and Qt Cloud Services 1. + ➡ public socket 2. + + ➡ private socket 3. ➡ do anything you want
  • 21. +
  • 22. WebSocket server Create EDS instance Create MWS instance Create EDS Webhook
  • 23.
  • 24. WebSocket server Create EDS instance Create MWS instance Create EDS Webhook
  • 25.
  • 26.
  • 27. WebSocket server Create EDS instance Create MWS instance Create EDS Webhook
  • 28. Create EDS Webhook http://bit.ly/eds-mws-webhook
  • 29. EDS MWS { data: '{ "object":{ "id":"541df1c1e5bde554a805b213", "createdAt":"2014-­‐09 20T21:29:37.849Z", "device":"FZXC0wg0LvaJ", "done":false, "objectType":"objects.todos", "text":"testi2", "updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", "userId":"user:54196f3f5a3d8b61860381a4" }, "meta":{ "backendId":"5417e5485a3d8b418a01adb7", "eventName":"create", "requestId":"a671f67b4f41c20b53988a6057b32539", "userId":null} }', receivers: { sockets: ['*'], tags: [] } } HTTP POST https://mws-eu-1.qtc.io/v1/gateways/MWS_GATEWAY_ID/webhook_receivers/enginio App { "object":{ "id":"541df1c1e5bde554a805b213", "createdAt":"2014-­‐09 20T21:29:37.849Z", "device":"FZXC0wg0LvaJ", "done":false, "objectType":"objects.todos", "text":"testi2", "updatedAt":"2014-­‐09-­‐20T21:29:37.849Z", "userId":"user:54196f3f5a3d8b61860381a4" }, "meta":{ "backendId":"5417e5485a3d8b418a01adb7", "eventName":"create", "requestId":"a671f67b4f41c20b53988a6057b32539", "userId":null} } } send WebSocket message to all sockets
  • 30. WebSocket server Create a EDS instance Create a MWS instance Create EDS Webhook
  • 32. 2. create Todo 3. trigger Webhook 4. send WebSocket message 5. refresh UI 1. connect to WebSocket
  • 33. websocketclient.cpp #include "websocketclient.h" #include <QtCore/QDebug> " QT_USE_NAMESPACE " WebSocketClient::WebSocketClient(const QUrl &url, QObject *parent) : QObject(parent), m_url(url) { connect(&m_webSocket, &QWebSocket::connected, this, &WebSocketClient::onConnected); connect(&m_webSocket, &QWebSocket::disconnected, this, &WebSocketClient::closed); m_webSocket.open(QUrl(url)); } " void WebSocketClient::onConnected() { qDebug() << "WebSocket connected"; connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &WebSocketClient::onTextMessageReceived); } " void WebSocketClient::onTextMessageReceived(QString message) { emit onMessageReceived(message); }
  • 34. mainwindow.cpp #define REQUEST_URL “https://mws-­‐eu-­‐1.qtc.io/v1/gateways/MWS_GATEWAY_ID/websocket_uri” " MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { … m_networkManager = new QNetworkAccessManager(this); QObject::connect(m_networkManager, &QNetworkAccessManager::finished, this, &MainWindow::requestFinished); getWebSocketUrl(); … } QNetworkReply* MainWindow::getWebSocketUrl() { QNetworkRequest request; request.setUrl(QUrl(QString("%1").arg(REQUEST_URL))); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); " QNetworkReply *reply = m_networkManager-­‐>get(request); return reply; } void MainWindow::requestFinished(QNetworkReply *reply) { QJsonDocument replyData = QJsonDocument::fromJson(reply-­‐>readAll()); QJsonObject data = replyData.object(); " m_mwsClient = new WebSocketClient(QUrl(data.value("uri").toString()), this); " QObject::connect(m_mwsClient, &WebSocketClient::onMessageReceived, this, &MainWindow::messageReceived); }
  • 35. void MainWindow::messageReceived(QString message) { qDebug() << "Message received:" << message; QJsonDocument messageJson = QJsonDocument::fromJson(message.toUtf8()); QJsonObject enginioObject = messageJson.object().value("object").toObject(); QJsonObject metaObject = messageJson.object().value("meta").toObject(); QString event = metaObject.value("eventName").toString(); if(event == "delete" || enginioObject.value("device_id").toString() != m_device) { qDebug() << "Refresh todos"; QJsonObject query; // reload todos from Enginio m_model-­‐>setQuery(query); " query["objectType"] = QString::fromUtf8("objects.todos"); m_model-­‐>setQuery(query); " } }
  • 36. Demo
  • 37.
  • 39. + +
  • 40. Server-side app // Qt Cloud Services package var qtc = require('qtc'); var qtcConfig = require('../config/qtc-­‐conf'); var mws = new qtc.Mws(qtcConfig.mws); module.exports = function(app) { app.post('/api/websocket/messages', function(req, res) { var payload = req.body.payload; console.log('got websocket request:') console.log(payload) " mws.send(JSON.stringify(payload), { sockets: null, tags: [payload.object.userId] }, function(e, mwsResponse) { console.log('send websocket message:'); console.log(mwsResponse); res.json(mwsResponse); }) }); … } app.get('/api/websocket', function(req, res) { authenticateRequest(req, function(e, session){ if(!e){ mws.createSocket(["user:"+session.userId], function(e, mwsResponse) { res.json(mwsResponse); }); } else { res.json(error(403, "Access Denied!")); } }); });
  • 42. 2. create Todo 4. trigger Webhook 5. send WebSocket message 6. refresh UI 3. insert Todo 1. connect to WebSocket
  • 43. main.qml import QtQuick 2.2 import QtQuick.Controls 1.1 import Qt.WebSockets 1.0 import "Storage.js" as Storage " Item { id: app width: 480 height: 800 … " WebSocket { id: socket active: true onTextMessageReceived: { console.log(message) Storage.handleWebsocketMessage(message) } onStatusChanged: { if (socket.status == WebSocket.Error) { console.log("Error: " + socket.errorString) } else if (socket.status == WebSocket.Open) { console.log("Open") } else if (socket.status == WebSocket.Closed) { console.log("Socket closed") } } } … }
  • 44. storage.js var REQUEST_URL = "http://qtc-­‐tutorial-­‐todo.qtcloudapp.com" function connectToWebSocket() { var doc = new XMLHttpRequest(); doc.open("GET", REQUEST_URL + "/api/websocket", true); doc.setRequestHeader('x-­‐todo-­‐session', sessionId); doc.setRequestHeader('Content-­‐Type', 'application/json'); doc.onreadystatechange = function() { // When ready if (doc.readyState === 4) { // If OK if (doc.status === 200) { var data = JSON.parse(doc.responseText); console.log(doc.responseText) socket.url = data.uri } } } doc.send() }
  • 45. function handleWebsocketMessage(message) { message = JSON.parse(message) var event = message.meta.eventName var object = message.object if(object.device !== device) { // ignore events created by this app var i if(event === "create") { addItem(object.text, object.id) } else if(event === "update") { for (i=itemModel.count; i-­‐-­‐;) { if( object.id === itemModel.get(i).itemId) { finishItem(i, false) break; } } } } if(event === "delete") { for (i=itemModel.count; i-­‐-­‐;) { if( object.id === itemModel.get(i).itemId) { deleteItem(i, false) break; } } } }
  • 46. Demo • Try it yourself! • http://bit.ly/qtc-todo-demo • username: qtincloud password: qtincloud
  • 48.
  • 50. I want to use !!!1
  • 51. Using WebSockets with MAR • Server must listen to a port that MAR gives to the app • To keep idle socket connections alive, the WebSocket server must send a ping control frame to every client at least once in < 60s
  • 52. Qt WebSocket EchoServer http://bit.ly/qt-echoserver • Example can be found from Qt 5.3 examples • Bug in Qt 5.3 that prevents deploying it to MAR • Fixed in Qt 5.4 • Qt 5.4 beta in MAR allows us to test it out
  • 53. main.cpp #include <QtCore/QCoreApplication> #include "echoserver.h" " int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int port = 1234; if(qEnvironmentVariableIsSet("PORT") && !qEnvironmentVariableIsEmpty("PORT")) { port = qgetenv("PORT").toInt(); } EchoServer *server = new EchoServer(port); QObject::connect(server, &EchoServer::closed, &a, &QCoreApplication::quit); " return a.exec(); }
  • 54. echoserver.cpp EchoServer::EchoServer(quint16 port, QObject *parent) : QObject(parent), m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Echo Server"), QWebSocketServer::NonSecureMode, this)), m_clients() { if (m_pWebSocketServer-­‐>listen(QHostAddress::Any, port)) { … QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &EchoServer::pingClients); timer-­‐>start(50000); } } void EchoServer::pingClients() { if(m_clients.length() > 0) { qDebug() << "Ping clients " << m_clients.length(); for(int i = 0; i< m_clients.length(); i++) { m_clients[i]-­‐>ping(); } } " }
  • 55. Demo
  • 56. How to Use With Qt? lanevala@it-l-m0015 ~/Development/qtwebsockets-echoserver-example[master*]$ git push qtc master Counting objects: 1, done. Writing objects: 100% (1/1), 186 bytes | 0 bytes/s, done. Total 1 (delta 0), reused 0 (delta 0) -----> Qt app detected Installing Qt 5.4.0-beta-2014-09-25_25 -----> Setting up Qt 5.4.0-beta-2014-09-25_25 -----> Configuring with qmake -----> Compiling with make g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o main.o main.cpp g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o echoserver.o echoserver.cpp /app/.qtcs/Qt/5.4/gcc_64/bin/moc -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I/app/.qtcs/Qt/ 5.4/gcc_64/mkspecs/linux-g++ -I/tmp/build -I/app/.qtcs/Qt/5.4/gcc_64/include -I/app/.qtcs/Qt/5.4/gcc_64/include/ QtWebSockets -I/app/.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I/app/.qtcs/Qt/5.4/gcc_64/include/QtCore echoserver.h -o moc_echoserver.cpp g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB - I.qtcs/Qt/5.4/gcc_64/mkspecs/linux-g++ -I. -I.qtcs/Qt/5.4/gcc_64/include -I.qtcs/Qt/5.4/gcc_64/include/QtWebSockets - I.qtcs/Qt/5.4/gcc_64/include/QtNetwork -I.qtcs/Qt/5.4/gcc_64/include/QtCore -I. -o moc_echoserver.o moc_echoserver.cpp g++ -Wl,-O1 -Wl,-rpath,/app/.qtcs/Qt/5.4/gcc_64 -Wl,-rpath,/app/.qtcs/Qt/5.4/gcc_64/lib -o echoserver main.o echoserver.o moc_echoserver.o -L/app/.qtcs/Qt/5.4/gcc_64/lib -lQt5WebSockets -lQt5Network -lQt5Core -lpthread -----> Discovering process types Procfile declares types -> web -----> Compiled slug size is 108M -----> Deploying app Uploading app container ...... done. mar-eu-1-twwto7g0 deployed to http://mar-eu-1-twwto8g1.qtcloudapp.com
  • 57. CONNECTED Does it echo? Does it echo? Echoserver listening on port 5000 Echoserver got new connection Ping clients 1 Echoserver got new pong Echoserver got new message "Does it echo?"
  • 58. Qt WebChannel • The Qt WebChannel module provides a library for seamless integration of C++ and QML applications with HTML/JavaScript clients. • Any QObject can be published to remote clients, where its public API becomes available.
  • 59. Example http://bit.ly/qtc-webchannel • Qt WebChannel Standalone example from Qt 5.4 examples • Instead of local WebSocket server, we are using WebSocket server running on MAR
  • 60. WebSocketClientWrapper.cpp /*! Construct the client wrapper with the given url. " All clients connecting to the QWebSocketServer will be automatically wrapped in WebSocketTransport objects. */ WebSocketClientWrapper::WebSocketClientWrapper(const QUrl &url, QObject *parent) : QObject(parent) , m_url(url) { qWarning() << "Open WebSocket connection: " << m_url; connect(&m_webSocket, &QWebSocket::connected, this, &WebSocketClientWrapper::handleNewConnection); m_webSocket.open(url); } " /*! Wrap an incoming WebSocket connection in a WebSocketTransport object. */ void WebSocketClientWrapper::handleNewConnection() { qWarning() << "WebSocket connected: " << m_url; emit clientConnected(new WebSocketTransport(&m_webSocket)); }
  • 61. main.cpp // wrap WebSocket clients in QWebChannelAbstractTransport objects WebSocketClientWrapper clientWrapper(QUrl("wss://mar-­‐eu-­‐1-­‐twwto7g0.qtcloudapp.com")); " // 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);
  • 62. index.html window.onload = function() { var baseUrl = "wss://mar-­‐eu-­‐1-­‐twwto7g0.qtcloudapp.com"; output("Connecting to WebSocket server at " + baseUrl + "."); var socket = new WebSocket(baseUrl); 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!"); }); } }
  • 63. Demo
  • 64. QML HTML Initializing WebChannel... Initialization complete, opening browser at file:/// Users/lanevala/Qt5.4.0/Examples/Qt-5.4/ webchannel/build-standalone- Desktop_Qt_5_4_clang_64bit-Debug/index.html. Received message: Client connected, ready to send/receive messages! Text Message Connecting to WebSocket server at wss://mar-eu-1- twwto7g0.qtcloudapp.com. WebSocket connected, setting up QWebChannel. Connected to WebChannel, ready to send/receive messages! Sent message: Test message Received message: Test message
  • 65. Summary • WebSockets are great • Using WebSockets with Qt and Qt Cloud Services is super easy and fast • There are multiple levels on you can utilise Qt Cloud Services to send and receive WebSocket messages • Use Managed WebSocket service • Deploy your own solution to MAR
  • 66. Further actions • Visit qtcloudservices.com • Sign-up • Use it • Give us feedback • Qt forum • info@qtcloudservices.com
  • 67. Thank you! Source Codes: • Enginio Todo: http://bit.ly/qtc-todo • Qt Cloud Services Todo: http://bit.ly/qtc-mar-todo • Qt WebSocket Echo Server: http://bit.ly/qt-echoserver