Skip to content

Instantly share code, notes, and snippets.

@phroggyy
Last active May 7, 2016 19:53
Show Gist options
  • Save phroggyy/14945cd762089b4388f5480a8f852715 to your computer and use it in GitHub Desktop.
Save phroggyy/14945cd762089b4388f5480a8f852715 to your computer and use it in GitHub Desktop.
A super basic WS server
defmodule Bsocial do
use Application
def start(_type, _args) do
import Supervisor.Spec
children = [
supervisor(Task.Supervisor, [[name: Bsocial.ConnectionsSupervisor]]),
worker(Task, [Bsocial.Server, :start, [4000]])
]
opts = [strategy: :one_for_one, name: Bsocial.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule Bsocial.Server do
def start(port) do
server = Socket.Web.listen! port
# For now, we keep it to one chat room for PoC simplicity
name = Bsocial.Chat
:pg2.create(name: name)
loop_acceptor(server, name)
end
defp loop_acceptor(server, chat_name) do
client = server |> Socket.Web.accept!
client |> Socket.Web.accept!
# Start our message sending process
{:ok, messaging_pid} = Task.Supervisor.start_child(Bsocial.ConnectionsSupervisor, fn -> handle_messages(client, chat_name) end)
:pg2.join(chat_name, messaging_pid)
{:ok, _} = Task.Supervisor.start_child(Bsocial.ConnectionsSupervisor, fn -> serve(client, messaging_pid) end)
loop_acceptor(server, chat_name)
end
defp serve(client, messagingProcess) do
message = client |> Socket.Web.recv!
send(messagingProcess, {:external, message})
serve(client, messagingProcess)
end
defp handle_messages(client, chat_name) do
receive do
{:internal, message} ->
# It's internal so it should be sent to client
client |> Socket.Web.send!(message)
{:external, message} ->
# A new message arrived from a web client, send to other connections
# Fetch the PIDs of other connections in the channel
members = :pg2.get_members(chat_name)
# broadcast it to the other connections
for process <- members, process != self() do
send(process, message)
end
_ ->
# Something's probably wrong, throw an error or handle it ¯\_(ツ)_/¯
throw {:error, "Unrecognized sender"}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment