SlideShare ist ein Scribd-Unternehmen logo
1 von 18
www.italiancpp.org
Italian C++ Conference 2016
14 Maggio, Milano
REST e Websocket in C++ diventano
semplici e produttivi con il REST SDK
Raffaele Rialdi
Twitter: @raffaeler
Email: raffaeler@vevy.com
Website: http://iamraf.net
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
Chi sono …
• Lavoro nella programmazione software dal 1987
•Senior Software Architect in Vevy Europe
•Consulente in diversi ambiti (finanziario, automotive, racing, manufacturing,
healthcare)
• Specializzato sul mondo Microsoft
•Ho iniziato con il DOS 1.0 … e ho seguito tutto ciò che è venuto dopo
•Linguaggi preferiti: C++ e C#
•Prediligo le tecnologie di "basso" livello e la «application security»
•Microsoft MVP dall'anno 2003
• Trainer e speaker
•Ho insegnato informatica per anni (e salutariamente continuo)
•Partecipo a varie conferenze italiane e internazionali
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
Cos'è Casablanca REST SDK?
• Una libreria che semplifica l'accesso a servizi REST e comunicazioni
Websocket
•Provvede anche servizi base (in beta) per creare semplici HTTP Server
• Si basa su alcuni «pillars» fondamentali:
1. Gestione asincrona basata sui Task
2. Utilizzo di C++ "moderno" (è nata al momento dello standard C++11)
3. Cross-platform (Windows Desktop/Store/Phone, Linux, Android, Mac, iOS)
4. Cerca di offrire tutti i «building blocks» indispensabili (Json, Uri, conversioni
Unicode, OAuth, etc.)
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
I problemi del cross-platform
• In Windows, le stringhe sono wide (16 bit)
•wchar_t, wstring, …
• In Posix (Linux, Unix) le stringhe sono narrow (8 bit)
•char, string, …
•Il REST SDK definisce un tipo neutrale
•Conversioni disponibili
• to_string_t, to_utf8string, to_utf16string
utility::string_t
#ifdef _UTF16_STRINGS
typedef wchar_t char_t ;
typedef std::wstring string_t;
#define _XPLATSTR(x) L ## x
typedef std::wostringstream ostringstream_t;
typedef std::wofstream ofstream_t;
typedef std::wostream ostream_t;
typedef std::wistream istream_t;
typedef std::wifstream ifstream_t;
typedef std::wistringstream istringstream_t;
typedef std::wstringstream stringstream_t;
#define ucout std::wcout
#define ucin std::wcin
#define ucerr std::wcerr
#else
...
basic_types.h
U("Hello, world")
std::string ansiRaf("raffaele");
string_t raf_t(to_string_t(ansiRaf));
std::string(begin(raf_t), end(raf_t));
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
PPL in una slide
• Dimenticate i thread, pensate a task
• Motivazioni: cross-platform, scalabilità, migliore schedulazione, codice più pulito, richiesto nelle applicazioni mobile
• Ok, da domani li uso … ma che problemi ci sono?
• Le STL sono sincrone, co-routines non fanno parte dello standard, i «futures» hanno diverse lacune
• Arrivano le «Parallel Pattern Library» in soccorso
• creare un task
• scrivere una continuation
• continuation con co_await
• usare i task_completion
• Un task setta il risultato
• L'altro task è un attesa del risultato
#include <ppl.h>
using namespace concurrency;
return create_task([] () {});
SumAsync(10, 20).then([=](int sum) { Process(sum); };
int result = co_await SumAsync(10, 20);
Process(result);
task_completion_event<bool> quit;
quit->set(true);
bool result = co_await pplx::task<bool>(quit);
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
concurrency::stream cheat sheet
basic_istream<>
stdio_istream<> async_iostream<>
basic_iostream<>
std
concurrency::streams
namespaces
concurrency::streams::details
streambuf<>
basic_streambuf<>
container_buffer<>
producer_consumer_
buffer<>
rawptr_buffer<>
basic_ostream<>
stdio_ostream<> async_ostream<>
basic_ostream<>
async_istream<>
basic_istream<>
astreambuf.h
interopstream.h
streams.h
containerstream.h
bytestream
(factory)
containerstream.h
container_stream<>
(factory)
containerstream.h
producerconsumerstream.h
rawptrstream.h
rawptr_stream
(factory)
rawptrstream.h
interopstream.h
interopstream.h
astreambuf.h
streams.h
interopstream.h
interopstream.h
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
typedefs definiti dal REST SDK
typedef container_stream<std::basic_string<char>> stringstream;
typedef stringstream::buffer_type stringstreambuf;
typedef container_stream<utility::string_t> wstringstream;
typedef wstringstream::buffer_type wstringstreambuf;
typedef file_stream<uint8_t> fstream;
typedef basic_ostream<uint8_t> ostream;
typedef basic_istream<uint8_t> istream;
typedef basic_ostream<utf16char> wostream;
typedef basic_istream<utf16char> wistream;
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
File streams – leggere un file di testo
file_buffer<>
file_stream<>
(factory)
filestream.h
std
concurrency::streams
namespaces
concurrency::streams::details
std::string Test1(const string_t& filename)
{
auto istr = slx::fstream::open_istream(filename, std::ios::in).get();
slx::stringstreambuf strbuf;
auto size = istr.read_to_end(strbuf).get();
istr.close();
string content = strbuf.collection();
cout << content.c_str();
return content;
}
task<std::string> Test1Async2(const string_t& filename)
{
auto istr = co_await slx::fstream::open_istream(filename, std::ios::in);
slx::stringstreambuf strbuf;
auto size = co_await istr.read_to_end(strbuf);
istr.close();
string content = strbuf.collection();
cout << content.c_str();
return content;
}
Nota: Al momento co_await funziona solo se viene aggiunto /await alla riga di comando del compilatore
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
File streams – copiare un file
file_buffer<>
file_stream<>
(factory)
filestream.h
std
concurrency::streams
namespaces
concurrency::streams::details
void Test3(const string_t& source, const string_t& target)
{
auto istr = slx::fstream::open_istream(source, std::ios::in).get();
auto ostr = slx::fstream::open_ostream(target, std::ios::out).get();
slx::producer_consumer_buffer<char> buffer;
int size = 110; // dimensione del blocco da copiare
while (auto ilen = istr.read(buffer, size).get())
{
auto olen = ostr.write(buffer, ilen).get();
}
istr.close();
ostr.close();
}
co_await
co_await
co_await
co_await
Nota: Al momento co_await funziona solo se viene aggiunto /await alla riga di comando del compilatore
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
I building block di rete
• Le tre classi principali sono:
•http_client: astrazione su tre librerie
• boost::asio per il mondo *nix
• WinHttp per Windows Desktop
• WinRT per il Windows Store
•http_listener (beta): astrazione su:
• boost::asio per il mondo *nix
• Http.sys per il mondo Windows Desktop
• WinRT vieta l'uso di listener nelle App (security!)
•websocket_client: astrazione su:
• Websocket++ per tutti gli OS tranne …
• WinRT offre il suo supporto nativo
Boost::Asio WinHttp WinRT
http_client
Boost::Asio Http.Sys
http_listener
WebsocketPP WinRT
websocket_client
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
Features vs Sistema Operativo
Windows
Desktop
Windows
Store
WP 8 WP 8.1
WP 8.1
Silverlight
Windows
XP
Linux
(Ubuntu)
Mac OS
X
iOS
Android
Programming
with Tasks
JSON
Asynchronous
Streams
URIs
HTTP Client
HTTP Listener (Beta) (Beta) (Beta) (Beta) (Beta)
WebSocket Client
OAuth Client (Beta) (Beta)
(Beta,
OAuth2
only)
(Beta,
OAuth2
only)
(Beta,
OAuth2
only)
(Beta,
OAuth2
only)
(Beta) (Beta) (Beta) (Beta)
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
Leggere/scrivere JSON
#include "cpprestjson.h"
json::value root2(100);
auto root6 = json::value::string(U("hello, world"));
vector<pair<string_t, json::value>> props
...
auto root2 = json::value::object(props);
Creare un intero:
Creare una stringa:
Creare un oggetto:
using namespace web;
using namespace utility;
using namespace utility::conversions;
auto jsonText = U("[ "Book", "Pencil" ]");
auto json = json::value::parse(jsonText);
Deserializzazione:
void print(const json::value& val)
{
string_t text = val.serialize();
std::string utf8 = to_utf8string(text);
cout << utf8.c_str() << endl;
}
Serializzazione:
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
tip: deserializzare in un boost::variant
1.
2. definire un tipo "metamorfico"
3. ciclare le proprietà del json::object e deserializzare ogni valore in
un "universal"
4. boost::variant è "iostream" friendly
typedef boost::variant<bool, double, int, std::string> universal;
#include "boostvariantvariant.hpp"
if (val.is_string())
{
auto stringt = val.as_string();
return universal(string(begin(stringt), end(stringt)));
}
if (val.is_boolean()) return universal(val.as_bool());
if (val.is_double()) return universal(val.as_double());
...
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
http_client in action
1. Costruire del client
2. Costruire una request
3. Aggiungere gli header
4. Aggiungere il body (POST)
5. Eseguire la chiamata
6. Controllare http status
7. Leggere il contenuto
http_client client(_address);
http_request request(methods::POST);
request.headers().add(
header_names::user_agent,
U("IAmRaf agent"));
request.set_body(body);
auto resp = co_await client.request(request);
http_response
if (response.status_code() == status_codes::OK)
auto json = co_await resp.extract_json();
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
http_listener (beta)
1. Dichiarare uno smart ptr
2. Creare il listener
3. Binding per ogni verb
4. Iniziare la Listen sulla rete
unique_ptr<http_listener> _listener;
_listener = make_unique<http_listener>(address);
_listener->support(methods::GET,
std::bind(&Listener::handle_get, this,
std::placeholders::_1));
co_await _listener->open();
#include "cppresthttp_listener.h"
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
websocket_client
1. Creare il client
2. Aprire la connessione
3. Creare un messaggio (out)
4. Impostare il contenuto
5. Spedire il messaggio
6. Ricevere la risposta
7. Leggere il body
8. Leggere il body type
9. Leggere il contenuto
co_await client->connect(U("ws://server/...");
client = std::make_unique<websocket_client>();
websocket_outgoing_message message;
message.set_utf8_message("hello, world");
websocket_incoming_message message =
co_await client->receive();
client->send(message);
istream body = message.body();
websocket_message_type messageType =
message.message_type();
auto text = co_await message.extract_string();
RFC 6455
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
tip: subprotocollo e headers Websockets
• Il protocollo Websocket inizia con un handshake HTTP
• Segue una notifica « 101 – Upgrade »
• E una negoziazione di un "subprotocol" definito a livello applicativo
Ecco i passi per poter aggiungere headers e subprotocollo
• Create the options
• Add the sub-protocol
• Add headers
websocket_client_config config;
config.add_subprotocol(U("subprotocol-raf"));
config.headers().add(U("X-Raf"),
to_string_t("C++ Native Client"));
RFC 6455
Italian C++ Conference 2016 – Un evento dell’Italian C++ Community
Domande?
Raffaele Rialdi
Twitter: @raffaeler
Email: raffaeler@vevy.com

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (15)

Introduzione a Python
Introduzione a PythonIntroduzione a Python
Introduzione a Python
 
05 1 intro-struttura
05 1 intro-struttura05 1 intro-struttura
05 1 intro-struttura
 
06 1 array_stringhe_typedef
06 1 array_stringhe_typedef06 1 array_stringhe_typedef
06 1 array_stringhe_typedef
 
Bash intro
Bash introBash intro
Bash intro
 
2006 Py02 base
2006 Py02 base2006 Py02 base
2006 Py02 base
 
2008 python
2008 python2008 python
2008 python
 
Gcc & Make
Gcc & MakeGcc & Make
Gcc & Make
 
Buffer Overflow - Shellcode - Shatter Attack
Buffer Overflow - Shellcode - Shatter AttackBuffer Overflow - Shellcode - Shatter Attack
Buffer Overflow - Shellcode - Shatter Attack
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@Unina
 
Assembly and Reverse Engineering
Assembly and Reverse EngineeringAssembly and Reverse Engineering
Assembly and Reverse Engineering
 
05 2 integrali-conversioni-costanti-preproc-inclusione
05 2 integrali-conversioni-costanti-preproc-inclusione05 2 integrali-conversioni-costanti-preproc-inclusione
05 2 integrali-conversioni-costanti-preproc-inclusione
 
Js intro
Js introJs intro
Js intro
 
2006 Py03 intermedio
2006 Py03 intermedio2006 Py03 intermedio
2006 Py03 intermedio
 
Cattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaCattive abitudini e-lineeguida
Cattive abitudini e-lineeguida
 
Pycrashcourse2.0
Pycrashcourse2.0Pycrashcourse2.0
Pycrashcourse2.0
 

Andere mochten auch

The World Cancer Research Fund International Continuous Update Project (CUP):...
The World Cancer Research Fund International Continuous Update Project (CUP):...The World Cancer Research Fund International Continuous Update Project (CUP):...
The World Cancer Research Fund International Continuous Update Project (CUP):...World Cancer Research Fund International
 
TravConnect Technology Day 2015 - Niek Stevens - Sue Amsterdam
TravConnect Technology Day 2015 - Niek Stevens - Sue AmsterdamTravConnect Technology Day 2015 - Niek Stevens - Sue Amsterdam
TravConnect Technology Day 2015 - Niek Stevens - Sue AmsterdamTravMagazine
 
How to Rock your Next Pitch Deck
How to Rock your Next Pitch DeckHow to Rock your Next Pitch Deck
How to Rock your Next Pitch Deckkathhemmings
 
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015Praveen Paranjothi
 
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...Nina Faulhaber
 
500’s Demo Day Batch 11 >> Slidebean
500’s Demo Day Batch 11 >> Slidebean 500’s Demo Day Batch 11 >> Slidebean
500’s Demo Day Batch 11 >> Slidebean 500 Startups
 
Pitch Deck Template for startups
Pitch Deck Template for startupsPitch Deck Template for startups
Pitch Deck Template for startupsMalcolm Lewis
 

Andere mochten auch (8)

The World Cancer Research Fund International Continuous Update Project (CUP):...
The World Cancer Research Fund International Continuous Update Project (CUP):...The World Cancer Research Fund International Continuous Update Project (CUP):...
The World Cancer Research Fund International Continuous Update Project (CUP):...
 
TravConnect Technology Day 2015 - Niek Stevens - Sue Amsterdam
TravConnect Technology Day 2015 - Niek Stevens - Sue AmsterdamTravConnect Technology Day 2015 - Niek Stevens - Sue Amsterdam
TravConnect Technology Day 2015 - Niek Stevens - Sue Amsterdam
 
How to Rock your Next Pitch Deck
How to Rock your Next Pitch DeckHow to Rock your Next Pitch Deck
How to Rock your Next Pitch Deck
 
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015
A VC dialogue on Venture Capital, US Embassy Presentation Feb 2015
 
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...
Funding Your Startup 101 - M.A. Fashion Entrepreneurship & Innovation Lecture...
 
500’s Demo Day Batch 11 >> Slidebean
500’s Demo Day Batch 11 >> Slidebean 500’s Demo Day Batch 11 >> Slidebean
500’s Demo Day Batch 11 >> Slidebean
 
Pitch Deck Template for startups
Pitch Deck Template for startupsPitch Deck Template for startups
Pitch Deck Template for startups
 
Build a Better Entrepreneur Pitch Deck
Build a Better Entrepreneur Pitch DeckBuild a Better Entrepreneur Pitch Deck
Build a Better Entrepreneur Pitch Deck
 

Ähnlich wie Rest sdk

What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018Marco Parenzan
 
TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"BENTOSA
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.jsMichele Capra
 
Analizzatori di programmi in C
Analizzatori di programmi in CAnalizzatori di programmi in C
Analizzatori di programmi in CBoymix81
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...UltraUploader
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)STELITANO
 
Qt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiQt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiPaolo Sereno
 
Introduzione a jQuery
Introduzione a jQueryIntroduzione a jQuery
Introduzione a jQuerySandro Marcon
 
06 Android - lavorare in background
06 Android - lavorare in background06 Android - lavorare in background
06 Android - lavorare in backgroundspawn150
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)STELITANO
 
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...Presentazione: uno studio sull'efficacia di checker automatici per la moderni...
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...Idriss Riouak
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBStefano Dindo
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con ScalaFranco Lombardo
 

