Skip to content

Instantly share code, notes, and snippets.

@lilrooness
Last active October 22, 2018 09:55
Show Gist options
  • Save lilrooness/7c77042d8857c7f9f8fb to your computer and use it in GitHub Desktop.
Save lilrooness/7c77042d8857c7f9f8fb to your computer and use it in GitHub Desktop.
Erlang Chat Program
-module(broadcast).
-export([start/1]).
start(Port) ->
{ok, AcceptSocket} = gen_tcp:listen(Port, [binary, {active, false}]),
io:fwrite("Now listening for new connections"),
% Process managing client connections
ManagerId = spawn(fun() -> manage_clients([]) end),
% Process accepting new connections
spawn(fun() -> listen(AcceptSocket, ManagerId) end).
listen(Socket, ManagerId) ->
{ok, Connection} = gen_tcp:accept(Socket),
ClientPid = spawn(fun() -> handle(Connection, ManagerId) end),
gen_tcp:controlling_process(Connection, ClientPid),
ManagerId ! {newClient, ClientPid}, % notify manager of new client
listen(Socket, ManagerId).
handle(Socket, ManagerId) ->
% Switch to active mode for a single message
inet:setopts(Socket, [{active, once}]),
receive
{tcp, Socket, <<"quit", _/binary>>} ->
gen_tcp:close(Socket);
{tcp, Socket, Message} ->
ManagerId ! {broadcast, Message, self()}, % instruct manager process to broadcast message to clients
handle(Socket, ManagerId);
{send, Message} ->
gen_tcp:send(Socket, Message),
handle(Socket, ManagerId)
end.
% broadcast message to all clients
send_to_clients(Message, Clients) ->
lists:foreach(fun(ClientPid) -> ClientPid ! {send,Message} end, Clients).
manage_clients(Clients) ->
receive
{newClient, Client} ->
io:fwrite("Accepted new connection"),
manage_clients([Client | Clients]);
{broadcast, Message, _} ->
send_to_clients(Message, Clients),
manage_clients(Clients)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment