Skip to content

Instantly share code, notes, and snippets.

@sshine
Created October 31, 2013 10:22
Show Gist options
  • Save sshine/7247430 to your computer and use it in GitHub Desktop.
Save sshine/7247430 to your computer and use it in GitHub Desktop.
-module(simple2).
-export([start/0]).
-define(PORT, 33333).
start() ->
{ok, spawn(fun listener/0)}.
listener() ->
ChatMaster = spawn(fun() -> chatmaster(dict:new()) end),
{ok, ListenSocket} = gen_tcp:listen(?PORT, [binary, {active, true}]),
spawn(fun() -> acceptor(ListenSocket, ChatMaster) end),
timer:sleep(infinity). % Keep this process alive while listening
acceptor(ListenSocket, ChatMaster) ->
{ok, _Socket} = gen_tcp:accept(ListenSocket),
spawn(fun() -> acceptor(ListenSocket, ChatMaster) end),
WorkerRef = make_ref(),
WorkerPid = self(),
ChatMaster ! {worker, WorkerRef, {WorkerPid, "John"}},
worker(WorkerRef, ChatMaster).
worker(WorkerRef, ChatMaster) ->
receive
{tcp, Socket, <<"QUIT", _/binary>>} ->
ChatMaster ! {quit, WorkerRef},
gen_tcp:close(Socket),
worker(WorkerRef, ChatMaster);
{tcp, Socket, <<"NAME ", name/binary>>} ->
io:format("Got NAME: ~p~n", [name]),
gen_tcp:send(Socket, ["Hello ", name, "\r\n"]),
worker(WorkerRef, ChatMaster);
{tcp, _Socket, What} ->
io:format("Got: ~p~n", [What]),
worker(WorkerRef, ChatMaster)
after 10000 ->
io:format("No message in worker ~p~n", [self()]),
worker(WorkerRef, ChatMaster)
end.
chatmaster(Workers) ->
receive
{worker, WorkerRef, WorkerDetails = {_WorkerPid, _WorkerName}} ->
WorkersNew = dict:store(WorkerRef, WorkerDetails, Workers),
chatmaster(WorkersNew);
{quit, WorkerRef} ->
{_QuitterPid, QuitterName} = dict:find(WorkerRef, Workers),
WorkersNew = dict:erase(WorkerRef, Workers),
dict:map(fun(_K, V = {WorkerPid, _WorkerName}) ->
WorkerPid ! {quit, QuitterName},
V
end, WorkersNew),
chatmaster(WorkersNew)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment