$30 off During Our Annual Pro Sale. View Details »

Node for Not HTTP

Evan Tahler
December 04, 2014

Node for Not HTTP

The talk gave an overview of some of the cool things you can do with node.js that are not related to websites. To do this, I cobbled together an actionhero project that would take input form HTTP, WebSockets, Telnet, and twitter which allowed us to turn a desk lamp on and off. I taught a room about the DMX lighting protocol and how to build an actionhero server in 20 minutes!

- Slides: https://docs.google.com/presentation/d/1jijGOARfeMDSqZnl52uv3N9zL8K4Eiu4g6wGTtUIll4
- Github Project: https://github.com/evantahler/nodefornot_http
- Video: http://strongloop.com/node-js/videos/#An-Introduction-to-Non-HTTP-Clients-for-Node.js

Evan Tahler

December 04, 2014
Tweet

More Decks by Evan Tahler

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

  3. 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).

    View Slide

  4. 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

    View Slide

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

    View Slide

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

    View Slide

  7. View Slide

  8. 0: Lights

    View Slide

  9. 0) How do we talk to this light?

    View Slide

  10. 0) How do we talk to this light?

    View Slide

  11. 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

    View Slide

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

    View Slide

  13. 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!

    View Slide

  14. 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!

    View Slide

  15. 1: Telnet

    View Slide

  16. 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!

    View Slide

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

    View Slide

  18. 2: Websockets

    View Slide

  19. 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

    View Slide

  20. 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!

    View Slide

  21. 3: Twitter

    View Slide

  22. 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…

    View Slide

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

    View Slide

  24. 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!

    View Slide

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

    View Slide

  26. Thanks!

    View Slide

  27. 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

    View Slide