Skip to content

Commit

Permalink
Add echo_handler module for Application Layer
Browse files Browse the repository at this point in the history
  • Loading branch information
kkiselev committed Jun 16, 2013
1 parent 549548a commit 252ea71
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
1 change: 0 additions & 1 deletion example-app/_deps/cowboy
Submodule cowboy deleted from 830d4c
1 change: 0 additions & 1 deletion example-app/_deps/rack
Submodule rack deleted from 16535a
1 change: 0 additions & 1 deletion example-app/_deps/ranch
Submodule ranch deleted from 53be20
7 changes: 3 additions & 4 deletions example-app/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
require 'websocket-eventmachine-client'
require 'json'

@ws_host = '127.0.0.1'
@ws_port = '8085'
@ws_host = ARGV[0]
@ws_port = ARGV[1].to_i

EM.run do
ws = WebSocket::EventMachine::Client.connect(:uri => "ws://#{@ws_host}:#{@ws_port}/ws")
Expand All @@ -21,8 +21,7 @@
"ts" => ts,
"action" => "main/index.json",
"query_str" => "",
"method" => "GET",
"params" => {},
"method" => "GET"
}

puts "Sending..."
Expand Down
4 changes: 2 additions & 2 deletions example-app/src/echo_get_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ start(_Type, _Args) ->

Dispatch = cowboy_router:compile([
{'_', [
{"/ws", cowboy_websocket_rack_handler, [{path, Path}]},
{'_', cowboy_rack_handler, [{path, Path}]}
{"/ws", cowboy_websocket_rack_handler, [{path, Path}, {handler, echo_handler}]},
{'_', cowboy_rack_handler, [{path, Path}, {handler, echo_handler}]}
]}
]),
{ok, _} = cowboy:start_http(http, 100, [{port, 8085}], [
Expand Down
93 changes: 93 additions & 0 deletions example-app/src/echo_handler.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
-module(echo_handler).
-author('Konstantin Kiselyov, <kiseljovkn@gmail.com>').

-export([
parse_message/1,
request_info_for_message/1,
encode_transport_response/2,
encode_rack_response/3
]).

%%% Application layer protocol

-record(ra_protocol_message, {
unique = <<"">>,
ts = 0,
action = <<"">>,
method = <<"GET">>,
query_str = <<"">>,
params = {struct, []},
response = <<"{}">>
}).

if_undefined_then_value(X, Value) ->
case X of
undefined -> Value;
_ -> X
end.

parse_message(Message) ->
{struct, PropList} = mochijson2:decode(Message),

% extract parameters
Unique = if_undefined_then_value(proplists:get_value(<<"unique">>, PropList), <<"">>),
Ts = if_undefined_then_value(proplists:get_value(<<"ts">>, PropList), 0),
Action = if_undefined_then_value(proplists:get_value(<<"action">>, PropList), <<"">>),
Query = if_undefined_then_value(proplists:get_value(<<"query_str">>, PropList), <<"">>),
Method = if_undefined_then_value(proplists:get_value(<<"method">>, PropList), <<"GET">>),
Params = if_undefined_then_value(proplists:get_value(<<"params">>, PropList), {struct, []}),

% create result message
#ra_protocol_message{
unique = Unique,
ts = Ts,
action = Action,
query_str = Query,
method = Method,
params = Params
}.

request_info_for_message(ProtocolMessage) ->
RequestMethod = ProtocolMessage#ra_protocol_message.method,
Path = ProtocolMessage#ra_protocol_message.action,
QueryString = ProtocolMessage#ra_protocol_message.query_str,
ServerName = <<"localhost">>,
ServerPort = 8080,
{RequestMethod, Path, QueryString, ServerName, ServerPort}.

encode_transport_response(Response, Message) ->
Unique = Message#ra_protocol_message.unique,
Ts = list_to_binary(integer_to_list(Message#ra_protocol_message.ts)),
Action = Message#ra_protocol_message.action,
Query = Message#ra_protocol_message.query_str,
Method = Message#ra_protocol_message.method,
Params = mochijson2:encode(Message#ra_protocol_message.params),

UniquePart = <<"\"unique\":", "\"", Unique/binary, "\"">>,
TsPart = <<"\"ts\":", Ts/binary>>,
ActionPart = <<"\"action\":", "\"", Action/binary, "\"">>,
QueryPart = <<"\"query_str\":", "\"", Query/binary, "\"">>,
MethodPart = <<"\"method\":", "\"", Method/binary, "\"">>,
ParamsPart = <<"\"params\":", Params/binary>>,
ResponsePart = <<"\"response\":", Response/binary>>,

_Result = <<"{",
UniquePart/binary, ",",
TsPart/binary, ",",
ActionPart/binary, ",",
QueryPart/binary, ",",
MethodPart/binary, ",",
ParamsPart/binary, ",",
ResponsePart/binary,
"}">>.

encode_rack_response(Status, ResponseHeaders, ResponseBody) ->
StatusValue = list_to_binary(integer_to_list(Status)),
_ResponseHeadersValue = ResponseHeaders,
ResponseBodyValue = ResponseBody,
<<"{",
"\"status\":", StatusValue/binary, ",",
% "\"headers\":\"", ResponseHeadersValue/binary, "\",",
"\"body\":", ResponseBodyValue/binary,
"}">>.

0 comments on commit 252ea71

Please sign in to comment.