Permalink
Browse files

Adding support for multiple listeners per gen_nb_server instance

  • Loading branch information...
1 parent aca066e commit bfea2e584a038ae0139903394e6a131243b2e83a @bigkevmcd bigkevmcd committed Jan 9, 2011
View
@@ -1 +1,2 @@
-ebin/*.beam
+ebin/*.beam
+doc
View
@@ -4,7 +4,7 @@ ebin:
mkdir ebin
compile: ebin
- cd src;erl -pa ../../ebin -make
+ cd src;erl -pa ../../../ebin -make
clean:
rm -rf ebin
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -20,52 +20,74 @@
-module(example).
--export([start_link/2]).
+-export([start_link/0,
+ add_listener/3,
+ remove_listener/3]).
--export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
--export([terminate/2, sock_opts/0, new_connection/2]).
+-export([init/2, handle_call/3, handle_cast/2, handle_info/2]).
+-export([terminate/2, sock_opts/0, new_connection/4]).
-behavior(gen_nb_server).
-start_link(IpAddr, Port) ->
- gen_nb_server:start_link(?MODULE, IpAddr, Port, []).
-
-init([]) ->
- {ok, []}.
-
+start_link() ->
+ gen_nb_server:start_link(?MODULE, []).
+
+add_listener(Pid, IpAddr, Port) ->
+ gen_server:call(Pid, {add_listener, IpAddr, Port}).
+
+remove_listener(Pid, IpAddr, Port) ->
+ gen_server:call(Pid, {remove_listener, IpAddr, Port}).
+
+init([], State) ->
+ {ok, State}.
+
+handle_call({add_listener, IpAddr, Port}, _From, State) ->
+ case gen_nb_server:add_listen_socket({IpAddr, Port}, State) of
+ {ok, State1} ->
+ {reply, ok, State1};
+ Error ->
+ {reply, Error, State}
+ end;
+handle_call({remove_listener, IpAddr, Port}, _From, State) ->
+ case gen_nb_server:remove_listen_socket({IpAddr, Port}, State) of
+ {ok, State1} ->
+ {reply, ok, State1};
+ Error ->
+ {reply, Error, State}
+ end;
handle_call(_Msg, _From, State) ->
- {reply, ignored, State}.
+ {reply, ignored, State}.
handle_cast(_Msg, State) ->
- {noreply, State}.
+ {noreply, State}.
handle_info({tcp, Sock, Data}, State) ->
- Me = self(),
- P = spawn(fun() -> worker(Me, Sock, Data) end),
- gen_tcp:controlling_process(Sock, P),
- {noreply, State};
+ Me = self(),
+ P = spawn(fun() -> worker(Me, Sock, Data) end),
+ gen_tcp:controlling_process(Sock, P),
+ {noreply, State};
handle_info(_Msg, State) ->
- {noreply, State}.
+ {noreply, State}.
terminate(_Reason, _State) ->
- ok.
+ ok.
sock_opts() ->
- [binary, {active, once}, {packet, 0}].
+ [binary, {active, once}, {packet, 0}].
-new_connection(Sock, State) ->
- Me = self(),
- P = spawn(fun() -> worker(Me, Sock) end),
- gen_tcp:controlling_process(Sock, P),
- {ok, State}.
+new_connection(_IpAddr, _Port, Sock, State) ->
+ Me = self(),
+ P = spawn(fun() -> worker(Me, Sock) end),
+ gen_tcp:controlling_process(Sock, P),
+ {ok, State}.
worker(Owner, Sock) ->
- gen_tcp:send(Sock, "Hello"),
- inet:setopts(Sock, [{active, once}]),
- gen_tcp:controlling_process(Sock, Owner).
+ gen_tcp:send(Sock, "Hello\n"),
+ inet:setopts(Sock, [{active, once}]),
+ gen_tcp:controlling_process(Sock, Owner).
worker(Owner, Sock, Data) ->
- gen_tcp:send(Sock, Data),
- inet:setopts(Sock, [{active, once}]),
- gen_tcp:controlling_process(Sock, Owner).
+ gen_tcp:send(Sock, Data),
+ inet:setopts(Sock, [{active, once}]),
+ gen_tcp:controlling_process(Sock, Owner).
@@ -1,56 +0,0 @@
-%% Copyright (c) 2009 Hypothetical Labs, Inc.
-
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-
--module(http_server).
-
--export([start/0, start_link/2]).
-
--export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
--export([terminate/2, sock_opts/0, new_connection/2]).
-
--behavior(gen_nb_server).
-
-start() ->
- start_link("0.0.0.0", 9292).
-
-start_link(IpAddr, Port) ->
- gen_nb_server:start_link(?MODULE, IpAddr, Port, []).
-
-init([]) ->
- {ok, []}.
-
-handle_call(_Msg, _From, State) ->
- {reply, ignored, State}.
-
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-handle_info(_Msg, State) ->
- {noreply, State}.
-
-terminate(_Reason, _State) ->
- ok.
-
-sock_opts() ->
- [binary, {active, once}, {packet, 0}].
-
-new_connection(Sock, State) ->
- http_worker:start(Sock),
- {ok, State}.
@@ -1,70 +0,0 @@
--module(http_worker).
-
--behaviour(gen_server).
-
--define(RESPONSE, "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 1\r\n\r\nA").
-%% API
--export([start/1]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--define(SERVER, ?MODULE).
-
--record(state, {sock}).
-
-configure(Pid) ->
- gen_server:call(Pid, configure).
-
-start(Sock) ->
- {ok, Pid} = gen_server:start(?MODULE, [Sock], []),
- gen_tcp:controlling_process(Sock, Pid),
- configure(Pid).
-
-init([Sock]) ->
- {ok, #state{sock=Sock}}.
-
-
-handle_call(configure, _From, #state{sock=Sock}=State) ->
- inet:setopts(Sock, [{active, once}, {packet, http}, binary]),
- {reply, ok, State};
-
-handle_call(_Request, _From, State) ->
- {reply, ignore, State}.
-
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-handle_info({http, Sock, http_eoh}, State) ->
- io:format("RESPONSE~n"),
- inet:setopts(Sock, [{packet, 0}]),
- gen_tcp:send(Sock, list_to_binary(?RESPONSE)),
- inet:setopts(Sock, [{packet, http}, {active, once}]),
- {noreply, State};
-
-handle_info({http, Sock, {http_header, _, _, _, _}}, State) ->
- io:format("HEADER~n"),
- inet:setopts(Sock, [{active, once}]),
- {noreply, State};
-
-handle_info({http, Sock, {http_request, _, _, _}}, State) ->
- io:format("REQUEST~n"),
- inet:setopts(Sock, [{active, once}]),
- {noreply, State};
-
-handle_info({http, Sock, Data}, #state{sock=Sock}=State) ->
- io:format("Data: ~p~n", [Data]),
- gen_tcp:close(Sock),
- {noreply, State};
-
-handle_info(_Info, State) ->
- {noreply, State}.
-
-terminate(_Reason, _State) ->
- ok.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%% Internal function
Oops, something went wrong.

0 comments on commit bfea2e5

Please sign in to comment.