add basic floof handling
This commit is contained in:
parent
be957afe44
commit
d4f5efca9d
|
@ -4,6 +4,7 @@ defmodule Chat.Application do
|
|||
@moduledoc false
|
||||
|
||||
use Application
|
||||
require Logger
|
||||
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
|
@ -13,9 +14,17 @@ defmodule Chat.Application do
|
|||
# Start the PubSub system
|
||||
{Phoenix.PubSub, name: Chat.PubSub},
|
||||
# Start the Endpoint (http/https)
|
||||
ChatWeb.Endpoint
|
||||
ChatWeb.Endpoint,
|
||||
# Start a worker by calling: Chat.Worker.start_link(arg)
|
||||
# {Chat.Worker, arg}
|
||||
# Start the message handler
|
||||
Chat.Floof,
|
||||
|
||||
# Start the relay
|
||||
{Task, fn ->
|
||||
Floof.Distributor.register(self())
|
||||
relay_loop()
|
||||
end}
|
||||
]
|
||||
|
||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||
|
@ -31,4 +40,20 @@ defmodule Chat.Application do
|
|||
ChatWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
|
||||
defp relay_loop do
|
||||
receive do
|
||||
{:fwdxfer, {_, {:XferBlob, source, _, _, _, xfinner}}} ->
|
||||
{:ok, dcdi} = :FloofProtocol.decode(:XferInner, xfinner)
|
||||
{:XferInner, topic, attrs, _, data} = dcdi
|
||||
if topic == [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 14}, "Chat"}] do
|
||||
[{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 4}, name}] = attrs
|
||||
{:ok, source_encd} = :FloofProtocol.encode(:RDNSequence, source)
|
||||
source_encd = Base.url_encode64(source_encd)
|
||||
ChatWeb.Endpoint.broadcast!("room:lobby", "shout", %{name: source_encd <> " :: " <> name, message: data})
|
||||
end
|
||||
x -> Logger.error("unable to handle message #{inspect(x)}")
|
||||
end
|
||||
relay_loop()
|
||||
end
|
||||
end
|
||||
|
|
37
lib/chat/floof.ex
Normal file
37
lib/chat/floof.ex
Normal file
|
@ -0,0 +1,37 @@
|
|||
defmodule Chat.Floof do
|
||||
use Agent
|
||||
require Logger
|
||||
|
||||
defstruct secret: "", source: []
|
||||
|
||||
def start_link do
|
||||
Agent.start_link(fn ->
|
||||
secret_file = Application.fetch_env!(:chat, :secret_file)
|
||||
source = Application.fetch_env!(:chat, :source)
|
||||
{:ok, secret} = File.read(secret_file)
|
||||
%Chat.Floof{secret: secret, source: source}
|
||||
end, name: __MODULE__)
|
||||
end
|
||||
|
||||
def setup do
|
||||
# generate and save a keypair
|
||||
kp = :enacl.sign_keypair()
|
||||
secret_file = Application.fetch_env!(:chat, :secret_file)
|
||||
source = Application.fetch_env!(:chat, :source)
|
||||
:ok = File.write(secret_file, kp.secret)
|
||||
{:ok, pkname} = :FloofProtocol.encode(:RDNSequence, source)
|
||||
pubkey_config = Application.fetch_env!(:floof, :pubkey_config)
|
||||
:ok = File.write(pubkey_config.keydb <> "/" <> Base.url_encode64(pkname), kp.public)
|
||||
end
|
||||
|
||||
def send_message(name, data) do
|
||||
msg_topic = [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 14}, "Chat"}]
|
||||
msg_attrs = [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 4}, name}]
|
||||
msg_inner = Floof.Message.pack_inner(msg_topic, msg_attrs, :info, data)
|
||||
Agent.cast(__MODULE__, fn state ->
|
||||
msg_outer = Floof.Message.build_outer(state.source, 255, [], state.secret, msg_inner)
|
||||
Floof.Message.emit(msg_outer)
|
||||
state
|
||||
end)
|
||||
end
|
||||
end
|
|
@ -21,6 +21,7 @@ defmodule ChatWeb.RoomChannel do
|
|||
# broadcast to everyone in the current topic (room:lobby).
|
||||
@impl true
|
||||
def handle_in("shout", payload, socket) do
|
||||
Chat.Floof.send_message(payload.name, payload.message)
|
||||
broadcast(socket, "shout", payload)
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue