node-amf and node-rtmp

AMF and RTMP libraries for node.js – Flash remoting with node.

I’ve been having fun playing with node.js over the past year, but have had little, or no excuse to use it in any production work, so I thought I’d set myself a challenge and build a module. That challenge was firstly to create a simple AMF gateway for Flash remoting, and secondarily to see if an RTMP socket server was achievable in node.

If you don’t know about “node” – It’s a JavaScript runtime that allows you to write socket servers. I like it a lot – it brings asynchronous, event-driven programming to the server side and provides a truly global variable scope across all connections. I’ll blog about it in more detail later, perhaps.

At Public we do a lot of Flash work, and regularly implement Flash remoting using a PHP AMF gateway. I wasn’t necessarily looking to replace this stock approach with node, but node offers proper socket connections that PHP can’t, so I was imagining the possibilities of using node as a free, and more flexible alternative to Flash Media Server. Not for streaming media, but for real-time messaging, for example in multi-player games. If I’m honest though, I did this mostly for fun, an academic exercise and as an excuse to work with node.

node-amf

node-amf is on GitHub as a public repository: http://github.com/timwhitlock/node-amf

The first step was to write a pure JavaScript AMF implementation. i.e. a library for serializing and deserializing AMF packets. If you’re not familiar with AMF (Action Message Format) – it’s a binary serialization and messaging format invented by Adobe for passing data back and forth between Flash and a remote server. I am not the only person to implement this in JavaScript: mid-way through my project I noticed amf.js appear – just a little too late for me. This library is probably much better than my own, but mine is designed specifically for node, so I shall stick with it for now.

With a working AMF library all that remained was to create a HTTP gateway. There are many examples of AMF gateways in other languages, including PHP. The general approach is that a single request/response exchange carries one or more messages, each one calling a web service on the server and returning the result. AMF also has the ability to invoke methods in the Flash client on response – an underused feature.

Node makes it incredibly easy to implement an HTTP server, all that I had to do was decide how to expose the web services to the gateway. I decided to do this by passing a user-defined JavaScript object when initializing the server – each property of the object is a function callable by name – example AMF gateway here. This suitably sandboxes the method calls, and ensures the client cannot execute arbitrary JavaScript functions – that would be bad.

This part of the project is largely complete and working. It has not been used in production yet, so if you’re brave enough to use it, please let me know how it’s going!

node-rtmp

node-rtmp is currently under the same project as node-amf because it’s dependant upon the AMF library. This incomplete, highly unstable, and experimental work is under the node-rtmp subdirectory with examples here.

If you’re not familiar with RTMP (Real Time Messaging Protocol) it provides bi-directional streaming media and messaging over persistent socket connections. It’s the messaging I’m interested in. Flash talks to Flash Media Server over RTMP sockets and can securely call methods in both directions.

As it turns out the RTMP specification is very badly written. (The AMF specs were quite easy to read, although possibly much simpler). If I was a cynic, I may even suggest that Adobe has purposefully written them badly to avoid third party developers being able to adhere to the usage license which insists in adequate conformance to the spec. However, it doesn’t seem to have stopped numerous projects such as librtmp from gluing the pieces together.

This is the point where I realised I might be out of my depth. I am currently in the process of glueing the pieces together myself. Armed with the dodgy specification, Wireshark, and the fragmented information dotted around the Internet, I am making some slow progress. At the time of writing I have the RTMP handshake working correctly, and have just about deciphered the command messaging packets.

I may give up before this is at all useful.

librtmp and node add-ons

As you may have noticed, I’m talking about implementing all of this in pure JavaScript, and you may be thinking that’s nuts. You are probably right. As libraries, these don’t really need to be written in JavaScript. In addition to pure JavaScript modules, node supports add-ons – compiled libraries which can be built against C and C++ system libraries. A good example of this is node-memcache.

C and C++ is unfortunately outside my skill set, but I imagine it may be possible to build an RTMP node add-on using librtmp. Anyone fancy a crack at that?

6 thoughts on “node-amf and node-rtmp”

  1. I took a different approach to integrating Node.JS with Flash: WebSockets. I wanted a unified server back-end that could talk equally well to both HTML5 and Flash applications on the front end, and to that end, wrote a WebSocket library for both Node.JS and for ActionScript 3.

    Once the WebSocket connection is established, one can send any kind of arbitrary data messages, including JSON for HTML5 apps and AMF3 for Flash apps. I’m considering using your AMF3 library in combination with my WebSocket library for real-time interactivity in my Flash application — I’m currently using JSON, which is working just fine, but am exploring AMF3 as a faster, more native messaging format.

    Node.JS WebSocket Client & Server Library:
    https://github.com/Worlize/WebSocket-Node

    ActionScript 3 WebSocket Client Library:
    https://github.com/Worlize/AS3WebSocket

  2. Hi , Will certainly look at your implementation and have a looksy at your source code))

    Cheers, mate))

  3. if you guys need them i can provide access and/or dumps from an actual macromedia fms installation, id love to see a node implementation of rtmp

  4. Hey dude, I was digging for SSJS alternations of AMFPHP that also supports remote shared objects and messaging, and I am personally have a great interest in node.js.

    Guess what? your project seems just fits all of my interests. Please tell me how can I contribute, you may just list issues in github and I’ll try to work on them!

  5. Hi,

    I’m really interested in your work with rtmp on node.js. I’ve been trying to get your code to work but I seem to be having quite a bit of trouble.

    I’ve spent hours digging around fluorinefx and red5 to try to understand what’s going wrong, but they all seem to implement the protocol in different ways. It’s driving me insane.

    Keep working on this project ;)

Comments are closed.