Slide 1

Slide 1 text

Node.js for !(HTTP) @evantahler https://github.com/evantahler/node_for_not_http

Slide 2

Slide 2 text

Node is great at HTTP 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');

Slide 3

Slide 3 text

What else can node do well? ● WebSockets ● TCP (socket) ● UDP (socket) ● Driver Communication ● Incoming Streams via all of the above The event loop is great for handling any connection type, not just HTTP (just don’t block the CPU).

Slide 4

Slide 4 text

What are we going to do? Lets turn this light on and off… … via telnet … via websockets … via twitter … via the temperature in the room … via joysticks This talk will be a quick survey of some of using node.js for things other than HTTP

Slide 5

Slide 5 text

{{ BioPage }} @evantahler evantahler.com ● Director of Technology @ TaskRabbit ● Creator of the actionhero.js framework We are hiring! Talk to me later!

Slide 6

Slide 6 text

When we last saw our hero... www.actionherojs.com actionhero.js is a multi-transport API Server with integrated cluster capabilities and delayed tasks.

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

0: Lights

Slide 9

Slide 9 text

0) How do we talk to this light?

Slide 10

Slide 10 text

0) How do we talk to this light?

Slide 11

Slide 11 text

DMX is pretty cool ● DMX is EASY It was the 1980’s... 1. send null (0v) 2. send a buffer of integer values (8 bits) 3. sleep 20ms. 4. goto 1

Slide 12

Slide 12 text

Unix is pretty cool ● Everything is a file! ○ COM port -> /dev/usb.. var ftdi = require('ftdi');

Slide 13

Slide 13 text

0) How do we talk to DMX? var ftdi = require('ftdi'); ... ftdi.find(function(err, devices){ api.dmx.device = new ftdi.FtdiDevice(devices[0]); api.dmx.device.on('error', function(e){ … }); api.dmx.device.open(api.config.dmx, function(){ … }); }) ... api.dmx.universe = Buffer(513); setInterval(function(){ api.dmx.device.write(api.dmx.universe); }, 20); Demo Time!

Slide 14

Slide 14 text

0) A DMX action actionhero generateAction --name=dmx … exports.action = { name: 'dmx', description: 'dmx', ... inputs: {required: ['channel', 'power'], optional: []}, run: function(api, connection, next){ var channel = parseInt(connection.params.channel); var power = parseInt(connection.params.power); try{ api.dmx.set(channel, power); }catch(err){ connection.error = err; } next(connection, true); } }; Demo Time!

Slide 15

Slide 15 text

1: Telnet

Slide 16

Slide 16 text

1) How do we talk to Telnet? server.server = net.createServer(...); … > telnet localhost 5000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. {"welcome":"Hello! Welcome to the actionhero api","room":"defaultRoom","context":"api"} > detailsView {"status":"OK","context":"response","data":{"id":"2d68c389-521d-4dc6-b4f1-8292cd6cbde6","remoteIP":"127.0.0.1","remotePort": 57393,"params":{},"connectedAt":1368918901456,"room":"defaultRoom","totalActions":0,"pendingActions":0},"messageCount":1} > randomNumber {"randomNumber":0.4977603426668793,"context":"response","messageCount":2} Demo Time!

Slide 17

Slide 17 text

1) How do we talk to Telnet? Telnet API Considerations: ● Simultaneous Actions / Parallelism for a single connection ● Line Terminators ● Data Transports

Slide 18

Slide 18 text

2: Websockets

Slide 19

Slide 19 text

2) How do we talk to websockets? ● The same design considerations apply as telnet! ○ … and now you need to worry about fall-back protocols and http handshakes

Slide 20

Slide 20 text

2) How do we talk to websockets? client = new ActionheroClient; client.on('connected', function(){ console.log('connected!') }) client.on('disconnected', function(){ console.log('disconnected :(') }) client.on('alert', function(message){ alert(message) }) client.on('api', function(message){ alert(message) }) client.on('welcome', function(message){ appendMessage(message); }) client.on('say', function(message){ appendMessage(message); }) client.connect(function(err, details){ if(err){ console.log(err); }else{ client.action('someAction', {key: 'k', value: 'v'}, function(error data){ // do stuff }); } }); Demo Time!

Slide 21

Slide 21 text

3: Twitter

Slide 22

Slide 22 text

3) How do we Twitter? ● Servers vs. Connections, a philosophical aside. ○ We could write another initializer for twitter, and handle the data as it streams in. ○ But isn’t each tweet kind of like a connection? ■ data, client_id, message…

Slide 23

Slide 23 text

3) How do we Twitter? actionhero generateServer \ --name=twitter

Slide 24

Slide 24 text

3) How do we Twitter? server.addTweet = function(tweet){ var twitterUser; try{ twitterUser = tweet.user.screen_name; }catch(e){ var twitterUser = "unknown"; } server.buildConnection({ id: tweet.id, rawConnection : { hashtag: api.config.servers.twitter.hashtag, clientId: tweet.id, message: tweet.text, twitterUser: twitterUser, }, remoteAddress : 0, remotePort : 0 , }); // will emit "connection" Demo Time!

Slide 25

Slide 25 text

All together now... [[ I just used twitter to control the #nodelights ]]

Slide 26

Slide 26 text

Thanks!

Slide 27

Slide 27 text

References Me: http://evantahler.com Actionhero: http://actionherojs.com ● Docs: http://actionherojs.com/docs/ About DMX: http://playground.arduino.cc/Learning/DMX Hardware: ● Dimmer Pack: http://www.amazon.com/gp/product/B000FVZUMM/ ● DMX Driver: http://www.enttec.com/index.php?main_menu=Products&pn=70303 This Project: https://github.com/evantahler/node_for_not_http