Flash, Erlang and Realtime Collaborative Interfaces

November 28, 2009

I’ve been learning Erlang for the past few weeks and loving the simplicity and beauty of the language. As part of a discussion at SAP TechEd, last week, I ended up creating a simple, rather rudimentary prototype of a realtime messaging server that enables collaborative user interfaces where multiple users can simultaneously work with the same interface …

Here’s a video of the code in action …

As you watch the above video, note as I drag a rectangle in any one Flash application, its sends AMF encoded binary messages to the server and the server multicasts these messages to other connected clients and those clients update in almost realtime. While in the example above all the application instances are running on the same system, they could just as easily be running on different systems and still communicate via the server.

Here the code for the Erlang server …

0001 -module(server).
0002 -export([start/1,stop/0]).
0003 
0004 -define(TCP_OPTIONS,[binary,
0005                      {packet, 0},
0006                      {active, false},
0007                      {reuseaddr, true}]).
0008 
0009 start(Port) ->
0010 	 Pid = spawn(fun() -> manage([]) end),
0011     register(client_manager, Pid),
0012 	 {ok, Socket} = gen_tcp:listen(Port, ?TCP_OPTIONS),
0013     accept(Socket).
0014 
0015 stop() -> todo.
0016 
0017 accept(Socket) ->
0018   	 {ok, NewSocket} = gen_tcp:accept(Socket),
0019     spawn(fun() -> recieve(NewSocket) end),
0020     client_manager ! {connected, NewSocket},
0021     accept(Socket).
0022 
0023 recieve(Socket) ->
0024     case gen_tcp:recv(Socket, 0) of
0025         {ok, Data} ->
0026             client_manager ! {multicast,Socket,Data},
0027             recieve(Socket);
0028         {error, closed} ->
0029  		 client_manager ! {disconnect, Socket}
0030     end.
0031 
0032 manage(Sockets) ->
0033     receive
0034         {connected, Socket} ->
0035             NewSockets = [Socket | Sockets];
0036         {disconnected, Socket} ->
0037             NewSockets = lists:delete(Socket, Sockets);
0038         {multicast,Socket, Data} ->
0039             multicast(Socket, Sockets, Data),
0040             NewSockets = Sockets
0041     end,
0042     manage(NewSockets).
0043 
0044 multicast(FromSocket, ToSockets, Data) ->
0045     SendData = fun(Socket) -> gen_tcp:send(Socket, Data) end,
0046     Sockets = [ S || S <- ToSockets, S /= FromSocket],
0047     lists:foreach(SendData, Sockets).

3 Responses - What do you think?

  1. I want to quote your post in my blog. It can?
    And you et an account on Twitter?

  2. Sure, feel free to do so, my posts here are all licensed under creative commons. And, I’m @mrinal on twitter :)

  3. Hi,

    Interesting idea about using Erlang for collaboration. I would like to see the code for the client if possible, to be able to gasp the whole concept of client-server sending messages.

Your thoughts or questions: