Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Asynchronous Communication Layer

Building Asynchronous Communication Layer

At Hulu, we built an asynchronous automation framework using XMPP, Ruby, and JavaScript called Bender. We use it with Roku, Playstation 3, Wii, Android, and iOS devices. This talk is a tour of some of the key technologies we chose and why we are using them.

Andrew Carter

April 26, 2012
Tweet

Other Decks in Programming

Transcript

  1. To help people find and enjoy the world’s premium content

    when, where, and how they want it. 4 Tuesday, April 24, 12
  2. •Multiple platforms (JavaScript, native UI) •Custom tools for each platform

    •Streaming video •Network conditions Why devices can be difficult 17 Tuesday, April 24, 12
  3. Testing Video Streaming 18 •Sensitive to network conditions and hardware

    •Achieving repeatability •Playback engines different for each platform •Time consuming Tuesday, April 24, 12
  4. •Minimal Latency •Works with constrained clients •HTTP 1.0, no cookies,

    no headers •No chunked transfer coding BOSH (XMPP over HTTP) 30 Tuesday, April 24, 12
  5. •Reference Jabber server •Runs jabber.org public service •Scale to 5000-10,000

    concurrent clients •Erlang •Installation •Via chef recipe •Nginx to proxy port 80 to port 5280 ejabberd 31 Tuesday, April 24, 12
  6. •Ruby implementation of XMPP client •Asynchronous API •Threaded library •Uses

    REXML •Alternatives •Blather (EventMachine + Nokogiri) •Net::XMPP •Jabber4R XMPP4R 35 Tuesday, April 24, 12
  7. •JavaScript implementation of BOSH •Uses XMLHTTPRequest •XML builder API •Plug-in

    support : Strophe.addConnectionPlugin •Alternatives •JSJaC •Xmpp4js •http://xmpp.org/xmpp-software Strophe.js 39 Tuesday, April 24, 12
  8. Strophe.js Plugin 40 Strophe.addConnectionPlugin('htv', { init: function (connection) { /*

    Platform-specific code */ }, register: function(address, password, successCb) { this.registerSuccessCb = successCb; this.connection._addSysHandler(successCb, Strophe.NS.REGISTER, null, "result", regId); this.connection.send( $iq({ type: "set”, to: domain, id: regId }) .c("query", { xmlns: Strophe.NS.REGISTER }) .c("username", {}).t(node).up() .c("password", {}).t(password).up() .c("username", {}).t(account).up() .c("password", {}).t(password) ); } }); Tuesday, April 24, 12
  9. •Ruby API to control remote devices •Simple DSL •Device agnostic

    command/response protocol •Synchronous API via Asynchronous transport •Delivered as a Ruby gem •Certification Test Suite •Runs on Ruby 1.9.3 Bender 44 Tuesday, April 24, 12
  10. def send_command(cmd) resp = nil @resp_mutex.synchronize do @transport.transmit(cmd.serialize_to_json) @resp_cond.wait(@resp_mutex, cmd.timeout)

    resp = @received.delete(cmd.response_id) if resp.nil? raise RequestTimeOut.new(“timed out!”) end end return resp end Ruby Threading 46 Tuesday, April 24, 12
  11. REXML with Unicode Jabber uses streams of segments as part

    of document which default to ASCII not UTF-8 53 Tuesday, April 24, 12