Add remote request capability
This commit is contained in:
parent
45f55083fc
commit
f1bd4a0fdd
6 changed files with 28 additions and 188 deletions
|
|
@ -7,19 +7,24 @@ defmodule BirdyChat.Dispatcher do
|
|||
end
|
||||
|
||||
def send_to_remote(%{server: server, to: to} = message) do
|
||||
{name, base_url} =
|
||||
{_name, base_url} =
|
||||
BirdyChat.Identity.peers()
|
||||
|> Enum.find(fn {name, _url} -> name == server end)
|
||||
|
||||
api_url = base_url <> "/api/internal"
|
||||
token = Phoenix.Token.sign(BirdyChatWeb.Endpoint, "serverAuth", to)
|
||||
|
||||
result =
|
||||
{_request, result} =
|
||||
Req.new(url: api_url, retry: false, method: :post)
|
||||
|> Req.merge(req_opts())
|
||||
|> Req.Request.put_new_header("authorization", token)
|
||||
|> Req.merge(json: message)
|
||||
|> Req.Request.run_request()
|
||||
|
||||
# Handle more when you encounter errors
|
||||
case result do
|
||||
%Req.Response{status: 201} -> :ok
|
||||
end
|
||||
end
|
||||
|
||||
def req_opts do
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
defmodule BirdyChatWeb.ServerChannel do
|
||||
use BirdyChatWeb, :channel
|
||||
|
||||
@impl true
|
||||
def join("server:" <> server_id, payload, socket) do
|
||||
if authorised?(payload, server_id) do
|
||||
{:ok, socket}
|
||||
else
|
||||
{:error, %{reason: "unauthorised"}}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_in("new_message", {:binary, message}, socket) do
|
||||
result = :erlang.binary_to_term(message, [:safe])
|
||||
|
||||
# TODO: Add validation that this is the right server.
|
||||
case BirdyChat.Message.validate(result) do
|
||||
{:ok, changeset} ->
|
||||
case BirdyChat.MessageWriter.write(changeset.changes) do
|
||||
:ok ->
|
||||
{:reply, {:ok, {:binary, message}}, socket}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This is how we send messages
|
||||
def broadcast!(peer, message) do
|
||||
channel = "server:#{peer}"
|
||||
encoded_message = :erlang.term_to_binary(message)
|
||||
BirdyChatWeb.Endpoint.broadcast!(channel, "new_message", {:binary, encoded_message})
|
||||
end
|
||||
|
||||
# Simple token-based authentication. Servers should use the same Phoenix secret key so they will
|
||||
# have the basis for generating tokens.
|
||||
defp authorised?(%{"token" => token}, server_id) do
|
||||
case Phoenix.Token.verify(BirdyChatWeb.Endpoint, "serverAuth", token, max_age: 86400) do
|
||||
{:ok, id} -> id == server_id
|
||||
{:error, :invalid} -> false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
defmodule BirdyChatWeb.ServerSocket do
|
||||
use Phoenix.Socket
|
||||
|
||||
# A Socket handler
|
||||
#
|
||||
# It's possible to control the websocket connection and
|
||||
# assign values that can be accessed by your channel topics.
|
||||
|
||||
## Channels
|
||||
|
||||
channel "server:*", BirdyChatWeb.ServerChannel
|
||||
|
||||
# Socket params are passed from the client and can
|
||||
# be used to verify and authenticate a user. After
|
||||
# verification, you can put default assigns into
|
||||
# the socket that will be set for all channels, ie
|
||||
#
|
||||
# {:ok, assign(socket, :user_id, verified_user_id)}
|
||||
#
|
||||
# To deny connection, return `:error` or `{:error, term}`. To control the
|
||||
# response the client receives in that case, [define an error handler in the
|
||||
# websocket
|
||||
# configuration](https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#socket/3-websocket-configuration).
|
||||
#
|
||||
# See `Phoenix.Token` documentation for examples in
|
||||
# performing token verification on connect.
|
||||
@impl true
|
||||
def connect(_params, socket, _connect_info) do
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
# Socket IDs are topics that allow you to identify all sockets for a given user:
|
||||
#
|
||||
# def id(socket), do: "user_socket:#{socket.assigns.user_id}"
|
||||
#
|
||||
# Would allow you to broadcast a "disconnect" event and terminate
|
||||
# all active sockets and channels for a given user:
|
||||
#
|
||||
# Elixir.BirdyChatWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{})
|
||||
#
|
||||
# Returning `nil` makes this socket anonymous.
|
||||
@impl true
|
||||
def id(socket), do: "user_socket:#{socket.assigns.server_id}"
|
||||
end
|
||||
|
|
@ -15,10 +15,6 @@ defmodule BirdyChatWeb.Endpoint do
|
|||
websocket: [connect_info: [session: @session_options]],
|
||||
longpoll: [connect_info: [session: @session_options]]
|
||||
|
||||
socket "/socket", BirdyChatWeb.ServerSocket,
|
||||
websocket: true,
|
||||
longpoll: false
|
||||
|
||||
# Serve at "/" the static files from "priv/static" directory.
|
||||
#
|
||||
# When code reloading is disabled (e.g., in production),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue