aboutsummaryrefslogtreecommitdiff
path: root/shard/lib/app/chat.ex
diff options
context:
space:
mode:
Diffstat (limited to 'shard/lib/app/chat.ex')
-rw-r--r--shard/lib/app/chat.ex57
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