Discovery channel
Mix.install([
{:jason, "~> 1.3"},
{:slipstream, "~> 1.0"},
{:req, "~> 0.3.0"}
])
Root
Memory
Root User
defmodule Echolocation do
use Slipstream,
restart: :temporary
require Logger
def start_link(args) do
Slipstream.start_link(__MODULE__, args)
end
@impl Slipstream
def init(%{config: config, topic: topic}) do
case connect(config) do
{:ok, socket} ->
{:ok, socket |> assign(:topic, topic)}
{:error, reason} ->
Logger.error(
"Could not start #{__MODULE__} because of " <>
"validation failure: #{inspect(reason)}"
)
:ignore
end
end
@impl Slipstream
def handle_connect(socket) do
{:ok,
socket
|> join(socket.assigns.topic)}
end
@impl Slipstream
def handle_join(topic, _join_response, socket) do
# an asynchronous push with no reply:
# push(socket, @topic, "ping", %{"hello" => "there"})
{:ok, socket}
end
@impl Slipstream
def handle_message(topic, "memory_formation", message, socket) do
Logger.info(
# <>
"Memories Remembered"
)
IO.inspect(message)
{:ok, socket}
end
@impl Slipstream
def handle_message(topic, "assembly_initiation", message, socket) do
Logger.info(
# <>
"Entering into the Assembly"
)
IO.inspect(message)
{:ok, socket}
end
def handle_message(topic, "assembly_" <> presence_event, message, socket) do
Logger.info(
# <>
"Something happened in your Assembly::" <> presence_event
)
IO.inspect(message)
{:ok, socket}
end
@impl Slipstream
def handle_reply(ref, reply, socket) do
IO.inspect(reply, label: "reply to my request")
{:ok, socket}
end
def handle_call({:say, goodbyein}, _from, socket) do
IO.puts("server going bye bye in T-#{inspect(goodbyein)}s")
:timer.send_interval(:timer.seconds(goodbyein), self(), :stop)
{:reply, {:ok, :saygoodbye}, socket}
end
def handle_call({:add, memory}, _from, socket) do
IO.puts("Push memory to socket with data #{inspect(memory)}")
push(socket, socket.assigns.topic, {:memory, "formation"}, memory)
{:reply, {:ok, :saygoodbye}, socket}
end
def handle_call({:location_update, message}, _from, socket) do
# message format %{name: "live", geohash: 612321341243213}
IO.puts("location sent for update: #{inspect(message)}")
push(socket, socket.assigns.topic, "location_update", message)
{:reply, {:ok, :hao}, socket}
end
@impl Slipstream
def handle_message(topic, event, message, socket) do
Logger.error(
"Was not expecting a push from the server. Heard: " <>
inspect({topic, event, message})
)
{:ok, socket}
end
@impl Slipstream
def handle_disconnect(_reason, socket) do
{:stop, :normal, socket}
end
@impl Slipstream
def handle_info(:stop, socket) do
IO.puts("sayonara mai gud ser")
{:stop, :normal, socket}
end
@impl Slipstream
def handle_info(:request_metrics, socket), do: {:noreply, socket}
@impl Slipstream
def terminate(reason, socket) do
Logger.debug("shutting down: " <> inspect(reason))
disconnect(socket)
end
end
User 1 Antoine
domain = "localhost:4000"
id = "6d7b0e7c-a633-4a8a-8d85-b8a493109bd4"
token = Req.get!("http://" <> domain <> "/api/devland/flameon?user=#{id}").body["payload"]
topic = "memory:user:#{id}"
config = %{
topic: topic,
config: [
uri: "ws://" <> domain <> "/socket/websocket?token=" <> token,
reconnect_after_msec: [200, 500, 1_000, 2_000]
]
}
{:ok, pid} =
case Echolocation.start_link(config) do
{:ok, _pid} = data -> data
{:error, {:already_started, pid}} -> {:ok, pid}
{:error, _} = data -> data
end
User2 LKY
domain = "localhost:4000"
id = "6d7b0e7c-a633-4a8a-8d85-b8a493109bd4"
token = Req.get!("http://" <> domain <> "/api/devland/flameon?user=#{id}").body["payload"]
topic = "memory:user:#{id}"
config = %{
topic: topic,
config: [
uri: "ws://" <> domain <> "/socket/websocket?token=" <> token,
reconnect_after_msec: [200, 500, 1_000, 2_000]
]
}
{:ok, pid} =
case Echolocation.start_link(config) do
{:ok, _pid} = data -> data
{:error, {:already_started, pid}} -> {:ok, pid}
{:error, _} = data -> data
end
GenServer.call(pid, {:say, 3})
Discovery
Socket Initialization
defmodule BeluSocket do
use Slipstream,
restart: :temporary
require Logger
@topic "discovery:usr:9bf9c443-f89b-460a-972d-6704ae66823d"
def start_link(args) do
Slipstream.start_link(__MODULE__, args, name: __MODULE__)
end
@impl Slipstream
def init(config) do
case connect(config) do
{:ok, socket} ->
{:ok, socket}
{:error, reason} ->
Logger.error(
"Could not start #{__MODULE__} because of " <>
"validation failure: #{inspect(reason)}"
)
:ignore
end
end
@impl Slipstream
def handle_connect(socket) do
{:ok, join(socket, @topic)}
end
@impl Slipstream
def handle_join(@topic, _join_response, socket) do
# an asynchronous push with no reply:
# push(socket, @topic, "ping", %{"hello" => "there"})
{:ok, socket}
end
@impl Slipstream
def handle_message(@topic, "loc_reverie", message, socket) do
Logger.info(
# <>
"Orbs Remembered in Location"
)
IO.inspect(message)
{:ok, socket}
end
def handle_call({:say, goodbyein}, _from, socket) do
IO.puts("server going bye bye in T-#{inspect(goodbyein)}s")
:timer.send_interval(:timer.seconds(goodbyein), self(), :stop)
{:reply, {:ok, :saygoodbye}, socket}
end
def handle_call({:location_update, message}, _from, socket) do
# message format %{name: "live", geohash: 612321341243213}
IO.puts("location sent for update: #{inspect(message)}")
push(socket, @topic, "location_update", message)
{:reply, {:ok, :hao}, socket}
end
@impl Slipstream
def handle_message(@topic, event, message, socket) do
Logger.error(
"Was not expecting a push from the server. Heard: " <>
inspect({@topic, event, message})
)
{:ok, socket}
end
@impl Slipstream
def handle_disconnect(_reason, socket) do
{:stop, :normal, socket}
end
@impl Slipstream
def handle_info(:stop, socket) do
IO.puts("sayonara mai gud ser")
{:stop, :normal, socket}
end
@impl Slipstream
def handle_info(:request_metrics, socket), do: {:noreply, socket}
@impl Slipstream
def terminate(reason, socket) do
Logger.debug("shutting down: " <> inspect(reason))
disconnect(socket)
end
end
Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"]
token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmeXJfaWQiOiIwYjNnZDVYVUd0TlA2bHFRZWFuNElBcDdvZ0czIiwidGVycml0b3J5Ijp7ImhvbWUiOnsiaGFzaCI6NjI4MDIxMjk3NjY2MjI0MTI3LCJyYWRpdXMiOjE2NjY0NTYyNjd9LCJ3b3JrIjp7Imhhc2giOjYyNzk4NjQ0Njk1MjM0OTY5NSwicmFkaXVzIjoxNjY2NDU2MjY3fX0sInVzZXJfaWQiOiI5YmY5YzQ0My1mODliLTQ2MGEtOTcyZC02NzA0YWU2NjgyM2QiLCJ1c2VybmFtZSI6Inp1a28iLCJleHAiOjE2NjY2ODU5MzYsImlhdCI6MTY2NjY4NDcyNCwiaXNzIjoiUHJpbmNldG9uIiwicm9sZSI6InBsZWIiLCJzdWIiOiJTY3JhdGNoQmFjIn0.pEh-6t-I_1YZ1wxxf5lWv2I6hMmybZMtLyMyJSyZmCU"
domain = "ws://localhost:4000"
config = [
uri: domain <> "/socket/websocket?token=" <> token,
reconnect_after_msec: [200, 500, 1_000, 2_000]
]
{:ok, pid} = BeluSocket.start_link(config)
# {:error, {:already_started, pid}} = BeluSocket.start_link(config)
message = %{"name" => "home", "geohash" => 628_021_297_666_224_127}
# GenServer.call(pid, {:say, 1})
GenServer.call(
pid,
{:location_update, %{"name" => "live", "locations" => 628_021_598_572_208_127}}
)