52
Real me applications with WebSockets / WorkShop Sergi Almar i graupera @sergialmar Romanian mobile systems community conference (mobos) November 2013 - cluj Napoca

Building Real-Time Applications with Android and WebSockets

Embed Size (px)

Citation preview

Page 1: Building Real-Time Applications with Android and WebSockets

Real Time applications with WebSockets / WorkShop

Sergi Almar i graupera @sergialmar

Romanian mobile systems community conference (mobos) November 2013 - cluj Napoca

Page 2: Building Real-Time Applications with Android and WebSockets

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

Page 3: Building Real-Time Applications with Android and WebSockets

Social FeedsMultiplayer Games

Collaborative Apps

Clickstream DataFinancial Tickets Sports Updates

Multimedia Chat

Location-based AppsOnline Education

Page 4: Building Real-Time Applications with Android and WebSockets

Real-time data on the web

• Polling

• Long polling / Comet

• Flash

Page 5: Building Real-Time Applications with Android and WebSockets

Problem Applications need two-way communication Too many connections and overhead with ajax / comet

Page 6: Building Real-Time Applications with Android and WebSockets

WebSockets two-way real time communication

Page 7: Building Real-Time Applications with Android and WebSockets

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

Page 8: Building Real-Time Applications with Android and WebSockets

WebSocket HandshakeGET /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

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat

client sends a WebSocket handshake request

server response

Page 9: Building Real-Time Applications with Android and WebSockets

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); };

Page 10: Building Real-Time Applications with Android and WebSockets

What we are gonna build (real-time chat app)

websockets

websockets

Page 11: Building Real-Time Applications with Android and WebSockets

Dependency Injection decouple components, flexible code, reduce

boilerplate, testable code

Page 12: Building Real-Time Applications with Android and WebSockets

Dependency Injection in Android

• RoboGuice

• Dagger

• Transfuse

• Android annotations

Page 13: Building Real-Time Applications with Android and WebSockets

RoboGuice

• Dependency Injection framework

• Uses Google Guice as the backbone

• Supports JSR-330

Page 14: Building Real-Time Applications with Android and WebSockets

Extending from RoboGuice• RoboActivity

• RoboListActivity

• RoboMapActivity

• RoboPreferenceActivity

• RoboFragmentActivity

• RoboFragment

• RoboService

• …

Page 15: Building Real-Time Applications with Android and WebSockets

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;

Page 16: Building Real-Time Applications with Android and WebSockets

Injecting Resources

@InjectResource(R.anim.my_animation) Animation myAnimation; !@InjectResource(R.drawable.icon) Drawable icon; !@InjectResource(R.string.app_name) String myName;

Page 17: Building Real-Time Applications with Android and WebSockets

Injection POJOs@Singleton public class MyPojo { private String myField; ! public void myMethod() { ... } }

@Inject private MyPojo myPojo;

Page 18: Building Real-Time Applications with Android and WebSockets

Custom Bindingpublic 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

Page 19: Building Real-Time Applications with Android and WebSockets

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 ); } }

Page 20: Building Real-Time Applications with Android and WebSockets

RoboGuice Approach

@ContentView(R.layout.main) class RoboWay extends RoboActivity { @InjectView(R.id.name) TextView name; @InjectView(R.id.thumbnail) ImageView thumbnail; @InjectResource(R.drawable.icon) Drawable icon; @InjectResource(R.string.app_name) String myName; @Inject LocationManager loc; ! public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); name.setText( "Hello, " + myName ); } }

Page 21: Building Real-Time Applications with Android and WebSockets

Lab I https://github.com/salmar/android-websockets-

mobos2013/wiki

Page 22: Building Real-Time Applications with Android and WebSockets

Part II Building the Server with NodeJS

and Socket.io

Page 23: Building Real-Time Applications with Android and WebSockets

Node.js event driven, non-blocking server

side JS

Page 24: Building Real-Time Applications with Android and WebSockets

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

Page 25: Building Real-Time Applications with Android and WebSockets

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

Page 26: Building Real-Time Applications with Android and WebSockets

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');

Page 27: Building Real-Time Applications with Android and WebSockets

Module Examplevar 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

Page 28: Building Real-Time Applications with Android and WebSockets

Dependency Management

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 … [email protected] node_modules/express ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ([email protected]) ├── [email protected] ([email protected]) └── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected],

Node packet manager (npm) express (routing), socket.io (websockets)…

Page 29: Building Real-Time Applications with Android and WebSockets

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

Page 30: Building Real-Time Applications with Android and WebSockets

var http = require('http'); !http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337, '127.0.0.1'); !console.log('Server running at http://127.0.0.1:1337/');

Web Server in NodeJS

Page 31: Building Real-Time Applications with Android and WebSockets

Running the appSergis-MacBook-Air:tmp salmar$ node app.js Server running at http://127.0.0.1:1337/

Page 32: Building Real-Time Applications with Android and WebSockets

Express.js sinatra inspired web framework for node.js

Page 33: Building Real-Time Applications with Android and WebSockets

Express.js

var express = require('express'); var app = express(); !app.get('/', function(req, res){ res.send('Hello World'); }); !app.listen(3000);

Page 34: Building Real-Time Applications with Android and WebSockets

Socket.ioabstraction layer for WebSockets

Page 35: Building Real-Time Applications with Android and WebSockets

http://caniuse.com/#feat=websockets / Nov 2013

Page 36: Building Real-Time Applications with Android and WebSockets

Socket.io• Abstraction layer for WebSockets

• Fallback to:

• Flash socket

• AJAX Long-polling

• AJAX multi-part streaming

• JSONP polling

• iFrame

Page 37: Building Real-Time Applications with Android and WebSockets

Handling Eventsio.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

Page 38: Building Real-Time Applications with Android and WebSockets

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

Page 39: Building Real-Time Applications with Android and WebSockets

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

Page 40: Building Real-Time Applications with Android and WebSockets

Attach information to the socket

socket.set('nickname', data.name, <optional_callback>);

Page 41: Building Real-Time Applications with Android and WebSockets

Lab II https://github.com/salmar/android-websockets-

mobos2013/wiki

Page 42: Building Real-Time Applications with Android and WebSockets

Part III Building the Android client with

Socket.io

Page 43: Building Real-Time Applications with Android and WebSockets

Otto enhanced event bus with emphasis on Android support

Page 44: Building Real-Time Applications with Android and WebSockets

Activity

Activity

FRAGMENT

SERVICE

POJO

bus

Activity

Activity

FRAGMENT

subscribepublish

Page 45: Building Real-Time Applications with Android and WebSockets

Otto

• Forked from Guava’s EventBus

• Lightweight - 19k

• Fast, optimised for Android

Page 46: Building Real-Time Applications with Android and WebSockets

Publishing

publish the message

synchronous delivery

Bus bus = new Bus();

bus.post(new ServerMessage("This is awesome"));

creates the bus (better use dependency injection)

Page 47: Building Real-Time Applications with Android and WebSockets

Subscribing

@Subscribe public void receiveMessage(ServerMessage serverMessage) { // TODO: React to the event somehow! }

Page 48: Building Real-Time Applications with Android and WebSockets

Otto API

• register(), unregister(), post()

• @Subscribe, @Produce

• Thread confinement

• Easy to test

Page 49: Building Real-Time Applications with Android and WebSockets

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

Page 50: Building Real-Time Applications with Android and WebSockets

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) { }

Page 51: Building Real-Time Applications with Android and WebSockets

Lab III https://github.com/salmar/android-websockets-

mobos2013/wiki

Page 52: Building Real-Time Applications with Android and WebSockets

Thank you! @sergialmar