最近写的一个Erlang与Flash xmlsocket进行通信以及消息分发的简单例子

   大概思路如下
   客户端采用flash,Xmlsocket与服务端通信.由于服务端要对消息进行分发,客户端发送的消息必须具有一定的消息结构以利于erlang收到消息之后对消息进行拆解从而分发,发送的消息结构为 "分类标志:8|源地址长度标志:8|源地址|目的地址长度标志:8|目的地址|消息内容"。分类标志有0,1和2,表示注册和发送私聊或者广播,源地址为发送方注册的昵称,昵称将在erlang里用record来bind该客户端的Socket id,erlang进程将会根据长度标志提取出发送方和接收方.
  
   tcp_socket.erl将以gen_tcp:listen(Port, [binary,{active, false}])的方式在本地打开一个tcp端口接受xmlsocket的连接,接收二进制数据。
   tcp_socket.erl:
  
%% Author: zhongju.mai
%% Created: 2009-12-31
%% Description: TODO: Open a tcp socket for xmlsocket
-module(tcp_socket).
-compile(export_all).
-record(player, {name=none, socket}).
server(Port) -> 
        {ok, ListenSocket} = gen_tcp:listen(Port, [binary,{active, false}]), 
	io:format("~p~n",[ListenSocket]),
        register(clienthandler,spawn(fun()->handle_clients([]) end)),
	wait_socket(ListenSocket). 

     wait_socket(ListenSocket) -> 
        {ok, Socket} = gen_tcp:accept(ListenSocket), 
        io:format("~p~n",[Socket]),
        spawn(?MODULE, wait_socket, [ListenSocket]), 
        get_request(Socket). 
        
     get_request(Socket) -> 
        case gen_tcp:recv(Socket, 0,60000) of 
          {ok, Packet} -> 
	       %消息结构为 状态位:8|源地址长度标志:8|源地址|目的地址长度标志:8|目的地址|消息内容
	      <<State:8,Header:8,Rest/binary>> = Packet,
	      N=Header-48,
              <<Middle:N/binary-unit:8,Rest2/binary>> = Rest,
	      Namee=list_to_atom(binary_to_list(Middle)),
	      if
	          State==48 ->
		        clienthandler ! {connect,Namee,Socket};
		  State==49 ->
		        <<Header2:8,Rest3/binary>> = Rest2,
			N2=Header2-48,
			<<Middle2:N2/binary-unit:8,Rest4/binary>> = Rest3,
			Namee2=list_to_atom(binary_to_list(Middle2)),
		        clienthandler ! {chat,Namee2,Rest4}
		end,
	      io:format("recv~p~n",[Middle]),
          get_request(Socket);
          %gen_tcp:close(Socket);
          {error, Reason} -> 
              io:format("eroor for ~p~n",[Reason])
        end.

      handle_clients(Players) ->
        receive
	{connect,Name,Socket} ->
               Player = #player{name=Name,socket=Socket},
	       Newplayers=[Player|Players],
	       handle_clients(Newplayers);
	{chat,To,Content} ->
	       {value,Tuplefound}=lists:keysearch(To,#player.name,Players),
	       {player,_,Des}=Tuplefound,
	       gen_tcp:send(Des,Content),
	       handle_clients(Players);
	 _ ->
	    true,
	    handle_clients(Players)
	end.

    compile之后可以用tcp_socket:server(9999)打开一个9999的tcp端口.这时可以接收xmlsocket的连接,例如flash发送了"03jim",erlang将会更新一个record,{player,{jim,#socket<...>}} 同理,flash方发送了"14jack3jimhello",erlang将会查找jim对应的socket然后gen_tcp:send(..)放送给jim消息"hello"

    可能不熟吧,对二进制消息进行拆分的时候特别恼火..最后还是强制把类型转换过来,期待高人指点...

你可能感兴趣的:(数据结构,erlang,socket,REST,Flash)