Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
PHIL @LEGGETTER
Head of Developer Relations
2 / 121
@leggetter
3 / 121
@leggetter
What we'll cover
1. Why Real-Time?
2. Common Real-Time Use Cases
3. What are your options?
How do you choose?
.NET example...
When do we need Realtime?
5 / 121
@leggetter
WCaaS
6 / 121
@leggetter
WCaaS
Data: Is there a timely nature to the data?
6 / 121
@leggetter
7 / 121
@leggetter
User Experience: Is there a timely nature to the
experience?
7 / 121
@leggetter
Realtime is required when there's a Need or
Demand for:
Up to date information
Interaction to maintain engagement (UX)
8 /...
These aren't new Needs or Demands
But...
9 / 121
@leggetter
These aren't new Needs or Demands
But...
The Internet
9 / 121
@leggetter
Internet
“a global computer network providing a variety
of information and communication facilities,
consisting of interco...
11 / 121
@leggetter
12 / 121
@leggetter
13 / 121
@leggetter
HTTP was better. But many wanted more.
14 / 121
@leggetter
15 / 121
@leggetter
16 / 121
@leggetter
17 / 121
@leggetter
HTTP + Browsers were restrictive
HTTP - request/response paradigm
Keeping persistent HTTP connections alive
No cross-brows...
HTTP + Browsers were restrictive
HTTP - request/response paradigm
Keeping persistent HTTP connections alive
No cross-brows...
Then Real-Time Went Mainstream
19 / 121
@leggetter
Social
20 / 121
@leggetter
Technology Advancements
Memory & CPU speed and cost
The Cloud
Browser standardisation & enhancements
Any client can use th...
22 / 121
@leggetter
MASSIVE Increase in Internet Usage
23 / 121
@leggetter
Internet Usage (per day)
200 billion emails
24 / 121
@leggetter
Internet Usage (per day)
200 billion emails
7 million blog posts written†
500 million tweets
30 billion WhatsApp messages
...
Internet Usage (per day)
200 billion emails
7 million blog posts written†
500 million tweets
30 billion WhatsApp messages
...
25 / 121
@leggetter
Common Real-Time Use Cases
26 / 121
@leggetter
Notifications & Activity Streams
27 / 121
@leggetter
Data Visualizations
28 / 121
@leggetter
29 / 121
Chat
@leggetter
30 / 121
@leggetter
Real-Time Location Tracking
31 / 121
@leggetter
Multi-User Collaboration
32 / 121
@leggetter
WebRTC Powered AV Chat
33 / 121
@leggetter
34 / 121
@leggetter
Users expect a real-time UX
34 / 121
@leggetter
Users expect a real-time UX
Without a real-time UX your app appears
broken
34 / 121
@leggetter
Real-time Web Apps & .NET
What are your options?
35 / 121
@leggetter
7 Factors to Consider
36 / 121
@leggetter
1. Should you keep on polling?
37 / 121
@leggetter
Polling Calculations
Scenario
1. Site average of 10,000 Users
38 / 121
@leggetter
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
38 / 121
@...
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
3. Request...
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
3. Request...
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
3. Request...
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
3. Request...
Polling Calculations
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, with a 10 second polling interval
3. Request...
Cache - clients keep polling
Push Proxy solutions
fanout.io
streamdata.io
Quick Win solutions
39 / 121
@leggetter
2. Use an existing solution
Don't reinvent the wheel
Unless you've a unique use case
40 / 121
@leggetter
Why use an existing solution?
Connection fallback/upgrade hacks still required
WebSocket: 91% of connections
HTTP fallback...
Why use an existing solution?
Connection fallback/upgrade hacks still required
WebSocket: 91% of connections
HTTP fallback...
Why use an existing solution?
Connection fallback/upgrade hacks still required
WebSocket: 91% of connections
HTTP fallback...
Why use an existing solution?
Connection fallback/upgrade hacks still required
WebSocket: 91% of connections
HTTP fallback...
Why use an existing solution?
Connection fallback/upgrade hacks still required
WebSocket: 91% of connections
HTTP fallback...
42 / 121
@leggetter
j.mp/realtime-tech-guide
42 / 121
@leggetter
3. Use languages you're comfortable
with
43 / 121
@leggetter
3. Use languages you're comfortable
with
43 / 121
@leggetter
Solutions by language
PHP: Ratchet, dNode-php
Java: Netty, Jetty
JavaScript (Node.JS): Faye, Socket.IO (Engine.IO), Primus...
4. Mobile Friendly?
45 / 121
@leggetter
Mobile Friendly
Only some have mobile libraries
46 / 121
@leggetter
Mobile Friendly
Only some have mobile libraries
How much data are you sending?
46 / 121
@leggetter
Mobile Friendly
Only some have mobile libraries
How much data are you sending?
SSL required on 3/4G networks
46 / 121
@leg...
5. Application/Solution
Communication Patterns
47 / 121
@leggetter
5. Application/Solution
Communication Patterns
How does the client/server & client/client communicate
47 / 121
@leggetter
Simple Messaging
48 / 121
@leggetter
0:00 49 / 121
@leggetter
Internet ^5 Machine
0:00 49 / 121
@leggetter
Internet ^5 Machine
Simple Messaging
// client
var ws = new WebSocket('wss://localhost/');
50 / 121
@leggetter
Simple Messaging
// client
var ws = new WebSocket('wss://localhost/');
ws.onmessage = function(evt) {
var data = JSON.pars...
Simple Messaging
// client
var ws = new WebSocket('wss://localhost/');
ws.onmessage = function(evt) {
var data = JSON.pars...
Simple Messaging
// client
var ws = new WebSocket('wss://localhost/');
ws.onmessage = function(evt) {
var data = JSON.pars...
Simple Messaging
// client
var ws = new WebSocket('wss://localhost/');
ws.onmessage = function(evt) {
var data = JSON.pars...
Simple Messaging
using Nexmo.Api;
// SMS
var results = SMS.Send(new SMS.SMSRequest
{
from = "15555551212",
to = "177755512...
PubSub
52 / 121
@leggetter
53 / 121
@leggetter
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
54 / 121
@leggetter
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
client.subscribe('/leggetter-updates', functi...
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
client.subscribe('/leggetter-updates', functi...
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
client.subscribe('/leggetter-updates', functi...
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
client.subscribe('/leggetter-updates', functi...
PubSub
// client
var client = new Faye.Client('http://localhost:8000/faye');
client.subscribe('/leggetter-updates', functi...
Evented PubSub
55 / 121
@leggetter
Evented PubSub
// client
var updates = io('/leggetter-updates');
56 / 121
@leggetter
Evented PubSub
// client
var updates = io('/leggetter-updates');
updates.on('created', function (data) {
// Add activity t...
Evented PubSub
// client
var updates = io('/leggetter-updates');
updates.on('created', function (data) {
// Add activity t...
Evented PubSub
// client
var updates = io('/leggetter-updates');
updates.on('created', function (data) {
// Add activity t...
Evented PubSub
// client
var updates = io('/leggetter-updates');
updates.on('created', function (data) {
// Add activity t...
Evented PubSub
// client
var updates = io('/leggetter-updates');
updates.on('created', function (data) {
// Add activity t...
PubSub vs. Evented PubSub
57 / 121
@leggetter
58 / 121
@leggetter
59 / 121
@leggetter
PubSub
client.subscribe('devexp-channel', function(data) {
if(data.eventType === 'chat-message') {
addMessage(data.message...
PubSub
client.subscribe('devexp-channel', function(data) {
if(data.eventType === 'chat-message') {
addMessage(data.message...
PubSub
client.subscribe('devexp-channel', function(data) {
if(data.eventType === 'chat-message') {
addMessage(data.message...
PubSub
client.subscribe('devexp-channel', function(data) {
if(data.eventType === 'chat-message') {
addMessage(data.message...
DataSync
61 / 121
@leggetter
62 / 121
@leggetter
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
63 / 121
@leggetter
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
ref.on('child_added', function(childS...
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
ref.on('child_added', function(childS...
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
ref.on('child_added', function(childS...
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
ref.on('child_added', function(childS...
Data Sync
// client
var ref = new Firebase("https://app.firebaseio.com/doc1/lines");
ref.on('child_added', function(childS...
RMI (aka RPC)
64 / 121
@leggetter
65 / 121
@leggetter
RMI
// client
var chat = $.connection.chatHub;
66 / 121
@leggetter
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
RMI
// client
var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {
// handle message...
67 / 121
@leggetter
68 / 121
@leggetter
69 / 121
@leggetter
70 / 121
@leggetter
71 / 121
@leggetter
6. Deployment & Architecture
Considerations
72 / 121
@leggetter
Code
https://github.com/leggetter/realtime-dotnet-examples
Short link: http://j.mp/rt-dotnet-ex
73 / 121
@leggetter
Self Hosted (Tightly Coupled) 74 / 121
@leggetter
.NET Self-Hosted Real-Time options
SignalR
XSockets
75 / 121
@leggetter
76 / 121
@leggetter
Self-Hosted Demo 1: ASP.NET + SignalR (Tightly Coupled)
76 / 121
@leggetter
What we'll look at:
ReferencesMicrosoft.AspNet.SignalR.*
Scriptsjquery.signalR*.js
App_StartSignalRStartup.cs
ControllersH...
Pros
.NET
Simple integration
MS Supported
jQuery Dependency
Cons
Tightly coupled
RMI only
Self-Scaling
Scaling (realtime +...
79 / 121
@leggetter
Self-Hosted Demo 2: ASP.NET + XSockets (Tightly Coupled)
79 / 121
@leggetter
What we'll look at:
ReferencesXSockets.*
App_StartXSocketsStartup.cs
ControllersHomeController.cs
XSocketsChatController.c...
Pros
.NET
Simple integration
Communication patterns
PubSub/Evented
RMI
Licensed
Cons
Tightly coupled
Self-Scaling
Scaling ...
Self-Hosted: .NET + Message Queue (Loosely Coupled)
82 / 121
@leggetter
83 / 121
@leggetter
Pros
.NET
Maps well to PubSub
Loosely coupled
Could use another runtime
Cons
How does it fit with RMI/SignalR?
Multiple co...
85 / 121
@leggetter
Self-Hosted: ASP.NET + Faye
(Loosely Coupled)
85 / 121
@leggetter
Pros
PubSub
Connection fallback
Redis Queue support
Simple integration
Cons
Not .NET(?)
You need to scale
Self-Hosted + Fa...
.NET Hosted Real-Time options
Ably
Firebase
Fanout
PubNub
Pusher
Realtime.co
Syncano
87 / 121
@leggetter
88 / 121
@leggetter
Hosted Demo: Pusher
88 / 121
@leggetter
What we'll look at:
ReferencesPusherServer
ControllersHomeController.cs
ViewsHomePusher.cshtml
ScriptchatPusherChat.js
Pus...
Pros
Simple & powerful
Instantly scalable
Managed & dedicated
Direct integration. No overhead.
Cons
3rd party reliance
Diff...
Why use a hosted service?
Scenario
1. Site average of 10,000 Users
91 / 121
@leggetter
Why use a hosted service?
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, no polling
91 / 121
@leggetter
Why use a hosted service?
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, no polling
3. Requests from pages load ...
Why use a hosted service?
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, no polling
3. Requests from pages load ...
Why use a hosted service?
Scenario
1. Site average of 10,000 Users
2. Over 1 Hour, no polling
3. Requests from pages load ...
7. Self-Hosted v Hosted
"Build vs. Buy"
92 / 121
@leggetter
Build vs. Buy - Costs
baremetrics.com/calculator
93 / 121
@leggetter
How do you choose?
7 Realtime Framework Considerations
1. Should you keep on polling?
2. Use an Existing Solution
3. Use a...
Future
95 / 121
@leggetter
Network Infrastructure & Protocols
Reliability
Speed
Beyond HTTP
HTTP2
96 / 121
@leggetter
Bayeux
DDP
dNode
EPCP
GRIP
gRPC
MQTT
Pusher Protocol
STOMP
SignalR Protocol
WAMP (Web App Messaging Protocol)
XMPP (variou...
98 / 121
@leggetter
Firebase
GitHub
Iron.io
MailChimp
MailJet
PagerDuty
Nexmo
SendGrid
Real-Time APIs
99 / 121
@leggetter
100 / 121
@leggetter
More "Things"!
101 / 121
@leggetter
The Physical Web
102 / 121
@leggetter
IoT, Apps & Developers
103 / 121
@leggetter
A thing can be anything
104 / 121
@leggetter
A thing can be anything
Sensors
Appliances
Vehicles
Smart Phones
Devices (Arduino, Electric Imp, Raspberry Pi etc.)
104 / ...
A thing can be anything
Sensors
Appliances
Vehicles
Smart Phones
Devices (Arduino, Electric Imp, Raspberry Pi etc.)
Server...
The Majority of code we'll write will still be
for "Apps"
Configuring
Monitoring
Interacting
App Logic
105 / 121
@leggetter
Real-Time Use Case Evolution
Notifications & Signalling
Activity Streams
Data Viz & Polls
Chat
Collaboration
Multiplayer G...
Notifications/Activity Streams -> Actions
107 / 121
@leggetter
The end of apps as we know it - Intercom
Subscriptions
108 / 121
@leggetter
Personalised Event Streams
109 / 121
@leggetter
Unified UIs
110 / 121
@leggetter
Chat & Bots for Everything and the rise of the .ai domain 111 / 121
@leggetter
600M MAUs
10M integrations
app-within-an-app model
taxi, order food, tickets, games etc.
WeChat
112 / 121
@leggetter
Chat Integrations
113 / 121
@leggetter
Siri
Google Now
Microso Cortana
Facebook M
Chat "Virtual Assistants"
114 / 121
@leggetter
115 / 121
@leggetter
Chat has evolved. Chat is now a platform!
116 / 121
@leggetter
Multi-Device Experiences
117 / 121
@leggetter
Ben Foxall - A conceptual future for the multi-device web (FutureJS 2014)
118 / 121
@leggetter
You need Real-Time!
There are lots of options.
Make the choice that's right for you.
I hope this helps!
119 / 121
@leggett...
Resources
Real-time Tech Guide
github.com/leggetter/realtime-dotnet-examples
Tools, Tips and Techniques for Developing Rea...
Real-time Web Apps & .NET
What are your options?
Questions?
PHIL @LEGGETTER
Head of Developer Relations
121 / 121
@leggett...
Real-Time Web Apps & .NET - What are your options?
Nächste SlideShare
Wird geladen in …5
×

Real-Time Web Apps & .NET - What are your options?

1.057 Aufrufe

Veröffentlicht am

Real-time is becoming the life blood of applications. Facebook, Twitter, Uber, Google Docs and many more apps have increased user expectation to demand real-time features. Features such as notifications, activity streams, real-time data visualisations, chat or collaborative experiences instantly keep users up to date and enable them to work much more effectively. So, how do you build these sorts of features with .NET?

In this session, Phil will cover the benefits of moving away from polling to push, the options you have with .NET web application to do this and when adding real-time features to your apps, and the pros and cons of each to help choose which is the best solution for you.

Veröffentlicht in: Software
  • Als Erste(r) kommentieren

Real-Time Web Apps & .NET - What are your options?

  1. 1. PHIL @LEGGETTER Head of Developer Relations 2 / 121 @leggetter
  2. 2. 3 / 121 @leggetter
  3. 3. What we'll cover 1. Why Real-Time? 2. Common Real-Time Use Cases 3. What are your options? How do you choose? .NET examples Pros & Cons 4. The Future of Real-Time 4 / 121 @leggetter
  4. 4. When do we need Realtime? 5 / 121 @leggetter
  5. 5. WCaaS 6 / 121 @leggetter
  6. 6. WCaaS Data: Is there a timely nature to the data? 6 / 121 @leggetter
  7. 7. 7 / 121 @leggetter
  8. 8. User Experience: Is there a timely nature to the experience? 7 / 121 @leggetter
  9. 9. Realtime is required when there's a Need or Demand for: Up to date information Interaction to maintain engagement (UX) 8 / 121 @leggetter
  10. 10. These aren't new Needs or Demands But... 9 / 121 @leggetter
  11. 11. These aren't new Needs or Demands But... The Internet 9 / 121 @leggetter
  12. 12. Internet “a global computer network providing a variety of information and communication facilities, consisting of interconnected networks using standardized communication protocols. 10 / 121 @leggetter
  13. 13. 11 / 121 @leggetter
  14. 14. 12 / 121 @leggetter
  15. 15. 13 / 121 @leggetter
  16. 16. HTTP was better. But many wanted more. 14 / 121 @leggetter
  17. 17. 15 / 121 @leggetter
  18. 18. 16 / 121 @leggetter
  19. 19. 17 / 121 @leggetter
  20. 20. HTTP + Browsers were restrictive HTTP - request/response paradigm Keeping persistent HTTP connections alive No cross-browser XMLHttpRequest 2 connection limit No browser cross origin support General cross browser incompatibilities 18 / 121 @leggetter
  21. 21. HTTP + Browsers were restrictive HTTP - request/response paradigm Keeping persistent HTTP connections alive No cross-browser XMLHttpRequest 2 connection limit No browser cross origin support General cross browser incompatibilities So we HACKED! Java Applets, Flash, HTTP Hacks 18 / 121 @leggetter
  22. 22. Then Real-Time Went Mainstream 19 / 121 @leggetter
  23. 23. Social 20 / 121 @leggetter
  24. 24. Technology Advancements Memory & CPU speed and cost The Cloud Browser standardisation & enhancements Any client can use the standards 21 / 121 @leggetter
  25. 25. 22 / 121 @leggetter
  26. 26. MASSIVE Increase in Internet Usage 23 / 121 @leggetter
  27. 27. Internet Usage (per day) 200 billion emails 24 / 121 @leggetter
  28. 28. Internet Usage (per day) 200 billion emails 7 million blog posts written† 500 million tweets 30 billion WhatsApp messages 24 / 121 @leggetter
  29. 29. Internet Usage (per day) 200 billion emails 7 million blog posts written† 500 million tweets 30 billion WhatsApp messages 55 million Facebook status updates 5 billion Google+ +1's 60 million Instagram photos posted 2 billion minutes spent on Skype 33 million hours of Netflix watched 750 million hours of YouTube watched 24 / 121 @leggetter
  30. 30. 25 / 121 @leggetter
  31. 31. Common Real-Time Use Cases 26 / 121 @leggetter
  32. 32. Notifications & Activity Streams 27 / 121 @leggetter
  33. 33. Data Visualizations 28 / 121 @leggetter
  34. 34. 29 / 121 Chat @leggetter
  35. 35. 30 / 121 @leggetter
  36. 36. Real-Time Location Tracking 31 / 121 @leggetter
  37. 37. Multi-User Collaboration 32 / 121 @leggetter
  38. 38. WebRTC Powered AV Chat 33 / 121 @leggetter
  39. 39. 34 / 121 @leggetter
  40. 40. Users expect a real-time UX 34 / 121 @leggetter
  41. 41. Users expect a real-time UX Without a real-time UX your app appears broken 34 / 121 @leggetter
  42. 42. Real-time Web Apps & .NET What are your options? 35 / 121 @leggetter
  43. 43. 7 Factors to Consider 36 / 121 @leggetter
  44. 44. 1. Should you keep on polling? 37 / 121 @leggetter
  45. 45. Polling Calculations Scenario 1. Site average of 10,000 Users 38 / 121 @leggetter
  46. 46. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 38 / 121 @leggetter
  47. 47. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 38 / 121 @leggetter
  48. 48. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. Poll requests per user/minute = (60 / 10) = 6 38 / 121 @leggetter
  49. 49. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. Poll requests per user/minute = (60 / 10) = 6 5. Poll requests per user/hour = (6 * 60) = 360 38 / 121 @leggetter
  50. 50. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. Poll requests per user/minute = (60 / 10) = 6 5. Poll requests per user/hour = (6 * 60) = 360 6. Poll requests site wide per hour = (360 * 10,000) = 3,600,000 38 / 121 @leggetter
  51. 51. Polling Calculations Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, with a 10 second polling interval 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. Poll requests per user/minute = (60 / 10) = 6 5. Poll requests per user/hour = (6 * 60) = 360 6. Poll requests site wide per hour = (360 * 10,000) = 3,600,000 With polling the site would need to handle 3.65 Million requests per hour Or 50k HTTP requests + maintain 10k persistent connections? 38 / 121 @leggetter
  52. 52. Cache - clients keep polling Push Proxy solutions fanout.io streamdata.io Quick Win solutions 39 / 121 @leggetter
  53. 53. 2. Use an existing solution Don't reinvent the wheel Unless you've a unique use case 40 / 121 @leggetter
  54. 54. Why use an existing solution? Connection fallback/upgrade hacks still required WebSocket: 91% of connections HTTP fallback: 9% of connections 41 / 121 @leggetter
  55. 55. Why use an existing solution? Connection fallback/upgrade hacks still required WebSocket: 91% of connections HTTP fallback: 9% of connections Support/Community 41 / 121 @leggetter
  56. 56. Why use an existing solution? Connection fallback/upgrade hacks still required WebSocket: 91% of connections HTTP fallback: 9% of connections Support/Community Maintenance 41 / 121 @leggetter
  57. 57. Why use an existing solution? Connection fallback/upgrade hacks still required WebSocket: 91% of connections HTTP fallback: 9% of connections Support/Community Maintenance Future features 41 / 121 @leggetter
  58. 58. Why use an existing solution? Connection fallback/upgrade hacks still required WebSocket: 91% of connections HTTP fallback: 9% of connections Support/Community Maintenance Future features Scaling 41 / 121 @leggetter
  59. 59. 42 / 121 @leggetter
  60. 60. j.mp/realtime-tech-guide 42 / 121 @leggetter
  61. 61. 3. Use languages you're comfortable with 43 / 121 @leggetter
  62. 62. 3. Use languages you're comfortable with 43 / 121 @leggetter
  63. 63. Solutions by language PHP: Ratchet, dNode-php Java: Netty, Jetty JavaScript (Node.JS): Faye, Socket.IO (Engine.IO), Primus.io .NET (C#): SignalR, XSockets Python: Lots of options built on Tornado Ruby: em-websocket, Faye Language agnostic: most hosted services 44 / 121 @leggetter
  64. 64. 4. Mobile Friendly? 45 / 121 @leggetter
  65. 65. Mobile Friendly Only some have mobile libraries 46 / 121 @leggetter
  66. 66. Mobile Friendly Only some have mobile libraries How much data are you sending? 46 / 121 @leggetter
  67. 67. Mobile Friendly Only some have mobile libraries How much data are you sending? SSL required on 3/4G networks 46 / 121 @leggetter
  68. 68. 5. Application/Solution Communication Patterns 47 / 121 @leggetter
  69. 69. 5. Application/Solution Communication Patterns How does the client/server & client/client communicate 47 / 121 @leggetter
  70. 70. Simple Messaging 48 / 121 @leggetter
  71. 71. 0:00 49 / 121 @leggetter Internet ^5 Machine
  72. 72. 0:00 49 / 121 @leggetter Internet ^5 Machine
  73. 73. Simple Messaging // client var ws = new WebSocket('wss://localhost/'); 50 / 121 @leggetter
  74. 74. Simple Messaging // client var ws = new WebSocket('wss://localhost/'); ws.onmessage = function(evt) { var data = JSON.parse(evt.data); 50 / 121 @leggetter
  75. 75. Simple Messaging // client var ws = new WebSocket('wss://localhost/'); ws.onmessage = function(evt) { var data = JSON.parse(evt.data); // ^5 performHighFive(); }; 50 / 121 @leggetter
  76. 76. Simple Messaging // client var ws = new WebSocket('wss://localhost/'); ws.onmessage = function(evt) { var data = JSON.parse(evt.data); // ^5 performHighFive(); }; // server server.on('connection', function(socket){ 50 / 121 @leggetter
  77. 77. Simple Messaging // client var ws = new WebSocket('wss://localhost/'); ws.onmessage = function(evt) { var data = JSON.parse(evt.data); // ^5 performHighFive(); }; // server server.on('connection', function(socket){ socket.send(JSON.stringify({action: 'high-5'})); }); 50 / 121 @leggetter
  78. 78. Simple Messaging using Nexmo.Api; // SMS var results = SMS.Send(new SMS.SMSRequest { from = "15555551212", to = "17775551212", text = "this is a test" }); // Voice var result = Voice.TextToSpeech(new Voice.TextToSpeechCallCommand { to = "17775551212", from = "15555551212", text = "Hello from Nexmo" }); 51 / 121 @leggetter
  79. 79. PubSub 52 / 121 @leggetter
  80. 80. 53 / 121 @leggetter
  81. 81. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); 54 / 121 @leggetter
  82. 82. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); client.subscribe('/leggetter-updates', function(data) { 54 / 121 @leggetter
  83. 83. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); client.subscribe('/leggetter-updates', function(data) { console.log(data.text); }); 54 / 121 @leggetter
  84. 84. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); client.subscribe('/leggetter-updates', function(data) { console.log(data.text); }); client.subscribe('/leggetter-dm-notifications', function(data) { console.log(data.count); }); 54 / 121 @leggetter
  85. 85. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); client.subscribe('/leggetter-updates', function(data) { console.log(data.text); }); client.subscribe('/leggetter-dm-notifications', function(data) { console.log(data.count); }); // server server.publish('/leggetter-updates', {text: 'Hello DevWeek!'}); 54 / 121 @leggetter
  86. 86. PubSub // client var client = new Faye.Client('http://localhost:8000/faye'); client.subscribe('/leggetter-updates', function(data) { console.log(data.text); }); client.subscribe('/leggetter-dm-notifications', function(data) { console.log(data.count); }); // server server.publish('/leggetter-updates', {text: 'Hello DevWeek!'}); server.publish('/leggetter-dm-notifications', {count: 2}); 54 / 121 @leggetter
  87. 87. Evented PubSub 55 / 121 @leggetter
  88. 88. Evented PubSub // client var updates = io('/leggetter-updates'); 56 / 121 @leggetter
  89. 89. Evented PubSub // client var updates = io('/leggetter-updates'); updates.on('created', function (data) { // Add activity to UI }); 56 / 121 @leggetter
  90. 90. Evented PubSub // client var updates = io('/leggetter-updates'); updates.on('created', function (data) { // Add activity to UI }); updates.on('updated', function(data) { // Update activity }); updates.on('deleted', function(data) { // Remove activity }); 56 / 121 @leggetter
  91. 91. Evented PubSub // client var updates = io('/leggetter-updates'); updates.on('created', function (data) { // Add activity to UI }); updates.on('updated', function(data) { // Update activity }); updates.on('deleted', function(data) { // Remove activity }); // server var io = require('socket.io')(); var updates = io.of('/leggetter-updates'); 56 / 121 @leggetter
  92. 92. Evented PubSub // client var updates = io('/leggetter-updates'); updates.on('created', function (data) { // Add activity to UI }); updates.on('updated', function(data) { // Update activity }); updates.on('deleted', function(data) { // Remove activity }); // server var io = require('socket.io')(); var updates = io.of('/leggetter-updates'); updates.emit('created', {text: 'PubSub Rocks!', id: 1}); 56 / 121 @leggetter
  93. 93. Evented PubSub // client var updates = io('/leggetter-updates'); updates.on('created', function (data) { // Add activity to UI }); updates.on('updated', function(data) { // Update activity }); updates.on('deleted', function(data) { // Remove activity }); // server var io = require('socket.io')(); var updates = io.of('/leggetter-updates'); updates.emit('created', {text: 'PubSub Rocks!', id: 1}); updates.emit('updated', {text: 'Evented PubSub Rocks!', id: 1}); updates.emit('deleted', {id: 1}); 56 / 121 @leggetter
  94. 94. PubSub vs. Evented PubSub 57 / 121 @leggetter
  95. 95. 58 / 121 @leggetter
  96. 96. 59 / 121 @leggetter
  97. 97. PubSub client.subscribe('devexp-channel', function(data) { if(data.eventType === 'chat-message') { addMessage(data.message); } 60 / 121 @leggetter
  98. 98. PubSub client.subscribe('devexp-channel', function(data) { if(data.eventType === 'chat-message') { addMessage(data.message); } else if(data.eventType === 'channel-purposed-changed') { updateRoomTitle(data.purpose); } else if(/* and so on */) { } }) 60 / 121 @leggetter
  99. 99. PubSub client.subscribe('devexp-channel', function(data) { if(data.eventType === 'chat-message') { addMessage(data.message); } else if(data.eventType === 'channel-purposed-changed') { updateRoomTitle(data.purpose); } else if(/* and so on */) { } }) Evented PubSub var devexp = io('/devexp-channel'); devexp.on('chat-message', addMessage); devexp.on('channel-purposed-changed', updateChannelPurpose); 60 / 121 @leggetter
  100. 100. PubSub client.subscribe('devexp-channel', function(data) { if(data.eventType === 'chat-message') { addMessage(data.message); } else if(data.eventType === 'channel-purposed-changed') { updateRoomTitle(data.purpose); } else if(/* and so on */) { } }) Evented PubSub var devexp = io('/devexp-channel'); devexp.on('chat-message', addMessage); devexp.on('channel-purposed-changed', updateChannelPurpose); devexp.on('current-topic-changed', updateChannelTopic); devexp.on('user-online', userOnline); devexp.on('user-offline', userOffline); 60 / 121 @leggetter
  101. 101. DataSync 61 / 121 @leggetter
  102. 102. 62 / 121 @leggetter
  103. 103. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); 63 / 121 @leggetter
  104. 104. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); ref.on('child_added', function(childSnapshot, prevChildKey) { // code to handle new child. }); 63 / 121 @leggetter
  105. 105. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); ref.on('child_added', function(childSnapshot, prevChildKey) { // code to handle new child. }); ref.on('child_changed', function(childSnapshot, prevChildKey) { // code to handle child data changes. }); 63 / 121 @leggetter
  106. 106. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); ref.on('child_added', function(childSnapshot, prevChildKey) { // code to handle new child. }); ref.on('child_changed', function(childSnapshot, prevChildKey) { // code to handle child data changes. }); ref.on('child_removed', function(oldChildSnapshot) { // code to handle child removal. }); 63 / 121 @leggetter
  107. 107. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); ref.on('child_added', function(childSnapshot, prevChildKey) { // code to handle new child. }); ref.on('child_changed', function(childSnapshot, prevChildKey) { // code to handle child data changes. }); ref.on('child_removed', function(oldChildSnapshot) { // code to handle child removal. }); ref.push({ 'editor_id': 'leggetter', 'text': 'Nexmo Rocks!' }); 63 / 121 @leggetter
  108. 108. Data Sync // client var ref = new Firebase("https://app.firebaseio.com/doc1/lines"); ref.on('child_added', function(childSnapshot, prevChildKey) { // code to handle new child. }); ref.on('child_changed', function(childSnapshot, prevChildKey) { // code to handle child data changes. }); ref.on('child_removed', function(oldChildSnapshot) { // code to handle child removal. }); ref.push({ 'editor_id': 'leggetter', 'text': 'Nexmo Rocks!' }); Framework handles updates to other clients 63 / 121 @leggetter
  109. 109. RMI (aka RPC) 64 / 121 @leggetter
  110. 110. 65 / 121 @leggetter
  111. 111. RMI // client var chat = $.connection.chatHub; 66 / 121 @leggetter
  112. 112. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; 66 / 121 @leggetter
  113. 113. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; chat.server.send( 'me', 'hello world' ); 66 / 121 @leggetter
  114. 114. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; chat.server.send( 'me', 'hello world' ); $.connection.hub.start(); // async 66 / 121 @leggetter
  115. 115. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; chat.server.send( 'me', 'hello world' ); $.connection.hub.start(); // async // server public class ChatHub : Hub { 66 / 121 @leggetter
  116. 116. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; chat.server.send( 'me', 'hello world' ); $.connection.hub.start(); // async // server public class ChatHub : Hub { public void Send(string name, string message) { 66 / 121 @leggetter
  117. 117. RMI // client var chat = $.connection.chatHub; chat.client.broadcastMessage = function (name, message) { // handle message }; chat.server.send( 'me', 'hello world' ); $.connection.hub.start(); // async // server public class ChatHub : Hub { public void Send(string name, string message) { // Call the broadcastMessage method to update clients. Clients.All.broadcastMessage(name, message); } } 66 / 121 @leggetter
  118. 118. 67 / 121 @leggetter
  119. 119. 68 / 121 @leggetter
  120. 120. 69 / 121 @leggetter
  121. 121. 70 / 121 @leggetter
  122. 122. 71 / 121 @leggetter
  123. 123. 6. Deployment & Architecture Considerations 72 / 121 @leggetter
  124. 124. Code https://github.com/leggetter/realtime-dotnet-examples Short link: http://j.mp/rt-dotnet-ex 73 / 121 @leggetter
  125. 125. Self Hosted (Tightly Coupled) 74 / 121 @leggetter
  126. 126. .NET Self-Hosted Real-Time options SignalR XSockets 75 / 121 @leggetter
  127. 127. 76 / 121 @leggetter
  128. 128. Self-Hosted Demo 1: ASP.NET + SignalR (Tightly Coupled) 76 / 121 @leggetter
  129. 129. What we'll look at: ReferencesMicrosoft.AspNet.SignalR.* Scriptsjquery.signalR*.js App_StartSignalRStartup.cs ControllersHomeController.cs HubsChatHub.cs ViewsHomeSignalR.cshtml ScriptchatSignalRChat.js 77 / 121 @leggetter
  130. 130. Pros .NET Simple integration MS Supported jQuery Dependency Cons Tightly coupled RMI only Self-Scaling Scaling (realtime + HTTP) Self-Hosted Demo 1: Pro & Cons 78 / 121 @leggetter
  131. 131. 79 / 121 @leggetter
  132. 132. Self-Hosted Demo 2: ASP.NET + XSockets (Tightly Coupled) 79 / 121 @leggetter
  133. 133. What we'll look at: ReferencesXSockets.* App_StartXSocketsStartup.cs ControllersHomeController.cs XSocketsChatController.cs ViewsHomeXSockets.cshtml ScriptsXSockets.latest.js ScriptchatXSocketsChat.cs 80 / 121 @leggetter
  134. 134. Pros .NET Simple integration Communication patterns PubSub/Evented RMI Licensed Cons Tightly coupled Self-Scaling Scaling (realtime + HTTP) Licensed Self-Hosted Demo 2: Pro & Cons 81 / 121 @leggetter
  135. 135. Self-Hosted: .NET + Message Queue (Loosely Coupled) 82 / 121 @leggetter
  136. 136. 83 / 121 @leggetter
  137. 137. Pros .NET Maps well to PubSub Loosely coupled Could use another runtime Cons How does it fit with RMI/SignalR? Multiple components Self-scaling Queue routing questions In: HTTP. Out: WebSocket Self-Hosted: .NET + Message Queue - Pro & Cons 84 / 121 @leggetter
  138. 138. 85 / 121 @leggetter
  139. 139. Self-Hosted: ASP.NET + Faye (Loosely Coupled) 85 / 121 @leggetter
  140. 140. Pros PubSub Connection fallback Redis Queue support Simple integration Cons Not .NET(?) You need to scale Self-Hosted + Faye: Pros & Cons 86 / 121 @leggetter
  141. 141. .NET Hosted Real-Time options Ably Firebase Fanout PubNub Pusher Realtime.co Syncano 87 / 121 @leggetter
  142. 142. 88 / 121 @leggetter
  143. 143. Hosted Demo: Pusher 88 / 121 @leggetter
  144. 144. What we'll look at: ReferencesPusherServer ControllersHomeController.cs ViewsHomePusher.cshtml ScriptchatPusherChat.js Pusher Debug Console 89 / 121 @leggetter
  145. 145. Pros Simple & powerful Instantly scalable Managed & dedicated Direct integration. No overhead. Cons 3rd party reliance Difficult to influence functionality Hosted - Pros & Cons 90 / 121 @leggetter
  146. 146. Why use a hosted service? Scenario 1. Site average of 10,000 Users 91 / 121 @leggetter
  147. 147. Why use a hosted service? Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, no polling 91 / 121 @leggetter
  148. 148. Why use a hosted service? Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, no polling 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 91 / 121 @leggetter
  149. 149. Why use a hosted service? Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, no polling 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. That's it! Total: 50,000 91 / 121 @leggetter
  150. 150. Why use a hosted service? Scenario 1. Site average of 10,000 Users 2. Over 1 Hour, no polling 3. Requests from pages load + HTML, CSS, JS, Images for 10k users = 50,000 4. That's it! Total: 50,000 Your servers handle 50k requests per hour instead of 3.6M You offload the polling or persistent connections to the service 91 / 121 @leggetter
  151. 151. 7. Self-Hosted v Hosted "Build vs. Buy" 92 / 121 @leggetter
  152. 152. Build vs. Buy - Costs baremetrics.com/calculator 93 / 121 @leggetter
  153. 153. How do you choose? 7 Realtime Framework Considerations 1. Should you keep on polling? 2. Use an Existing Solution 3. Use a language you're comfortable with 4. Do you need native mobile support? 5. Simple Messaging, PubSub/Evented, RMI or DataSync 6. Architectural considerations 7. Hosted v Self-Hosted (Build vs. Buy) 94 / 121 @leggetter
  154. 154. Future 95 / 121 @leggetter
  155. 155. Network Infrastructure & Protocols Reliability Speed Beyond HTTP HTTP2 96 / 121 @leggetter
  156. 156. Bayeux DDP dNode EPCP GRIP gRPC MQTT Pusher Protocol STOMP SignalR Protocol WAMP (Web App Messaging Protocol) XMPP (various) Communication Pattern Protocol Standardisation 97 / 121 @leggetter
  157. 157. 98 / 121 @leggetter
  158. 158. Firebase GitHub Iron.io MailChimp MailJet PagerDuty Nexmo SendGrid Real-Time APIs 99 / 121 @leggetter
  159. 159. 100 / 121 @leggetter
  160. 160. More "Things"! 101 / 121 @leggetter
  161. 161. The Physical Web 102 / 121 @leggetter
  162. 162. IoT, Apps & Developers 103 / 121 @leggetter
  163. 163. A thing can be anything 104 / 121 @leggetter
  164. 164. A thing can be anything Sensors Appliances Vehicles Smart Phones Devices (Arduino, Electric Imp, Raspberry Pi etc.) 104 / 121 @leggetter
  165. 165. A thing can be anything Sensors Appliances Vehicles Smart Phones Devices (Arduino, Electric Imp, Raspberry Pi etc.) Servers Browsers Apps: Native, Web, running anywhere 104 / 121 @leggetter
  166. 166. The Majority of code we'll write will still be for "Apps" Configuring Monitoring Interacting App Logic 105 / 121 @leggetter
  167. 167. Real-Time Use Case Evolution Notifications & Signalling Activity Streams Data Viz & Polls Chat Collaboration Multiplayer Games 106 / 121 @leggetter
  168. 168. Notifications/Activity Streams -> Actions 107 / 121 @leggetter The end of apps as we know it - Intercom
  169. 169. Subscriptions 108 / 121 @leggetter
  170. 170. Personalised Event Streams 109 / 121 @leggetter
  171. 171. Unified UIs 110 / 121 @leggetter
  172. 172. Chat & Bots for Everything and the rise of the .ai domain 111 / 121 @leggetter
  173. 173. 600M MAUs 10M integrations app-within-an-app model taxi, order food, tickets, games etc. WeChat 112 / 121 @leggetter
  174. 174. Chat Integrations 113 / 121 @leggetter
  175. 175. Siri Google Now Microso Cortana Facebook M Chat "Virtual Assistants" 114 / 121 @leggetter
  176. 176. 115 / 121 @leggetter
  177. 177. Chat has evolved. Chat is now a platform! 116 / 121 @leggetter
  178. 178. Multi-Device Experiences 117 / 121 @leggetter
  179. 179. Ben Foxall - A conceptual future for the multi-device web (FutureJS 2014) 118 / 121 @leggetter
  180. 180. You need Real-Time! There are lots of options. Make the choice that's right for you. I hope this helps! 119 / 121 @leggetter
  181. 181. Resources Real-time Tech Guide github.com/leggetter/realtime-dotnet-examples Tools, Tips and Techniques for Developing Real- time Apps Nexmo 120 / 121 @leggetter
  182. 182. Real-time Web Apps & .NET What are your options? Questions? PHIL @LEGGETTER Head of Developer Relations 121 / 121 @leggetter

×