Your SlideShare is downloading. ×
0
Real Time applications with
WebSockets / WorkShop
Sergi Almar i graupera
@sergialmar

Romanian mobile systems community co...
Agenda
•

Part 1 - Architecture and Dependency Injection with Android

•

Part 2 - Building the Server in Node.js and Sock...
Collaborative Apps
Multiplayer Games
Multimedia Chat
Social Feeds
Sports Updates
Financial Tickets
Clickstream Data
Online...
Real-time data on the web
•

Polling

•

Long polling / Comet

•

Flash
Problem

Applications need two-way communication
Too many connections and overhead with ajax / comet
WebSockets
two-way real time communication
WebSockets
•

Real-time full duplex communication over TCP

•

Uses port 80 / 443 (URL scheme: ws:// and wss://)

•

Small...
WebSocket Handshake
GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key...
WebSocket API
var ws = new WebSocket('ws://www.romobos.com/ws');

!

// When the connection is open, send some data to the...
What we are gonna build
(real-time chat app)
websoc

kets

w

ckets
ebso
Dependency Injection
decouple components, flexible code, reduce
boilerplate, testable code
Dependency Injection in Android
•

RoboGuice

•

Dagger

•

Transfuse

•

Android annotations
RoboGuice
•

Dependency Injection framework

•

Uses Google Guice as the backbone

•

Supports JSR-330
Extending from RoboGuice
•

RoboActivity

•

RoboListActivity

•

RoboMapActivity

•

RoboPreferenceActivity

•

RoboFragm...
Injecting Views
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
a...
Injecting Resources
@InjectResource(R.anim.my_animation) Animation myAnimation;

!
@InjectResource(R.drawable.icon)
!

Dra...
Injection POJOs
@Singleton
public class MyPojo {
private String myField;

!

public void myMethod() {
...
}

}

@Inject pr...
Custom Binding
public class MyModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(IFoo...
Traditional Approach
class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable...
RoboGuice Approach
@ContentView(R.layout.main)
class RoboWay extends RoboActivity {
@InjectView(R.id.name)
@InjectView(R.i...
Lab I
https://github.com/salmar/android-websocketsmobos2013/wiki
Part II
Building the Server with NodeJS
and Socket.io
Node.js
event driven, non-blocking server
side JS
Google V8 Engine
•

Open source JS engine by Google (used in Google
Chrome)

•

No JIT, all JS compiled to assembler

•

O...
CommonJS
•

Set of specifications for JS outside the browser

•

Node.js implements some specifications
•

i.e modules
•

Th...
Modules
•

Node.js provides some core modules like http, tcp, fs, sys…
•

will look for the module in the node_modules dir...
Module Example
var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) ...
Dependency Management
Node packet manager (npm)
express (routing), socket.io (websockets)…
Sergis-MacBook-Air:tmp salmar$ ...
package.json
{
"name": "Mobos Chat",
"version": "1.0.0",
"description": "Real time chat",
"author": "salmar",
"scripts": {...
Web Server in NodeJS
var http = require('http');

!

http.createServer(function (req, res) {
res.writeHead(200, {'Content-...
Running the app
Sergis-MacBook-Air:tmp salmar$ node app.js
Server running at http://127.0.0.1:1337/
Express.js
sinatra inspired web framework for node.js
Express.js
var express = require('express');
var app = express();

!

app.get('/', function(req, res){
res.send('Hello Wor...
Socket.io

abstraction layer for WebSockets
http://caniuse.com/#feat=websockets / Nov 2013
Socket.io
•

Abstraction layer for WebSockets

•

Fallback to:
•

Flash socket

•

AJAX Long-polling

•

AJAX multi-part s...
Handling Events
io.sockets.on('connection', function(socket) {});

initial connection from client
socket.on('message', fun...
Sending messages
socket.send(JSON.stringify({user:'sergi',
message: 'Welcome to Mobos'})
);

sends a message to the connec...
Emitting Events
socket.emit('user:join', {name: 'sergi'});

triggers a custom event

socket.broadcast.emit('user:joined', ...
Attach information to the socket

socket.set('nickname', data.name, <optional_callback>);
Lab II
https://github.com/salmar/android-websocketsmobos2013/wiki
Part III
Building the Android client with
Socket.io
Otto
enhanced event bus with emphasis on Android support
publish

subscribe

Activity
Activity

Activity
FRAGMENT
SERVICE
POJO

bus

Activity
FRAGMENT
Otto
•

Forked from Guava’s EventBus

•

Lightweight - 19k

•

Fast, optimised for Android
Publishing
Bus bus = new Bus();

creates the bus (better use dependency injection)

bus.post(new ServerMessage("This is aw...
Subscribing
@Subscribe
public void receiveMessage(ServerMessage serverMessage) {
// TODO: React to the event somehow!
}
Otto API
•

register(), unregister(), post()

•

@Subscribe, @Produce

•

Thread confinement

•

Easy to test
SocketIO for Android
•

There’s no official library, but there are community
libraries, sometimes buggy :(
•

•

https://gi...
Callbacks
!
!
!
!
!

public void onMessage(JsonElement json, IOAcknowledge ack) {
}
public void onMessage(String data, IOA...
Lab III
https://github.com/salmar/android-websocketsmobos2013/wiki
Thank you!
@sergialmar
Upcoming SlideShare
Loading in...5
×

Building Real-Time Applications with Android and WebSockets

28,792

Published on

Workshop delivered at Mobos 2013 (http://romobos.com/) (building real-time applications with android socket.io and node.js)

Published in: Technology

Transcript of "Building Real-Time Applications with Android and WebSockets"

  1. 1. Real Time applications with WebSockets / WorkShop Sergi Almar i graupera @sergialmar Romanian mobile systems community conference (mobos) November 2013 - cluj Napoca
  2. 2. Agenda • Part 1 - Architecture and Dependency Injection with Android • Part 2 - Building the Server in Node.js and Socket.io • Part 3 - Building the Android client
  3. 3. Collaborative Apps Multiplayer Games Multimedia Chat Social Feeds Sports Updates Financial Tickets Clickstream Data Online Education Location-based Apps
  4. 4. Real-time data on the web • Polling • Long polling / Comet • Flash
  5. 5. Problem Applications need two-way communication Too many connections and overhead with ajax / comet
  6. 6. WebSockets two-way real time communication
  7. 7. WebSockets • Real-time full duplex communication over TCP • Uses port 80 / 443 (URL scheme: ws:// and wss://) • Small overhead for text messages (frames) • • 0x00 for frame start, 0xFF for frame end (vs HTTP 1K) Ping / pong frames for staying alive
  8. 8. WebSocket Handshake GET /mychat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat Sec-WebSocket-Version: 13 Origin: http://example.com client sends a WebSocket handshake request HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat server response
  9. 9. WebSocket API var ws = new WebSocket('ws://www.romobos.com/ws'); ! // When the connection is open, send some data to the server ws.onopen = function () { ws.send('Ping'); // Send the message 'Ping' to the server }; ! // Log errors ws.onerror = function (error) { ws.log('WebSocket Error ' + error); }; ! // Log messages from the server ws.onmessage = function (e) { ws.log('Server: ' + e.data); };
  10. 10. What we are gonna build (real-time chat app) websoc kets w ckets ebso
  11. 11. Dependency Injection decouple components, flexible code, reduce boilerplate, testable code
  12. 12. Dependency Injection in Android • RoboGuice • Dagger • Transfuse • Android annotations
  13. 13. RoboGuice • Dependency Injection framework • Uses Google Guice as the backbone • Supports JSR-330
  14. 14. Extending from RoboGuice • RoboActivity • RoboListActivity • RoboMapActivity • RoboPreferenceActivity • RoboFragmentActivity • RoboFragment • RoboService • …
  15. 15. Injecting Views <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" /> @InjectView(R.id.text1) TextView mSampleText;
  16. 16. Injecting Resources @InjectResource(R.anim.my_animation) Animation myAnimation; ! @InjectResource(R.drawable.icon) ! Drawable icon; @InjectResource(R.string.app_name) String myName;
  17. 17. Injection POJOs @Singleton public class MyPojo { private String myField; ! public void myMethod() { ... } } @Inject private MyPojo myPojo;
  18. 18. Custom Binding public class MyModule implements Module { @Override public void configure(Binder binder) { binder.bind(IFoo.class).to(SimpleFoo.class); } } define a module public class App extends Application { ! ! @Override public void onCreate() { super.onCreate(); RoboGuice.setBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE, RoboGuice.newDefaultRoboModule(this), new MyModule()); } } let RoboGuice know about it
  19. 19. Traditional Approach class AndroidWay extends Activity { TextView name; ImageView thumbnail; LocationManager loc; Drawable icon; String myName; ! public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); name = (TextView) findViewById(R.id.name); thumbnail = (ImageView) findViewById(R.id.thumbnail); loc = (LocationManager) getSystemService(Activity.LOCATION_SERVICE); icon = getResources().getDrawable(R.drawable.icon); myName = getString(R.string.app_name); name.setText( "Hello, " + myName ); } }
  20. 20. RoboGuice Approach @ContentView(R.layout.main) class RoboWay extends RoboActivity { @InjectView(R.id.name) @InjectView(R.id.thumbnail) @InjectResource(R.drawable.icon) @InjectResource(R.string.app_name) @Inject ! TextView name; ImageView thumbnail; Drawable icon; String myName; LocationManager loc; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); name.setText( "Hello, " + myName ); } }
  21. 21. Lab I https://github.com/salmar/android-websocketsmobos2013/wiki
  22. 22. Part II Building the Server with NodeJS and Socket.io
  23. 23. Node.js event driven, non-blocking server side JS
  24. 24. Google V8 Engine • Open source JS engine by Google (used in Google Chrome) • No JIT, all JS compiled to assembler • Optimisations like inlining, elision of runtime properties… • Improved garbage collector
  25. 25. CommonJS • Set of specifications for JS outside the browser • Node.js implements some specifications • i.e modules • There should be a function called require • There should be a var called exports
  26. 26. Modules • Node.js provides some core modules like http, tcp, fs, sys… • will look for the module in the node_modules dir hierarchically • if not found, will look in the paths outlined in NODE_PATH var http = require('http');
  27. 27. Module Example var PI = Math.PI; exports.area = function (r) { return PI * r * r; }; exports.circumference = function (r) { return 2 * PI * r; }; module definition in myModule.js var myModule = require('./myModule.js'); include myModule.js in some other file
  28. 28. Dependency Management Node packet manager (npm) express (routing), socket.io (websockets)… Sergis-MacBook-Air:tmp salmar$ npm install express npm http GET https://registry.npmjs.org/express npm http 200 https://registry.npmjs.org/express npm http GET https://registry.npmjs.org/express/-/express-3.4.4.tgz npm http 200 https://registry.npmjs.org/express/-/express-3.4.4.tgz npm http GET https://registry.npmjs.org/connect/2.11.0 npm http GET https://registry.npmjs.org/commander/1.3.2 npm http GET https://registry.npmjs.org/methods/0.1.0 npm http GET https://registry.npmjs.org/range-parser/0.0.4 npm http GET https://registry.npmjs.org/mkdirp/0.3.5 npm http GET https://registry.npmjs.org/cookie/0.1.0 npm http GET https://registry.npmjs.org/buffer-crc32/0.2.1 npm http GET https://registry.npmjs.org/fresh/0.2.0 npm http GET https://registry.npmjs.org/cookie-signature/1.0.1 npm http GET https://registry.npmjs.org/send/0.1.4 npm http GET https://registry.npmjs.org/debug npm http 200 https://registry.npmjs.org/methods/0.1.0 npm http 304 https://registry.npmjs.org/range-parser/0.0.4 npm http GET https://registry.npmjs.org/methods/-/methods-0.1.0.tgz npm http 200 https://registry.npmjs.org/commander/1.3.2 npm http GET https://registry.npmjs.org/commander/-/commander-1.3.2.tgz npm http 304 https://registry.npmjs.org/cookie/0.1.0 … ! express@3.4.4 node_modules/express ├── methods@0.1.0 ├── range-parser@0.0.4 ├── cookie-signature@1.0.1 ├── fresh@0.2.0 ├── debug@0.7.4 ├── buffer-crc32@0.2.1 ├── cookie@0.1.0 ├── mkdirp@0.3.5 ├── commander@1.3.2 (keypress@0.1.0) ├── send@0.1.4 (mime@1.2.11) └── connect@2.11.0 (methods@0.0.1, uid2@0.0.3, pause@0.0.1, qs@0.6.5, raw-body@0.0.3, bytes@0.2.1, negotiator@0.3.0,
  29. 29. package.json { "name": "Mobos Chat", "version": "1.0.0", "description": "Real time chat", "author": "salmar", "scripts": { "start": "node app.js" }, "dependencies": { "socket.io": "latest", "express": "latest", "jade": "latest" } } npm install
  30. 30. Web Server in NodeJS var http = require('http'); ! http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(1337, '127.0.0.1'); ! console.log('Server running at http://127.0.0.1:1337/');
  31. 31. Running the app Sergis-MacBook-Air:tmp salmar$ node app.js Server running at http://127.0.0.1:1337/
  32. 32. Express.js sinatra inspired web framework for node.js
  33. 33. Express.js var express = require('express'); var app = express(); ! app.get('/', function(req, res){ res.send('Hello World'); }); ! app.listen(3000);
  34. 34. Socket.io
 abstraction layer for WebSockets
  35. 35. http://caniuse.com/#feat=websockets / Nov 2013
  36. 36. Socket.io • Abstraction layer for WebSockets • Fallback to: • Flash socket • AJAX Long-polling • AJAX multi-part streaming • JSONP polling • iFrame
  37. 37. Handling Events io.sockets.on('connection', function(socket) {}); initial connection from client socket.on('message', function(message) {}) message handler triggered when message is received socket.on('disconnect', function() {}) triggered when socket disconnects socket.on('custom_event', function(data) {}) event handler for custom event
  38. 38. Sending messages socket.send(JSON.stringify({user:'sergi', message: 'Welcome to Mobos'}) ); sends a message to the connected client socket.broadcast.send(JSON.stringify({user:’sergi', message: 'Welcome to Mobos'}) ); sends a message to all clients except the owner of the socket
  39. 39. Emitting Events socket.emit('user:join', {name: 'sergi'}); triggers a custom event socket.broadcast.emit('user:joined', data); sends a message to all clients except the owner of the socket
  40. 40. Attach information to the socket socket.set('nickname', data.name, <optional_callback>);
  41. 41. Lab II https://github.com/salmar/android-websocketsmobos2013/wiki
  42. 42. Part III Building the Android client with Socket.io
  43. 43. Otto enhanced event bus with emphasis on Android support
  44. 44. publish subscribe Activity Activity Activity FRAGMENT SERVICE POJO bus Activity FRAGMENT
  45. 45. Otto • Forked from Guava’s EventBus • Lightweight - 19k • Fast, optimised for Android
  46. 46. Publishing Bus bus = new Bus(); creates the bus (better use dependency injection) bus.post(new ServerMessage("This is awesome")); publish the message synchronous delivery
  47. 47. Subscribing @Subscribe public void receiveMessage(ServerMessage serverMessage) { // TODO: React to the event somehow! }
  48. 48. Otto API • register(), unregister(), post() • @Subscribe, @Produce • Thread confinement • Easy to test
  49. 49. SocketIO for Android • There’s no official library, but there are community libraries, sometimes buggy :( • • https://github.com/fatshotty/socket.io-java-client Server-like API
  50. 50. Callbacks ! ! ! ! ! public void onMessage(JsonElement json, IOAcknowledge ack) { } public void onMessage(String data, IOAcknowledge ack) { } public void onError(SocketIOException socketIOException) { } public void onDisconnect() { } public void onConnect() { } public void on(String event, IOAcknowledge ack, JsonElement... args) { }
  51. 51. Lab III https://github.com/salmar/android-websocketsmobos2013/wiki
  52. 52. Thank you! @sergialmar
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×