• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Building Real-Time Applications with Android and WebSockets
 

Building Real-Time Applications with Android and WebSockets

on

  • 10,823 views

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

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

Statistics

Views

Total Views
10,823
Views on SlideShare
10,790
Embed Views
33

Actions

Likes
14
Downloads
186
Comments
0

5 Embeds 33

http://lanyrd.com 26
http://www.linkedin.com 3
https://twitter.com 2
https://www.chatwork.com 1
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Building Real-Time Applications with Android and WebSockets Building Real-Time Applications with Android and WebSockets Presentation Transcript

    • Real Time applications with WebSockets / WorkShop Sergi Almar i graupera @sergialmar Romanian mobile systems community conference (mobos) November 2013 - cluj Napoca
    • 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
    • Collaborative Apps Multiplayer Games Multimedia Chat Social Feeds Sports Updates Financial Tickets Clickstream Data Online Education Location-based Apps
    • 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 overhead for text messages (frames) • • 0x00 for frame start, 0xFF for frame end (vs HTTP 1K) Ping / pong frames for staying alive
    • 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
    • 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); };
    • 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 • RoboFragmentActivity • RoboFragment • RoboService • …
    • 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;
    • Injecting Resources @InjectResource(R.anim.my_animation) Animation myAnimation; ! @InjectResource(R.drawable.icon) ! Drawable icon; @InjectResource(R.string.app_name) String myName;
    • Injection POJOs @Singleton public class MyPojo { private String myField; ! public void myMethod() { ... } } @Inject private MyPojo myPojo;
    • 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
    • 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 ); } }
    • 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 ); } }
    • 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 • Optimisations like inlining, elision of runtime properties… • Improved garbage collector
    • 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
    • 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');
    • 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
    • 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,
    • 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
    • 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/');
    • 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 World'); }); ! app.listen(3000);
    • 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 streaming • JSONP polling • iFrame
    • 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
    • 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
    • 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
    • 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 awesome")); publish the message synchronous delivery
    • 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://github.com/fatshotty/socket.io-java-client Server-like API
    • 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) { }
    • Lab III https://github.com/salmar/android-websocketsmobos2013/wiki
    • Thank you! @sergialmar