If you are not familar with erlang sockets you can review my article about Erlang TCP sockets with gen_tcp & sampe echo server it should help to understand Erlang TCP sockets themselves.
Some time ago I had to use sockets from Adobe Flash/Flex, so needed a simple one implemented in Erlang. I do not suggest to use it exactly like it listed below, but you may find some idea for your project there. I hope that you know what I am talking about, if you are reading this article, so do not want to waist your time...
Here is flex code to load policy file from non-standard port:
Security.loadPolicyFile("xmlsocket://localhost:8001");
Here is an example of policy file:
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <site-control permitted-cross-domain-policies="all"/> <allow-access-from domain="*" to-ports="8000-8002"/> </cross-domain-policy>
And here is erlang server code
-module(policy_server).
-author('Sergiy Dzysyak ').
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,terminate/2, code_change/3]).
-export([start/1, stop/0, accept_loop/1]).
-define(TCP_OPTIONS, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]).
start(Port)->
gen_server:start({local, ?MODULE}, ?MODULE, [Port], []).
stop()->
gen_server:cast(?MODULE, {stop}).
accept_loop(LSocket) ->
{ok, Socket} = gen_tcp:accept(LSocket),
% Let the server spawn a new process and replace this loop
% with the echo loop, to avoid blocking
gen_server:cast(?MODULE, {accepted}),
read(Socket).
% To be more robust we should be using spawn_link and trapping exits
accept(LSocket) ->
spawn_link(?MODULE, accept_loop, [LSocket]),
LSocket.
read(Socket)->
{ok, _Data} = gen_tcp:recv(Socket, 0),
{ok, Bin} = file:read_file("/srv/www/crossdomain.xml"),
gen_tcp:send(Socket, Bin).
init([Port]) ->
% set this so we can catch death of logged in pids:
%process_flag(trap_exit, true),
case gen_tcp:listen(Port, ?TCP_OPTIONS) of
{ok, LSocket} ->
{ok, accept(LSocket)};
{error, Reason} ->
{stop, Reason}
end.
handle_cast({accepted}, State) ->
{noreply, accept(State)};
handle_cast({stop}, State) ->
{stop, normal, State}.
% handle death and cleanup of logged in processes
handle_info(Info, State) ->
case Info of
{'EXIT', _Pid, _Why} ->
{noreply, State};
Wtf ->
io:format("Caught unhandled message: ~wn", [Wtf]),
{noreply, State}
end.
handle_call(_Msg, _From, State) -> {noreply, State}.
terminate(Reason, State) ->
io:format("Terminating: ~p~n", [Reason]),
gen_tcp:close(State),
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Internal functions