Ähnlich wie Rest sdk (20)

What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018
 
Corso c++
Corso c++Corso c++
Corso c++
 
TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"TypeScript, ovvero JavaScript che "non si rompe"
TypeScript, ovvero JavaScript che "non si rompe"
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
 
Analizzatori di programmi in C
Analizzatori di programmi in CAnalizzatori di programmi in C
Analizzatori di programmi in C
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)
 
Inferno Limbo Italian
Inferno Limbo ItalianInferno Limbo Italian
Inferno Limbo Italian
 
Qt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiQt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immagini
 
Introduzione a jQuery
Introduzione a jQueryIntroduzione a jQuery
Introduzione a jQuery
 
Pycon
PyconPycon
Pycon
 
06 Android - lavorare in background
06 Android - lavorare in background06 Android - lavorare in background
06 Android - lavorare in background
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)
 
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...Presentazione: uno studio sull'efficacia di checker automatici per la moderni...
Presentazione: uno studio sull'efficacia di checker automatici per la moderni...
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDB
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 
Devianze
DevianzeDevianze
Devianze
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13
 

Rest sdk

  • 1. www.italiancpp.org Italian C++ Conference 2016 14 Maggio, Milano REST e Websocket in C++ diventano semplici e produttivi con il REST SDK Raffaele Rialdi Twitter: @raffaeler Email: raffaeler@vevy.com Website: http://iamraf.net
  • 2. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community Chi sono … • Lavoro nella programmazione software dal 1987 •Senior Software Architect in Vevy Europe •Consulente in diversi ambiti (finanziario, automotive, racing, manufacturing, healthcare) • Specializzato sul mondo Microsoft •Ho iniziato con il DOS 1.0 … e ho seguito tutto ciò che è venuto dopo •Linguaggi preferiti: C++ e C# •Prediligo le tecnologie di "basso" livello e la «application security» •Microsoft MVP dall'anno 2003 • Trainer e speaker •Ho insegnato informatica per anni (e salutariamente continuo) •Partecipo a varie conferenze italiane e internazionali
  • 3. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community Cos'è Casablanca REST SDK? • Una libreria che semplifica l'accesso a servizi REST e comunicazioni Websocket •Provvede anche servizi base (in beta) per creare semplici HTTP Server • Si basa su alcuni «pillars» fondamentali: 1. Gestione asincrona basata sui Task 2. Utilizzo di C++ "moderno" (è nata al momento dello standard C++11) 3. Cross-platform (Windows Desktop/Store/Phone, Linux, Android, Mac, iOS) 4. Cerca di offrire tutti i «building blocks» indispensabili (Json, Uri, conversioni Unicode, OAuth, etc.)
  • 4. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community I problemi del cross-platform • In Windows, le stringhe sono wide (16 bit) •wchar_t, wstring, … • In Posix (Linux, Unix) le stringhe sono narrow (8 bit) •char, string, … •Il REST SDK definisce un tipo neutrale •Conversioni disponibili • to_string_t, to_utf8string, to_utf16string utility::string_t #ifdef _UTF16_STRINGS typedef wchar_t char_t ; typedef std::wstring string_t; #define _XPLATSTR(x) L ## x typedef std::wostringstream ostringstream_t; typedef std::wofstream ofstream_t; typedef std::wostream ostream_t; typedef std::wistream istream_t; typedef std::wifstream ifstream_t; typedef std::wistringstream istringstream_t; typedef std::wstringstream stringstream_t; #define ucout std::wcout #define ucin std::wcin #define ucerr std::wcerr #else ... basic_types.h U("Hello, world") std::string ansiRaf("raffaele"); string_t raf_t(to_string_t(ansiRaf)); std::string(begin(raf_t), end(raf_t));
  • 5. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community PPL in una slide • Dimenticate i thread, pensate a task • Motivazioni: cross-platform, scalabilità, migliore schedulazione, codice più pulito, richiesto nelle applicazioni mobile • Ok, da domani li uso … ma che problemi ci sono? • Le STL sono sincrone, co-routines non fanno parte dello standard, i «futures» hanno diverse lacune • Arrivano le «Parallel Pattern Library» in soccorso • creare un task • scrivere una continuation • continuation con co_await • usare i task_completion • Un task setta il risultato • L'altro task è un attesa del risultato #include <ppl.h> using namespace concurrency; return create_task([] () {}); SumAsync(10, 20).then([=](int sum) { Process(sum); }; int result = co_await SumAsync(10, 20); Process(result); task_completion_event<bool> quit; quit->set(true); bool result = co_await pplx::task<bool>(quit);
  • 6. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community concurrency::stream cheat sheet basic_istream<> stdio_istream<> async_iostream<> basic_iostream<> std concurrency::streams namespaces concurrency::streams::details streambuf<> basic_streambuf<> container_buffer<> producer_consumer_ buffer<> rawptr_buffer<> basic_ostream<> stdio_ostream<> async_ostream<> basic_ostream<> async_istream<> basic_istream<> astreambuf.h interopstream.h streams.h containerstream.h bytestream (factory) containerstream.h container_stream<> (factory) containerstream.h producerconsumerstream.h rawptrstream.h rawptr_stream (factory) rawptrstream.h interopstream.h interopstream.h astreambuf.h streams.h interopstream.h interopstream.h
  • 7. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community typedefs definiti dal REST SDK typedef container_stream<std::basic_string<char>> stringstream; typedef stringstream::buffer_type stringstreambuf; typedef container_stream<utility::string_t> wstringstream; typedef wstringstream::buffer_type wstringstreambuf; typedef file_stream<uint8_t> fstream; typedef basic_ostream<uint8_t> ostream; typedef basic_istream<uint8_t> istream; typedef basic_ostream<utf16char> wostream; typedef basic_istream<utf16char> wistream;
  • 8. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community File streams – leggere un file di testo file_buffer<> file_stream<> (factory) filestream.h std concurrency::streams namespaces concurrency::streams::details std::string Test1(const string_t& filename) { auto istr = slx::fstream::open_istream(filename, std::ios::in).get(); slx::stringstreambuf strbuf; auto size = istr.read_to_end(strbuf).get(); istr.close(); string content = strbuf.collection(); cout << content.c_str(); return content; } task<std::string> Test1Async2(const string_t& filename) { auto istr = co_await slx::fstream::open_istream(filename, std::ios::in); slx::stringstreambuf strbuf; auto size = co_await istr.read_to_end(strbuf); istr.close(); string content = strbuf.collection(); cout << content.c_str(); return content; } Nota: Al momento co_await funziona solo se viene aggiunto /await alla riga di comando del compilatore
  • 9. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community File streams – copiare un file file_buffer<> file_stream<> (factory) filestream.h std concurrency::streams namespaces concurrency::streams::details void Test3(const string_t& source, const string_t& target) { auto istr = slx::fstream::open_istream(source, std::ios::in).get(); auto ostr = slx::fstream::open_ostream(target, std::ios::out).get(); slx::producer_consumer_buffer<char> buffer; int size = 110; // dimensione del blocco da copiare while (auto ilen = istr.read(buffer, size).get()) { auto olen = ostr.write(buffer, ilen).get(); } istr.close(); ostr.close(); } co_await co_await co_await co_await Nota: Al momento co_await funziona solo se viene aggiunto /await alla riga di comando del compilatore
  • 10. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community I building block di rete • Le tre classi principali sono: •http_client: astrazione su tre librerie • boost::asio per il mondo *nix • WinHttp per Windows Desktop • WinRT per il Windows Store •http_listener (beta): astrazione su: • boost::asio per il mondo *nix • Http.sys per il mondo Windows Desktop • WinRT vieta l'uso di listener nelle App (security!) •websocket_client: astrazione su: • Websocket++ per tutti gli OS tranne … • WinRT offre il suo supporto nativo Boost::Asio WinHttp WinRT http_client Boost::Asio Http.Sys http_listener WebsocketPP WinRT websocket_client
  • 11. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community Features vs Sistema Operativo Windows Desktop Windows Store WP 8 WP 8.1 WP 8.1 Silverlight Windows XP Linux (Ubuntu) Mac OS X iOS Android Programming with Tasks JSON Asynchronous Streams URIs HTTP Client HTTP Listener (Beta) (Beta) (Beta) (Beta) (Beta) WebSocket Client OAuth Client (Beta) (Beta) (Beta, OAuth2 only) (Beta, OAuth2 only) (Beta, OAuth2 only) (Beta, OAuth2 only) (Beta) (Beta) (Beta) (Beta)
  • 12. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community Leggere/scrivere JSON #include "cpprestjson.h" json::value root2(100); auto root6 = json::value::string(U("hello, world")); vector<pair<string_t, json::value>> props ... auto root2 = json::value::object(props); Creare un intero: Creare una stringa: Creare un oggetto: using namespace web; using namespace utility; using namespace utility::conversions; auto jsonText = U("[ "Book", "Pencil" ]"); auto json = json::value::parse(jsonText); Deserializzazione: void print(const json::value& val) { string_t text = val.serialize(); std::string utf8 = to_utf8string(text); cout << utf8.c_str() << endl; } Serializzazione:
  • 13. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community tip: deserializzare in un boost::variant 1. 2. definire un tipo "metamorfico" 3. ciclare le proprietà del json::object e deserializzare ogni valore in un "universal" 4. boost::variant è "iostream" friendly typedef boost::variant<bool, double, int, std::string> universal; #include "boostvariantvariant.hpp" if (val.is_string()) { auto stringt = val.as_string(); return universal(string(begin(stringt), end(stringt))); } if (val.is_boolean()) return universal(val.as_bool()); if (val.is_double()) return universal(val.as_double()); ...
  • 14. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community http_client in action 1. Costruire del client 2. Costruire una request 3. Aggiungere gli header 4. Aggiungere il body (POST) 5. Eseguire la chiamata 6. Controllare http status 7. Leggere il contenuto http_client client(_address); http_request request(methods::POST); request.headers().add( header_names::user_agent, U("IAmRaf agent")); request.set_body(body); auto resp = co_await client.request(request); http_response if (response.status_code() == status_codes::OK) auto json = co_await resp.extract_json();
  • 15. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community http_listener (beta) 1. Dichiarare uno smart ptr 2. Creare il listener 3. Binding per ogni verb 4. Iniziare la Listen sulla rete unique_ptr<http_listener> _listener; _listener = make_unique<http_listener>(address); _listener->support(methods::GET, std::bind(&Listener::handle_get, this, std::placeholders::_1)); co_await _listener->open(); #include "cppresthttp_listener.h"
  • 16. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community websocket_client 1. Creare il client 2. Aprire la connessione 3. Creare un messaggio (out) 4. Impostare il contenuto 5. Spedire il messaggio 6. Ricevere la risposta 7. Leggere il body 8. Leggere il body type 9. Leggere il contenuto co_await client->connect(U("ws://server/..."); client = std::make_unique<websocket_client>(); websocket_outgoing_message message; message.set_utf8_message("hello, world"); websocket_incoming_message message = co_await client->receive(); client->send(message); istream body = message.body(); websocket_message_type messageType = message.message_type(); auto text = co_await message.extract_string(); RFC 6455
  • 17. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community tip: subprotocollo e headers Websockets • Il protocollo Websocket inizia con un handshake HTTP • Segue una notifica « 101 – Upgrade » • E una negoziazione di un "subprotocol" definito a livello applicativo Ecco i passi per poter aggiungere headers e subprotocollo • Create the options • Add the sub-protocol • Add headers websocket_client_config config; config.add_subprotocol(U("subprotocol-raf")); config.headers().add(U("X-Raf"), to_string_t("C++ Native Client")); RFC 6455
  • 18. Italian C++ Conference 2016 – Un evento dell’Italian C++ Community Domande? Raffaele Rialdi Twitter: @raffaeler Email: raffaeler@vevy.com