2010/11/12

Erlang + Websocket でCanvas共有

拙作のerlang_websocket_serverを用いて、Canvas共有をErlangに移植しました。
非同期メッセージパッシングというパラダイムのおかげで簡単に書けます。

こちらです!どんどん落書きしてください!
http://etsukata.com/erl/cvws.html
ChromeおよびSafariで動作確認しています。複数のウインドウを立ち上げて描いてみてください。

クライアントサイドのコードはNode.js版と全く一緒です。
サーバーサイドのコードを以下に掲載します。

githubでお読みになると、横スクロールがなくて見やすいです。
https://github.com/Etsukata/erlang_websocket_server/blob/master/example/canvas_sharing_handler.erl

-module(canvas_sharing_handler).
-import(websocket_server, [unicast/2, broadcast/2, sendall/1]).
-compile(export_all).

go() -> websocket_server:start("etsukata.com", 9000, ?MODULE, canvas_sharing_handler, [[],[]]).

canvas_sharing_handler(IDList, PointList) ->
  receive
    {open, ConnectionID} ->
      broadcast("@NC:" ++ ConnectionID, ConnectionID),
      unicast("@ID:" ++ ConnectionID, ConnectionID),
      StrIDList = lists:foldr(fun(X, Xs) -> X ++ "," ++ Xs end, "", IDList),
      Str = case StrIDList of
              []   -> [];
              _Any -> lists:sublist(StrIDList, length(StrIDList) -1)
            end,
      unicast("@PT:" ++ Str, ConnectionID),
      lists:foreach(fun(X) -> unicast(X, ConnectionID) end, lists:reverse(PointList)),
      canvas_sharing_handler([ConnectionID|IDList], PointList);
    {message, Data, ConnectionID} ->
      case lists:member($@, Data) of
        true ->
          case string:substr(Data, 1, 3) of
            "@CU" ->
              broadcast(Data, ConnectionID),
              canvas_sharing_handler(IDList, []);
            _Any ->
              canvas_sharing_handler(IDList, PointList)
          end;
        false ->
          broadcast(Data, ConnectionID),
          canvas_sharing_handler(IDList, [Data|PointList])
      end;
    {closed, ConnectionID} ->
      broadcast("@CL:" ++ ConnectionID, ConnectionID),
      canvas_sharing_handler(lists:delete(ConnectionID,IDList), PointList);
    Any ->
      io:format("Any:~w~n", [Any]),    
      canvas_sharing_handler(IDList, PointList)
  end.
Node.js版のソースコードとほとんど長さは変わっていません。
Node.jsのスピード感のある開発も楽しいです。しかしErlangのメッセージパッシングで考えたほうがほうが単純に物事を捉えることができ、これもまた楽しいのです。僕はNode.jsとErlang、どっちも好きです!

2 件のコメント:

  1. 魅力あふれるソースコードが激しい横スクロールで読みにくいです。

    返信削除
  2. ですねー。Syntax Highlighterつかってみたものの、、、。
    Githubへのリンク加えました。

    返信削除