Distribution by another means
Ulf Wiger
etxuwig@REDACTED
Tue Jun 13 18:09:35 CEST 2000
I'm just now building a network of cooperating web servers using
"HTTP-based RPC". That is, the web servers run Erlang, and when they
need to communicate, they use a set of predefined "internal requests"
via HTTP:
query_internal(Host, Port, What, Req) ->
{ok, Sock} = gen_tcp:connect(Host, Port, [binary, {packet, 0}]),
Auth = ccv_auth:internal_pack_user(Req#ccv_req.user),
Query = ["/ccviewer/internal/", What],
Cmd = ["GET ", Query, " HTTP/1.0\r\n"
"Cookie: ", Auth, ";\r\n"
"\r\n"],
ok=io:format("connected~n", []),
gen_tcp:send(Sock, list_to_binary(Cmd)),
do_recv(Sock).
do_recv(Sock) ->
receive
{tcp, Sock, Data} ->
ok=io:format("received ~p~n", [Data]),
{B1,B2} = split_binary(Data, 4),
LengthBytes = binary_to_list(B1),
Length = i32(LengthBytes),
ok=io:format("Length = ~p~n", [Length]),
case size(B2) of
L when L == Length ->
ok=io:format("Got whole packet~n", []),
gen_tcp:close(Sock),
binary_to_term(B2);
_ ->
ok=io:format("wait for more~n", []),
do_recv(Sock, Length, B2)
end
after 10000 ->
exit(timeout)
end.
do_recv(Sock, Length, Bin) ->
receive
{tcp, Sock, Data} ->
Bin2 = list_to_binary([Bin, Data]),
case size(Bin2) of
Length ->
ok=io:format("Got whole packet~n", []),
gen_tcp:close(Sock),
binary_to_term(Bin2);
_ ->
ok=io:format("wait for more~n", []),
do_recv(Sock, Length, Bin2)
end
after 10000 ->
exit(timeout)
end.
i32([B1,B2,B3,B4]) ->
((B1 bsl 24) bor
(B2 bsl 16) bor
(B3 bsl 8) bor
B4);
i32(I) when integer(I) ->
B1 = (I band 16#ff000000) bsr 24,
B2 = (I band 16#00ff0000) bsr 16,
B3 = (I band 16#0000ff00) bsr 8,
B4 = I band 16#000000ff,
[B1, B2, B3, B4].
And the server side looks kinda like this:
ccv_handler({get, "/internal/" ++ Query, Args}, Socket, Env) ->
X = {get, Query, Args},
put(socket, Socket),
Result = case ccv_auth:internal_request(X, Socket, Env) of
{'EXIT', Reason} ->
{error, Reason};
{ok, NewX, Req} ->
put(request, Req),
handle_internal_request(NewX, Req);
Other ->
Other
end,
Bin = term_to_binary(Result),
gen_tcp:send(Socket, [ccv_lib:i32(size(Bin)), Bin]);
Of course, one also needs an HTTP server. Personally, I use a
home-grown, based on Joe's/Luke's pico. A more natural choice perhaps
would be to use INETS, but what fun would that be?
At AXD301, we had a similar problem, and solved it there with CORBA.
It's also reasonably straightforward. I can dig up the code if you'd
like.
/Uffe
On Tue, 13 Jun 2000, Francesco Cesarini wrote:
>Might seem far fetched, but when discussing this problem a few years
>ago, one of the simplest ideas and solutions which came to up was to run
>the calls through the WWW proxy, masking the http requests as arguments
>in the URL.
>
>//fc
>
>Sean Hinde wrote:
>>
>> I need to connect up two separate Erlang/OTP based systems which are
>> separated amongst other things by a firewall.
>>
>> I don't want to run the standard distribution mechanism between the two
>> systems for various reasons but need a simple rpc type call in both
>> directions.
>>
>> Out of all the mechanisms available in OTP what are peoples views on which
>> would be the quickest and easiest mechanism requiring least overhead and
>> minimum complexity. Full on CORBA would work but is probably overkill??
>>
>> Views?
>>
>> Sean
>
>
--
Ulf Wiger tfn: +46 8 719 81 95
Network Architecture & Product Strategies mob: +46 70 519 81 95
Ericsson Telecom AB, Datacom Networks and IP Services
Varuvägen 9, Älvsjö, S-126 25 Stockholm, Sweden
More information about the erlang-questions
mailing list