diff options
Diffstat (limited to 'shard/lib/app/chat.ex')
-rw-r--r-- | shard/lib/app/chat.ex | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/shard/lib/app/chat.ex b/shard/lib/app/chat.ex index 53767ef..61403b8 100644 --- a/shard/lib/app/chat.ex +++ b/shard/lib/app/chat.ex @@ -7,6 +7,10 @@ defmodule SApp.Chat do %SApp.Chat.Manifest{channel: channel_name} + A private chat room manifest is of the form: + + %SApp.Chat.PrivChat.Manifest{pk_list: ordered_list_of_authorized_pks} + Future improvements: - message signing - storage of the chatroom messages to disk @@ -22,6 +26,10 @@ defmodule SApp.Chat do alias SData.MerkleSearchTree, as: MST + # ========= + # MANIFESTS + # ========= + defmodule Manifest do defstruct [:channel] end @@ -33,6 +41,24 @@ defmodule SApp.Chat do end + defmodule PrivChat.Manifest do + defstruct [:pk_list] + + def new(pk_list) do + %__MODULE__{pk_list: Enum.sort(pk_list)} + end + end + + defimpl Shard.Manifest, for: PrivChat.Manifest do + def start(m) do + DynamicSupervisor.start_child(Shard.DynamicSupervisor, {SApp.Chat, m}) + end + end + + # ========== + # MAIN LOGIC + # ========== + @doc """ Start a process that connects to a given channel """ @@ -44,7 +70,6 @@ defmodule SApp.Chat do Initialize channel process. """ def init(manifest) do - %Manifest{channel: channel} = manifest id = SData.term_hash manifest case Shard.Manager.register(id, manifest, self()) do @@ -62,12 +87,16 @@ defmodule SApp.Chat do mst = %MST{store: %SApp.PageStore{pid: page_store}, cmp: &msg_cmp/2, root: root} - group = %SNet.PubShardGroup{id: id} - SNet.Group.init_lookup(group, self()) + netgroup = case manifest do + %Manifest{channel: _channel} -> + %SNet.PubShardGroup{id: id} + %PrivChat.Manifest{pk_list: pk_list} -> + %SNet.PrivGroup{pk_list: pk_list} + end + SNet.Group.init_lookup(netgroup, self()) {:ok, - %{channel: channel, - id: id, - group: group, + %{id: id, + netgroup: netgroup, manifest: manifest, page_store: page_store, mst: mst, @@ -114,13 +143,19 @@ defmodule SApp.Chat do for pid <- state.subs do if Process.alive?(pid) do - send(pid, {:chat_send, state.channel, msgitem}) + send(pid, {:chat_send, state.manifest, msgitem}) end end notif = {state.id, nil, {:append, prev_root, msgitem, mst.root}} - SNet.Group.broadcast(state.group, notif) + SNet.Group.broadcast(state.netgroup, notif) + + {:noreply, state} + end + def handle_cast({:peer_connected, conn_pid}, state) do + # this is called by the SNet.Group thing so it is already authenticated + SNet.Manager.send_pid(conn_pid, {state.id, nil, {:root, state.mst.root}}) {:noreply, state} end @@ -129,7 +164,7 @@ defmodule SApp.Chat do connected to asks to recieve data for this channel. """ def handle_cast({:interested, conn_pid, auth}, state) do - if SNet.Group.in_group?(state.group, conn_pid, auth) do + if SNet.Group.in_group?(state.netgroup, conn_pid, auth) do SNet.Manager.send_pid(conn_pid, {state.id, nil, {:root, state.mst.root}}) end {:noreply, state} @@ -151,7 +186,7 @@ defmodule SApp.Chat do Merkle hash of the store of older messages. """ def handle_cast({:msg, conn_pid, auth, _shard_id, nil, msg}, state) do - if not SNet.Group.in_group?(state.group, conn_pid, auth) do + if not SNet.Group.in_group?(state.netgroup, conn_pid, auth) do # Ignore message {:noreply, state} else @@ -250,7 +285,7 @@ defmodule SApp.Chat do defp msg_callback(state, {pk, msgbin, sign}) do for pid <- state.subs do if Process.alive?(pid) do - send(pid, {:chat_recv, state.channel, {pk, msgbin, sign}}) + send(pid, {:chat_recv, state.manifest, {pk, msgbin, sign}}) end end end |