Browse Source

upgrade group chat

pull/18/head
Sun 3 years ago
parent
commit
3803d313e3
  1. 3
      lib/apps/group/detail.dart
  2. 6
      lib/apps/group/models.dart
  3. 712
      src/apps/group/layer.rs
  4. 8
      src/apps/group/models/group.rs
  5. 8
      src/apps/group/models/message.rs
  6. 7
      src/apps/group/rpc.rs
  7. 41
      src/layer.rs
  8. 90
      src/rpc.rs
  9. 26
      types/group/src/lib.rs

3
lib/apps/group/detail.dart

@ -85,10 +85,9 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
} }
} }
// [group_id, member_id, member_addr] // [group_id, member_id]
_memberOnline(List params) { _memberOnline(List params) {
if (_group.id == params[0] && this._members.containsKey(params[1])) { if (_group.id == params[0] && this._members.containsKey(params[1])) {
this._members[params[1]]!.addr = params[2];
this._members[params[1]]!.online = true; this._members[params[1]]!.online = true;
setState(() {}); setState(() {});
} }

6
lib/apps/group/models.dart

@ -35,7 +35,6 @@ class Member {
int id = 0; int id = 0;
int fid = 0; int fid = 0;
String mid = ''; String mid = '';
String addr = '';
String name = ''; String name = '';
bool leave = false; bool leave = false;
bool online = false; bool online = false;
@ -44,9 +43,8 @@ class Member {
this.id = params[0]; this.id = params[0];
this.fid = params[1]; this.fid = params[1];
this.mid = params[2]; this.mid = params[2];
this.addr = params[3]; this.name = params[3];
this.name = params[4]; this.leave = params[4];
this.leave = params[5];
if (this.mid == Global.pid) { if (this.mid == Global.pid) {
this.online = true; this.online = true;
} }

712
src/apps/group/layer.rs

@ -9,13 +9,12 @@ use tdn_storage::local::DStorage;
use crate::apps::chat::Friend; use crate::apps::chat::Friend;
use crate::global::Global; use crate::global::Global;
use crate::layer::Layer;
use crate::rpc::{ use crate::rpc::{
session_close, session_connect, session_last, session_lost, session_suspend, session_close, session_connect, session_last, session_lost, session_suspend,
session_update_name, session_update_name,
}; };
use crate::session::{connect_session, Session, SessionType}; use crate::session::{connect_session, Session, SessionType};
use crate::storage::{delete_avatar, group_db, session_db, write_avatar_sync}; use crate::storage::{chat_db, delete_avatar, group_db, session_db, write_avatar_sync};
use super::models::{handle_network_message, GroupChat, Member, Message}; use super::models::{handle_network_message, GroupChat, Member, Message};
use super::rpc; use super::rpc;
@ -56,7 +55,7 @@ pub(crate) async fn handle(msg: RecvType, global: &Arc<Global>) -> Result<Handle
let db = group_db(&global.base, &pid, &db_key)?; let db = group_db(&global.base, &pid, &db_key)?;
let s_db = session_db(&global.base, &pid, &db_key)?; let s_db = session_db(&global.base, &pid, &db_key)?;
let group = GroupChat::close(&db, &gid, &peer.id)?; let group = GroupChat::close_id(&db, &gid, &peer.id)?;
let sid = Session::close(&s_db, &group.id, &SessionType::Group)?; let sid = Session::close(&s_db, &group.id, &SessionType::Group)?;
results.rpcs.push(session_close(&sid)); results.rpcs.push(session_close(&sid));
} }
@ -71,22 +70,16 @@ pub(crate) async fn handle(msg: RecvType, global: &Arc<Global>) -> Result<Handle
results.layers.push((GROUP_CHAT_ID, msg)); results.layers.push((GROUP_CHAT_ID, msg));
} }
} }
RecvType::Leave(..) => {}
RecvType::Event(addr, bytes) => { RecvType::Event(addr, bytes) => {
// PEER & SERVER
let event: LayerEvent = bincode::deserialize(&bytes)?; let event: LayerEvent = bincode::deserialize(&bytes)?;
debug!("----------- DEBUG GROUP CHAT: SERVER GOT LAYER EVENT"); handle_event(addr, event, global, &mut results).await?;
//handle_server_event(fgid, addr, event, layer, &mut results).await?;
debug!("----------- DEBUG GROUP CHAT: SERVER OVER LAYER EVENT");
debug!("----------- DEBUG GROUP CHAT: PEER GOT LAYER EVENT");
//handle_peer_event(ogid, addr, event, layer, &mut results).await?;
debug!("----------- DEBUG GROUP CHAT: PEER OVER LAYER EVENT");
} }
RecvType::Delivery(..) => {}
RecvType::Stream(_uid, _stream, _bytes) => { RecvType::Stream(_uid, _stream, _bytes) => {
// TODO stream // TODO stream
} }
RecvType::Leave(..) => {} // nerver here.
RecvType::Delivery(..) => {}
} }
Ok(results) Ok(results)
@ -98,7 +91,7 @@ async fn handle_connect(
gid: GroupChatId, gid: GroupChatId,
results: &mut HandleResult, results: &mut HandleResult,
) -> Result<()> { ) -> Result<()> {
let (height, sid, id) = global.layer.read().await.group(&gid)?.info(); let (height, _, id, _) = global.layer.read().await.group(&gid)?.info();
let pid = global.pid().await; let pid = global.pid().await;
let db_key = global.group.read().await.db_key(&pid)?; let db_key = global.group.read().await.db_key(&pid)?;
@ -117,7 +110,7 @@ async fn handle_connect(
results.rpcs.push(rpc::member_online(id, mid)); results.rpcs.push(rpc::member_online(id, mid));
let data = LayerEvent::MemberOnline(gid, peer.id); let data = LayerEvent::MemberOnline(gid, peer.id);
broadcast(&gid, global, &data, results).await; broadcast(&gid, global, &data, results).await?;
Ok(()) Ok(())
} }
@ -182,384 +175,310 @@ async fn handle_result(
Ok(()) Ok(())
} }
// async fn handle_server_event( async fn handle_event(
// fgid: GroupId, addr: PeerId,
// addr: PeerId, event: LayerEvent,
// event: LayerEvent, global: &Arc<Global>,
// layer: &Arc<RwLock<Layer>>, results: &mut HandleResult,
// results: &mut HandleResult, ) -> Result<()> {
// ) -> Result<()> { let gid = event.gid();
// let gcd = event.gcd(); let (height, sid, id, gaddr) = global.layer.read().await.group(&gid)?.info();
// let base = layer.read().await.base().clone(); let pid = global.pid().await;
// let (ogid, height, id) = layer.read().await.running(gcd)?.owner_height_id(); let db_key = global.group.read().await.db_key(&pid)?;
// let db = layer.read().await.group.read().await.group_db(&ogid)?; let db = group_db(&global.base, &pid, &db_key)?;
let is_server = gaddr == pid;
// match event { if !is_server && gaddr != addr {
// LayerEvent::Offline(gcd) => { warn!("INVALID EVENT NOT FROM THE SERVER.");
// // 1. check member online. return Err(anyhow!("NOT THE SERVER EVENT"));
// if layer.write().await.remove_online(&gcd, &fgid).is_none() { }
// return Ok(());
// } match event {
LayerEvent::Offline(gid) => {
// // 2. UI: offline the member. // SERVER & PEER
// if let Ok(mid) = Member::get_id(&db, &id, &fgid) { if is_server {
// results.rpcs.push(rpc::member_offline(ogid, id, mid)); // 1. check member online.
// } if !global.layer.write().await.group_del_online(&gid, &addr) {
return Ok(());
// // 3. broadcast offline event. }
// broadcast(&LayerEvent::MemberOffline(gcd, fgid), layer, &gcd, results).await?;
// } // 2. UI: offline the member.
// LayerEvent::GroupName(gcd, name) => { if let Ok(mid) = Member::get_id(&db, &id, &addr) {
// // 1. update group name results.rpcs.push(rpc::member_offline(id, mid));
// let _ = GroupChat::update_name(&db, &id, &name)?; }
// // 2. UI: update
// results.rpcs.push(rpc::group_name(ogid, &id, &name)); // 3. broadcast offline event.
// if let Ok(sid) = Session::update_name_by_id( broadcast(&gid, global, &LayerEvent::MemberOffline(gid, addr), results).await?;
// &layer.read().await.group.read().await.session_db(&ogid)?, } else {
// &id, // 1. offline group chat.
// &SessionType::Group, global.layer.write().await.group_del(&gid);
// &name,
// ) { // 2. UI: offline the session.
// results.rpcs.push(session_update_name(ogid, &sid, &name)); results.rpcs.push(session_lost(&sid));
// } }
// // 3. broadcast }
// broadcast(&LayerEvent::GroupName(gcd, name), layer, &gcd, results).await?; LayerEvent::Suspend(gid) => {
// } // PEER
// LayerEvent::Sync(gcd, _, event) => { if global
// match event { .layer
// Event::MemberJoin(mgid, maddr, mname, mavatar) => { .write()
// let mdid_res = Member::get_id(&db, &id, &mgid); .await
// let h = layer.write().await.running_mut(&gcd)?.increased(); .group_mut(&gid)?
// let new_e = Event::MemberJoin(mgid, maddr, mname.clone(), mavatar.clone()); .suspend(false, true)
.is_some()
// if let Ok(mdid) = mdid_res { {
// Member::update(&db, &h, &mdid, &maddr, &mname)?; results.rpcs.push(session_suspend(&sid));
// if mavatar.len() > 0 { }
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?; }
// } LayerEvent::Actived(gid) => {
// let mem = Member::info(mdid, id, mgid, maddr, mname); // PEER
// results.rpcs.push(rpc::member_join(ogid, &mem)); let _ = global.layer.write().await.group_mut(&gid)?.active(false);
// } else { results.rpcs.push(session_connect(&sid, &addr));
// let mut member = Member::new(h, id, mgid, maddr, mname); }
// member.insert(&db)?; LayerEvent::MemberOnline(_gid, mpid) => {
// if mavatar.len() > 0 { // PEER
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?; if let Ok(mid) = Member::get_id(&db, &id, &mpid) {
// } results.rpcs.push(rpc::member_online(id, mid));
// results.rpcs.push(rpc::member_join(ogid, &member)); }
// } }
LayerEvent::MemberOffline(_gid, mpid) => {
// // broadcast // PEER
// GroupChat::add_height(&db, id, h)?; if let Ok(mid) = Member::get_id(&db, &id, &mpid) {
// broadcast(&LayerEvent::Sync(gcd, h, new_e), layer, &gcd, results).await?; results.rpcs.push(rpc::member_offline(id, mid));
// } }
// Event::MemberLeave(mgid) => { }
// let mdid = Member::get_id(&db, &id, &mgid)?; LayerEvent::MemberOnlineSync(gid) => {
// let h = layer.write().await.running_mut(&gcd)?.increased(); // SERVER
// Member::leave(&db, &mdid, &h)?; let onlines = global.layer.read().await.group(&gid)?.addrs.clone();
let event = LayerEvent::MemberOnlineSyncResult(gid, onlines);
// // check mid is my chat friend. if not, delete avatar. let data = bincode::serialize(&event).unwrap_or(vec![]);
// let s_db = &layer.read().await.group.read().await.chat_db(&ogid)?; let msg = SendType::Event(0, addr, data);
// if Friend::get_id(&s_db, &mgid).is_err() { results.layers.push((GROUP_CHAT_ID, msg));
// let _ = delete_avatar(&base, &ogid, &mgid).await; }
// } LayerEvent::MemberOnlineSyncResult(_gid, onlines) => {
// results.rpcs.push(rpc::member_leave(ogid, id, mdid)); // PEER
for mpid in onlines {
// // broadcast if let Ok(mid) = Member::get_id(&db, &id, &mpid) {
// GroupChat::add_height(&db, id, h)?; results.rpcs.push(rpc::member_online(id, mid));
// broadcast(&LayerEvent::Sync(gcd, h, event), layer, &gcd, results).await?; }
// } }
// Event::MessageCreate(mgid, nmsg, mtime) => { }
// debug!("Sync: create message start"); LayerEvent::GroupName(gid, name) => {
// let _mdid = Member::get_id(&db, &id, &mgid)?; // SERVER & PEER
// 1. update group name
// let new_e = Event::MessageCreate(mgid, nmsg.clone(), mtime); let _ = GroupChat::update_name(&db, &id, &name)?;
// let new_h = layer.write().await.running_mut(&gcd)?.increased();
// broadcast(&LayerEvent::Sync(gcd, new_h, new_e), layer, &gcd, results).await?; // 2. UI: update
// GroupChat::add_height(&db, id, new_h)?; results.rpcs.push(rpc::group_name(&id, &name));
let s_db = session_db(&global.base, &pid, &db_key)?;
// let msg = handle_network_message( let _ = Session::update_name(&s_db, &sid, &name);
// &layer.read().await.group, results.rpcs.push(session_update_name(&sid, &name));
// new_h,
// id, if is_server {
// mgid, // 3. broadcast
// &ogid, broadcast(&gid, global, &LayerEvent::GroupName(gid, name), results).await?;
// nmsg, }
// mtime, }
// &base, LayerEvent::GroupClose(gid) => {
// results, // PEER
// ) let group = GroupChat::close(&db, &id)?;
// .await?; let s_db = session_db(&global.base, &pid, &db_key)?;
// results.rpcs.push(rpc::message_create(ogid, &msg)); let sid = Session::close(&s_db, &group.id, &SessionType::Group)?;
// debug!("Sync: create message ok"); results.rpcs.push(session_close(&sid));
}
// // UPDATE SESSION. LayerEvent::Sync(gid, height, event) => {
// if let Ok(s_db) = layer.read().await.group.read().await.session_db(&ogid) { // SERVER & PEER
// update_session(&s_db, &ogid, &id, &msg, results); debug!("Sync: handle is_server: {} height: {} ", is_server, height);
// } match event {
// } Event::MemberJoin(mpid, mname, mavatar) => {
// } let mid_res = Member::get_id(&db, &id, &mpid);
// } let h = if is_server {
// LayerEvent::MemberOnlineSync(gcd) => { global.layer.write().await.group_mut(&gid)?.increased()
// let onlines = layer } else {
// .read() height
// .await };
// .running(&gcd)?
// .onlines() if let Ok(mid) = mid_res {
// .iter() Member::update(&db, &h, &mid, &mname)?;
// .map(|(g, a)| (**g, **a)) if mavatar.len() > 0 {
// .collect(); write_avatar_sync(&global.base, &pid, &mpid, mavatar.clone())?;
// let event = LayerEvent::MemberOnlineSyncResult(gcd, onlines); }
// let data = bincode::serialize(&event).unwrap_or(vec![]); let mem = Member::info(mid, id, mpid, mname.clone());
// let s = SendType::Event(0, addr, data); results.rpcs.push(rpc::member_join(&mem));
// add_server_layer(results, fgid, s); } else {
// } let mut member = Member::new(h, id, mpid, mname.clone());
// LayerEvent::SyncReq(gcd, from) => { member.insert(&db)?;
// debug!("Got sync request. height: {} from: {}", height, from); if mavatar.len() > 0 {
write_avatar_sync(&global.base, &pid, &mpid, mavatar.clone())?;
// if height >= from { }
// let to = if height - from > 20 { results.rpcs.push(rpc::member_join(&member));
// from + 20 }
// } else {
// height GroupChat::add_height(&db, id, h)?;
// }; if is_server {
// broadcast
// let (members, leaves) = Member::sync(&base, &ogid, &db, &id, &from, &to).await?; let new_e = Event::MemberJoin(mpid, mname, mavatar);
// let messages = Message::sync(&base, &ogid, &db, &id, &from, &to).await?; broadcast(&gid, global, &LayerEvent::Sync(gid, h, new_e), results).await?;
// let event = LayerEvent::SyncRes(gcd, height, from, to, members, leaves, messages); }
// let data = bincode::serialize(&event).unwrap_or(vec![]); }
// let s = SendType::Event(0, addr, data); Event::MemberLeave(mpid) => {
// add_server_layer(results, fgid, s); let mid = Member::get_id(&db, &id, &mpid)?;
// debug!("Sended sync request results. from: {}, to: {}", from, to); let h = if is_server {
// } global.layer.write().await.group_mut(&gid)?.increased()
// } } else {
// LayerEvent::Suspend(..) => {} height
// LayerEvent::Actived(..) => {} };
// _ => error!("group server handle event nerver here"), Member::leave(&db, &mid, &h)?;
// }
// check mid is my chat friend. if not, delete avatar.
// Ok(()) let c_db = chat_db(&global.base, &pid, &db_key)?;
// } if Friend::get_id(&c_db, &mpid).is_err() {
let _ = delete_avatar(&global.base, &pid, &mpid).await;
// async fn handle_peer_event( }
// ogid: GroupId, results.rpcs.push(rpc::member_leave(id, mid));
// addr: PeerId,
// event: LayerEvent, // broadcast
// layer: &Arc<RwLock<Layer>>, GroupChat::add_height(&db, id, h)?;
// results: &mut HandleResult, if is_server {
// ) -> Result<()> { broadcast(&gid, global, &LayerEvent::Sync(gid, h, event), results).await?;
// let base = layer.read().await.base().clone(); }
// let gcd = event.gcd(); }
// let (sid, id) = layer.read().await.get_running_remote_id(&ogid, gcd)?; Event::MessageCreate(mpid, nmsg, mtime) => {
// let db = layer.read().await.group.read().await.group_db(&ogid)?; debug!("Sync: create message start");
let _mid = Member::get_id(&db, &id, &mpid)?;
// match event { let h = if is_server {
// LayerEvent::Offline(gcd) => { global.layer.write().await.group_mut(&gid)?.increased()
// // 1. offline group chat. } else {
// layer height
// .write() };
// .await
// .running_mut(&ogid)? let msg = handle_network_message(
// .check_offline(&gcd, &addr); &pid,
&global.base,
// // 2. UI: offline the session. &db_key,
// results.rpcs.push(session_lost(ogid, &sid)); h,
// } id,
// LayerEvent::Suspend(gcd) => { mpid,
// if layer nmsg.clone(),
// .write() mtime,
// .await results,
// .running_mut(&ogid)? )
// .suspend(&gcd, false, true)? .await?;
// { results.rpcs.push(rpc::message_create(&msg));
// results.rpcs.push(session_suspend(ogid, &sid)); debug!("Sync: create message ok");
// }
// } // UPDATE SESSION.
// LayerEvent::Actived(gcd) => { let s_db = session_db(&global.base, &pid, &db_key)?;
// let _ = layer.write().await.running_mut(&ogid)?.active(&gcd, false); update_session(&s_db, &id, &msg, results);
// results.rpcs.push(session_connect(ogid, &sid, &addr));
// } GroupChat::add_height(&db, id, h)?;
// LayerEvent::MemberOnline(_gcd, mgid, maddr) => { if is_server {
// if let Ok(mid) = Member::addr_update(&db, &id, &mgid, &maddr) { let new_e = Event::MessageCreate(mpid, nmsg, mtime);
// results.rpcs.push(rpc::member_online(ogid, id, mid, &maddr)); broadcast(&gid, global, &LayerEvent::Sync(gid, h, new_e), results).await?;
// } }
// } }
// LayerEvent::MemberOffline(_gcd, mgid) => { }
// if let Ok(mid) = Member::get_id(&db, &id, &mgid) { }
// results.rpcs.push(rpc::member_offline(ogid, id, mid)); LayerEvent::SyncReq(gid, from) => {
// } // SERVER
// } debug!("Got sync request. height: {} from: {}", height, from);
// LayerEvent::MemberOnlineSyncResult(_gcd, onlines) => {
// for (mgid, maddr) in onlines { if height >= from {
// if let Ok(mid) = Member::addr_update(&db, &id, &mgid, &maddr) { let to = if height - from > 20 {
// results.rpcs.push(rpc::member_online(ogid, id, mid, &maddr)); from + 20
// } } else {
// } height
// } };
// LayerEvent::GroupName(_gcd, name) => {
// let _ = GroupChat::update_name(&db, &id, &name)?; let (members, leaves) =
// results.rpcs.push(rpc::group_name(ogid, &id, &name)); Member::sync(&global.base, &pid, &db, &id, &from, &to).await?;
// let _ = Session::update_name( let messages = Message::sync(&global.base, &pid, &db, &id, &from, &to).await?;
// &layer.read().await.group.read().await.session_db(&ogid)?, let event = LayerEvent::SyncRes(gid, height, from, to, members, leaves, messages);
// &sid, let data = bincode::serialize(&event).unwrap_or(vec![]);
// &name, let s = SendType::Event(0, addr, data);
// ); results.layers.push((GROUP_CHAT_ID, s));
// results.rpcs.push(session_update_name(ogid, &sid, &name)); debug!("Sended sync request results. from: {}, to: {}", from, to);
// } }
// LayerEvent::GroupClose(_gcd) => { }
// let group = GroupChat::close(&db, &gcd)?; LayerEvent::SyncRes(gid, height, from, to, adds, leaves, messages) => {
// let sid = Session::close( // PEER
// &layer.read().await.group.read().await.session_db(&ogid)?, if to >= height {
// &group.id, results.layers.push((GROUP_CHAT_ID, sync_online(gid, addr)));
// &SessionType::Group, // when last packed sync, start sync online members.
// )?; }
// results.rpcs.push(session_close(ogid, &sid));
// } debug!("Start handle sync packed... {}, {}, {}", height, from, to);
// LayerEvent::Sync(_gcd, height, event) => { let mut last_message = None;
// debug!("Sync: handle height: {}", height);
for (height, mpid, mname, mavatar) in adds {
// match event { let mid_res = Member::get_id(&db, &id, &mpid);
// Event::MemberJoin(mgid, maddr, mname, mavatar) => { if let Ok(mid) = mid_res {
// let mdid_res = Member::get_id(&db, &id, &mgid); Member::update(&db, &height, &mid, &mname)?;
// if let Ok(mdid) = mdid_res { if mavatar.len() > 0 {
// Member::update(&db, &height, &mdid, &maddr, &mname)?; write_avatar_sync(&global.base, &pid, &mpid, mavatar)?;
// if mavatar.len() > 0 { }
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?; let mem = Member::info(mid, id, mpid, mname);
// } results.rpcs.push(rpc::member_join(&mem));
// let mem = Member::info(mdid, id, mgid, maddr, mname); } else {
// results.rpcs.push(rpc::member_join(ogid, &mem)); let mut member = Member::new(height, id, mpid, mname);
// } else { member.insert(&db)?;
// let mut member = Member::new(height, id, mgid, maddr, mname); if mavatar.len() > 0 {
// member.insert(&db)?; write_avatar_sync(&global.base, &pid, &mpid, mavatar)?;
// if mavatar.len() > 0 { }
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?; results.rpcs.push(rpc::member_join(&member));
// } }
// results.rpcs.push(rpc::member_join(ogid, &member)); }
// }
let c_db = chat_db(&global.base, &pid, &db_key)?;
// // save consensus. for (height, mpid) in leaves {
// GroupChat::add_height(&db, id, height)?; if let Ok(mid) = Member::get_id(&db, &id, &mpid) {
// } Member::leave(&db, &height, &mid)?;
// Event::MemberLeave(mgid) => { // check mid is my chat friend. if not, delete avatar.
// let mdid = Member::get_id(&db, &id, &mgid)?; if Friend::get_id(&c_db, &mpid).is_err() {
// Member::leave(&db, &height, &mdid)?; let _ = delete_avatar(&global.base, &pid, &mpid).await;
}
// // check mid is my chat friend. if not, delete avatar. results.rpcs.push(rpc::member_leave(id, mid));
// let s_db = &layer.read().await.group.read().await.chat_db(&ogid)?; }
// if Friend::get_id(&s_db, &mgid).is_err() { }
// let _ = delete_avatar(&base, &ogid, &mgid).await;
// } for (height, mpid, nm, time) in messages {
// results.rpcs.push(rpc::member_leave(ogid, id, mdid)); if let Ok(msg) = handle_network_message(
&pid,
// // save consensus. &global.base,
// GroupChat::add_height(&db, id, height)?; &db_key,
// } height,
// Event::MessageCreate(mgid, nmsg, mtime) => { id,
// debug!("Sync: create message start"); mpid,
// let _mdid = Member::get_id(&db, &id, &mgid)?; nm,
time,
// let msg = handle_network_message( results,
// &layer.read().await.group, )
// height, .await
// id, {
// mgid, results.rpcs.push(rpc::message_create(&msg));
// &ogid, last_message = Some(msg);
// nmsg, }
// mtime, }
// &base,
// results, if to < height {
// ) results
// .await?; .layers
// results.rpcs.push(rpc::message_create(ogid, &msg)); .push((GROUP_CHAT_ID, sync(gid, addr, to + 1)));
}
// GroupChat::add_height(&db, id, height)?;
// debug!("Sync: create message ok"); // update group chat height.
GroupChat::add_height(&db, id, to)?;
// // UPDATE SESSION.
// if let Ok(s_db) = layer.read().await.group.read().await.session_db(&ogid) { // UPDATE SESSION.
// update_session(&s_db, &ogid, &id, &msg, results); if let Some(msg) = last_message {
// } let s_db = session_db(&global.base, &pid, &db_key)?;
// } update_session(&s_db, &id, &msg, results);
// } }
// } debug!("Over handle sync packed... {}, {}, {}", height, from, to);
// LayerEvent::SyncRes(gcd, height, from, to, adds, leaves, messages) => { }
// if to >= height { }
// // when last packed sync, start sync online members.
// add_layer(results, ogid, sync_online(gcd, addr)); Ok(())
// } }
// debug!("Start handle sync packed... {}, {}, {}", height, from, to);
// let mut last_message = None;
// for (height, mgid, maddr, mname, mavatar) in adds {
// let mdid_res = Member::get_id(&db, &id, &mgid);
// if let Ok(mdid) = mdid_res {
// Member::update(&db, &height, &mdid, &maddr, &mname)?;
// if mavatar.len() > 0 {
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?;
// }
// let mem = Member::info(mdid, id, mgid, maddr, mname);
// results.rpcs.push(rpc::member_join(ogid, &mem));
// } else {
// let mut member = Member::new(height, id, mgid, maddr, mname);
// member.insert(&db)?;
// if mavatar.len() > 0 {
// write_avatar_sync(&base, &ogid, &mgid, mavatar)?;
// }
// results.rpcs.push(rpc::member_join(ogid, &member));
// }
// }
// for (height, mgid) in leaves {
// if let Ok(mdid) = Member::get_id(&db, &id, &mgid) {
// Member::leave(&db, &height, &mdid)?;
// // check mid is my chat friend. if not, delete avatar.
// let s_db = &layer.read().await.group.read().await.chat_db(&ogid)?;
// if Friend::get_id(&s_db, &mgid).is_err() {
// let _ = delete_avatar(&base, &ogid, &mgid).await;
// }
// results.rpcs.push(rpc::member_leave(ogid, id, mdid));
// }
// }
// for (height, mgid, nm, time) in messages {
// if let Ok(msg) = handle_network_message(
// &layer.read().await.group,
// height,
// id,
// mgid,
// &ogid,
// nm,
// time,
// &base,
// results,
// )
// .await
// {
// results.rpcs.push(rpc::message_create(ogid, &msg));
// last_message = Some(msg);
// }
// }
// if to < height {
// add_layer(results, ogid, sync(gcd, addr, to + 1));
// }
// // update group chat height.
// GroupChat::add_height(&db, id, to)?;
// // UPDATE SESSION.
// if let Some(msg) = last_message {
// if let Ok(s_db) = layer.read().await.group.read().await.session_db(&ogid) {
// update_session(&s_db, &ogid, &id, &msg, results);
// }
// }
// debug!("Over handle sync packed... {}, {}, {}", height, from, to);
// }
// _ => error!("group peer handle event nerver here"),
// }
// Ok(())
// }
pub(crate) async fn broadcast( pub(crate) async fn broadcast(
gid: &GroupChatId, gid: &GroupChatId,
@ -569,7 +488,7 @@ pub(crate) async fn broadcast(
) -> Result<()> { ) -> Result<()> {
let new_data = bincode::serialize(event)?; let new_data = bincode::serialize(event)?;
for mpid in global.layer.read().await.group(gid)?.addrs.iter() { for mpid in global.layer.read().await.group(gid)?.addrs.iter().skip(1) {
let s = SendType::Event(0, *mpid, new_data.clone()); let s = SendType::Event(0, *mpid, new_data.clone());
results.layers.push((GROUP_CHAT_ID, s)); results.layers.push((GROUP_CHAT_ID, s));
debug!("--- DEBUG broadcast to: {:?}", mpid); debug!("--- DEBUG broadcast to: {:?}", mpid);
@ -601,9 +520,10 @@ pub(crate) fn update_session(s_db: &DStorage, id: &i64, msg: &Message, results:
} }
} }
pub(crate) fn group_conn(addr: Peer, gid: GroupChatId) -> SendType { pub(crate) fn group_conn(addr: PeerId, gid: GroupChatId, results: &mut HandleResult) {
let data = bincode::serialize(&LayerConnect(gid)).unwrap_or(vec![]); let data = bincode::serialize(&LayerConnect(gid)).unwrap_or(vec![]);
SendType::Connect(0, addr, data) let msg = SendType::Connect(0, Peer::peer(addr), data);
results.layers.push((GROUP_CHAT_ID, msg));
} }
fn sync(gid: GroupChatId, addr: PeerId, height: i64) -> SendType { fn sync(gid: GroupChatId, addr: PeerId, height: i64) -> SendType {

8
src/apps/group/models/group.rs

@ -177,7 +177,13 @@ impl GroupChat {
db.update(&sql) db.update(&sql)
} }
pub fn close(db: &DStorage, gid: &GroupChatId, addr: &PeerId) -> Result<GroupChat> { pub fn close(db: &DStorage, id: &i64) -> Result<GroupChat> {
let sql = format!("UPDATE groups SET is_close = true WHERE id = {}", id);
db.update(&sql)?;
Self::get(db, id)
}
pub fn close_id(db: &DStorage, gid: &GroupChatId, addr: &PeerId) -> Result<GroupChat> {
let group = Self::get_id(db, gid, addr)?; let group = Self::get_id(db, gid, addr)?;
let sql = format!("UPDATE groups SET is_close = true WHERE id = {}", group.id); let sql = format!("UPDATE groups SET is_close = true WHERE id = {}", group.id);
db.update(&sql)?; db.update(&sql)?;

8
src/apps/group/models/message.rs

@ -138,8 +138,8 @@ impl Message {
} }
pub async fn sync( pub async fn sync(
own: &PeerId,
base: &PathBuf, base: &PathBuf,
own: &PeerId,
db: &DStorage, db: &DStorage,
fid: &i64, fid: &i64,
from: &i64, from: &i64,
@ -191,17 +191,17 @@ pub(crate) async fn handle_network_message(
base: &PathBuf, base: &PathBuf,
db_key: &str, db_key: &str,
height: i64, height: i64,
gdid: i64, id: i64,
mid: PeerId, mid: PeerId,
msg: NetworkMessage, msg: NetworkMessage,
datetime: i64, datetime: i64,
results: &mut HandleResult, results: &mut HandleResult,
) -> Result<Message> { ) -> Result<Message> {
let db = group_db(base, own, db_key)?; let db = group_db(base, own, db_key)?;
let mdid = Member::get_id(&db, &gdid, &mid)?; let mdid = Member::get_id(&db, &id, &mid)?;
let is_me = &mid == own; let is_me = &mid == own;
let (m_type, raw) = from_network_message(own, base, db_key, msg, results).await?; let (m_type, raw) = from_network_message(own, base, db_key, msg, results).await?;
let mut msg = Message::new_with_time(height, gdid, mdid, is_me, m_type, raw, datetime); let mut msg = Message::new_with_time(height, id, mdid, is_me, m_type, raw, datetime);
msg.insert(&db)?; msg.insert(&db)?;
Ok(msg) Ok(msg)
} }

7
src/apps/group/rpc.rs

@ -124,7 +124,6 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) {
let mut m = Member::new(gh, id, pid, me.name); let mut m = Member::new(gh, id, pid, me.name);
m.insert(&db)?; m.insert(&db)?;
let mid = m.id;
let _ = write_avatar(&state.base, &pid, &pid, &me.avatar).await; let _ = write_avatar(&state.base, &pid, &pid, &me.avatar).await;
// Add new session. // Add new session.
@ -192,7 +191,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) {
if g.local { if g.local {
// local save. // local save.
let new_h = state.layer.write().await.group_increased(&gid)?; let new_h = state.layer.write().await.group_mut(&gid)?.increased();
let mut mem = Member::new(new_h, g.id, f.pid, f.name); let mut mem = Member::new(new_h, g.id, f.pid, f.name);
mem.insert(&group_db)?; mem.insert(&group_db)?;
@ -236,7 +235,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) {
if group.local { if group.local {
// local save. // local save.
let new_h = state.layer.write().await.group_increased(&gid)?; let new_h = state.layer.write().await.group_mut(&gid)?.increased();
let mut msg = Message::new_with_time(new_h, id, mid, true, m_type, raw, datetime); let mut msg = Message::new_with_time(new_h, id, mid, true, m_type, raw, datetime);
msg.insert(&db)?; msg.insert(&db)?;
@ -311,7 +310,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) {
if g.local { if g.local {
// dissolve group. // dissolve group.
let data = bincode::serialize(&LayerEvent::GroupClose(g.gid))?; let data = bincode::serialize(&LayerEvent::GroupClose(g.gid))?;
if let Some(addrs) = state.layer.write().await.group_rm_online(&g.gid) { if let Some(addrs) = state.layer.write().await.group_del(&g.gid) {
for addr in addrs { for addr in addrs {
let s = SendType::Event(0, addr, data.clone()); let s = SendType::Event(0, addr, data.clone());
results.layers.push((GROUP_CHAT_ID, s)); results.layers.push((GROUP_CHAT_ID, s));

41
src/layer.rs

@ -119,12 +119,6 @@ impl Layer {
} }
} }
pub fn group_add(&mut self, gid: GroupChatId, pid: PeerId, sid: i64, fid: i64, h: i64) {
if !self.groups.contains_key(&gid) {
self.groups.insert(gid, LayerSession::new(pid, sid, fid, h));
}
}
pub fn group(&self, gid: &GroupChatId) -> Result<&LayerSession> { pub fn group(&self, gid: &GroupChatId) -> Result<&LayerSession> {
if let Some(session) = self.groups.get(gid) { if let Some(session) = self.groups.get(gid) {
Ok(session) Ok(session)
@ -133,18 +127,24 @@ impl Layer {
} }
} }
pub fn group_rm_online(&mut self, gid: &GroupChatId) -> Option<Vec<PeerId>> { pub fn group_mut(&mut self, gid: &GroupChatId) -> Result<&mut LayerSession> {
self.groups.remove(gid).map(|session| session.addrs)
}
pub fn group_increased(&mut self, gid: &GroupChatId) -> Result<i64> {
if let Some(session) = self.groups.get_mut(gid) { if let Some(session) = self.groups.get_mut(gid) {
Ok(session.increased()) Ok(session)
} else { } else {
Err(anyhow!("session missing!")) Err(anyhow!("session missing!"))
} }
} }
pub fn group_add(&mut self, gid: GroupChatId, pid: PeerId, sid: i64, fid: i64, h: i64) {
if !self.groups.contains_key(&gid) {
self.groups.insert(gid, LayerSession::new(pid, sid, fid, h));
}
}
pub fn group_del(&mut self, gid: &GroupChatId) -> Option<Vec<PeerId>> {
self.groups.remove(gid).map(|session| session.addrs)
}
pub fn group_add_member(&mut self, gid: &GroupChatId, addr: PeerId) { pub fn group_add_member(&mut self, gid: &GroupChatId, addr: PeerId) {
if let Some(session) = self.groups.get_mut(gid) { if let Some(session) = self.groups.get_mut(gid) {
session.addrs.push(addr); session.addrs.push(addr);
@ -157,6 +157,16 @@ impl Layer {
} }
} }
pub fn group_del_online(&mut self, gid: &GroupChatId, addr: &PeerId) -> bool {
if let Some(session) = self.groups.get_mut(gid) {
if let Some(pos) = session.addrs.iter().position(|x| x == addr) {
session.addrs.remove(pos);
return true;
}
}
false
}
// pub fn remove_running(&mut self, gid: &GroupId) -> HashMap<PeerId, GroupId> { // pub fn remove_running(&mut self, gid: &GroupId) -> HashMap<PeerId, GroupId> {
// // check close the stable connection. // // check close the stable connection.
// let mut addrs: HashMap<PeerId, GroupId> = HashMap::new(); // let mut addrs: HashMap<PeerId, GroupId> = HashMap::new();
@ -248,7 +258,6 @@ impl Layer {
// } // }
pub fn broadcast(&self, user: User, results: &mut HandleResult) { pub fn broadcast(&self, user: User, results: &mut HandleResult) {
let gid = user.id;
let info = ChatLayerEvent::InfoRes(user); let info = ChatLayerEvent::InfoRes(user);
let data = bincode::serialize(&info).unwrap_or(vec![]); let data = bincode::serialize(&info).unwrap_or(vec![]);
@ -256,6 +265,8 @@ impl Layer {
let msg = SendType::Event(0, *fpid, data.clone()); let msg = SendType::Event(0, *fpid, data.clone());
results.layers.push((CHAT_ID, msg)); results.layers.push((CHAT_ID, msg));
} }
// TODO GROUPS
} }
} }
@ -326,8 +337,8 @@ impl LayerSession {
} }
} }
pub fn info(&self) -> (i64, i64, i64) { pub fn info(&self) -> (i64, i64, i64, PeerId) {
(self.height, self.s_id, self.db_id) (self.height, self.s_id, self.db_id, self.addrs[0])
} }
pub fn increased(&mut self) -> i64 { pub fn increased(&mut self) -> i64 {

90
src/rpc.rs

@ -1,14 +1,11 @@
use chat_types::CHAT_ID; use chat_types::CHAT_ID;
use esse_primitives::{id_from_str, id_to_str}; use esse_primitives::{id_from_str, id_to_str};
use group_types::GroupChatId; use group_types::{GroupChatId, LayerEvent as GroupLayerEvent, GROUP_CHAT_ID};
use group_types::GROUP_CHAT_ID;
use std::collections::HashMap;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use tdn::{ use tdn::{
prelude::{new_send_channel, start_main}, prelude::{new_send_channel, start_main},
types::{ types::{
group::GroupId,
message::{ message::{
NetworkType, RpcSendMessage, SendMessage, SendType, StateRequest, StateResponse, NetworkType, RpcSendMessage, SendMessage, SendType, StateRequest, StateResponse,
}, },
@ -17,21 +14,15 @@ use tdn::{
}, },
}; };
use tdn_did::{generate_mnemonic, Count}; use tdn_did::{generate_mnemonic, Count};
use tokio::sync::{
mpsc::{self, error::SendError, Sender},
RwLock,
};
use crate::account::lang_from_i64; use crate::account::lang_from_i64;
use crate::apps::app_rpc_inject; use crate::apps::app_rpc_inject;
use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent}; use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent};
use crate::apps::group::{group_conn, GroupChat};
use crate::global::Global; use crate::global::Global;
//use crate::apps::group::{add_layer, group_conn, GroupChat};
//use crate::event::InnerEvent; //use crate::event::InnerEvent;
use crate::group::Group;
use crate::layer::Layer;
use crate::session::{connect_session, Session, SessionType}; use crate::session::{connect_session, Session, SessionType};
use crate::storage::session_db; use crate::storage::{group_db, session_db};
pub(crate) fn init_rpc(global: Arc<Global>) -> RpcHandler<Global> { pub(crate) fn init_rpc(global: Arc<Global>) -> RpcHandler<Global> {
let mut handler = new_rpc_handler(global); let mut handler = new_rpc_handler(global);
@ -129,28 +120,6 @@ fn session_list(sessions: Vec<Session>) -> RpcParam {
json!(results) json!(results)
} }
#[inline]
pub(crate) async fn sleep_waiting_close_stable(
sender: Sender<SendMessage>,
groups: HashMap<PeerId, ()>,
layers: HashMap<PeerId, GroupId>,
) -> std::result::Result<(), SendError<SendMessage>> {
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
for (addr, _) in groups {
sender
.send(SendMessage::Group(SendType::Disconnect(addr)))
.await?;
}
for (faddr, fgid) in layers {
sender
.send(SendMessage::Layer(fgid, SendType::Disconnect(faddr)))
.await?;
}
Ok(())
}
#[inline] #[inline]
pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> Result<()> { pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> Result<()> {
// Inner network default rpc method. only use in http-rpc. // Inner network default rpc method. only use in http-rpc.
@ -161,7 +130,7 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> R
_ => return Ok(()), _ => return Ok(()),
}; };
let (s, mut r) = mpsc::channel::<StateResponse>(128); let (s, mut r) = tokio::sync::mpsc::channel::<StateResponse>(128);
let _ = global let _ = global
.send(SendMessage::Network(NetworkType::NetworkState(req, s))) .send(SendMessage::Network(NetworkType::NetworkState(req, s)))
.await?; .await?;
@ -371,7 +340,7 @@ fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?; let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let me_lock = params[1].as_str().ok_or(RpcError::ParseError)?; let me_lock = params[1].as_str().ok_or(RpcError::ParseError)?;
let mut results = HandleResult::rpc(json!([id_to_str(&pid)])); let results = HandleResult::rpc(json!([id_to_str(&pid)]));
let (tdn_send, tdn_recv) = new_send_channel(); let (tdn_send, tdn_recv) = new_send_channel();
let running = state.reset(&pid, me_lock, tdn_send).await?; let running = state.reset(&pid, me_lock, tdn_send).await?;
@ -379,31 +348,20 @@ fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
return Ok(results); return Ok(results);
} }
// TODO load all local services created by this account. // load all local services created by this account.
let db_key = state.group.read().await.db_key(&pid)?;
let group_db = group_db(&state.base, &pid, &db_key)?;
let s_db = session_db(&state.base, &pid, &db_key)?;
// 1. group chat. // 1. group chat.
// let self_addr = layer_lock.addr.clone(); let group_chats = GroupChat::local(&group_db)?;
// let group_lock = state.group.read().await; let mut layer = state.layer.write().await;
// let group_db = group_lock.group_db(&ogid)?; for g in group_chats {
// let s_db = group_lock.session_db(&ogid)?; // 2. online group to self group onlines.
// drop(group_lock); if let Some(s) = connect_session(&s_db, &SessionType::Group, &g.id, &pid)? {
// let group_chats = GroupChat::local(&group_db)?; layer.group_add(g.gid, g.addr, s.id, g.id, g.height);
// for g in group_chats { }
// layer_lock.add_running(&g.g_id, ogid, g.id, g.height)?; }
// results.networks.push(NetworkType::AddGroup(g.g_id)); drop(layer);
// // 2. online group to self group onlines.
// if let Some(session) =
// connect_session(&s_db, &SessionType::Group, &g.id, &self_addr)?
// {
// layer_lock.running_mut(&ogid)?.check_add_online(
// g.g_id,
// Online::Direct(self_addr),
// session.id,
// g.id,
// )?;
// }
// }
// drop(layer_lock);
let key = state.group.read().await.keypair(); let key = state.group.read().await.keypair();
let peer_id = start_main( let peer_id = start_main(
@ -475,11 +433,7 @@ fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
if let Some(addr) = online { if let Some(addr) = online {
return Ok(HandleResult::rpc(json!([id, id_to_str(&addr)]))); return Ok(HandleResult::rpc(json!([id, id_to_str(&addr)])));
} }
// add_layer( group_conn(s.addr, remote_gid, &mut results);
// &mut results,
// gid,
// group_conn(proof, Peer::peer(s.addr), s.gid),
// );
} }
_ => {} _ => {}
} }
@ -519,9 +473,9 @@ fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
if layer_lock.group_suspend(&remote_gid, true, must)?.is_some() { if layer_lock.group_suspend(&remote_gid, true, must)?.is_some() {
results.rpcs.push(json!([id])); results.rpcs.push(json!([id]));
} }
//let data = bincode::serialize(&GroupLayerEvent::Suspend(remote_gid))?; let data = bincode::serialize(&GroupLayerEvent::Suspend(remote_gid))?;
//let msg = SendType::Event(0, s.addr, data); let msg = SendType::Event(0, s.addr, data);
//results.layers.push((GROUP_CHAT_ID, msg)); results.layers.push((GROUP_CHAT_ID, msg));
} }
_ => { _ => {
return Ok(HandleResult::new()); // others has no online. return Ok(HandleResult::new()); // others has no online.

26
types/group/src/lib.rs

@ -62,20 +62,20 @@ pub enum LayerEvent {
impl LayerEvent { impl LayerEvent {
/// get event's group id. /// get event's group id.
pub fn gcd(&self) -> &GroupChatId { pub fn gid(&self) -> &GroupChatId {
match self { match self {
Self::Offline(gcd) => gcd, Self::Offline(gid) => gid,
Self::Suspend(gcd) => gcd, Self::Suspend(gid) => gid,
Self::Actived(gcd) => gcd, Self::Actived(gid) => gid,
Self::MemberOnline(gcd, ..) => gcd, Self::MemberOnline(gid, ..) => gid,
Self::MemberOffline(gcd, ..) => gcd, Self::MemberOffline(gid, ..) => gid,
Self::MemberOnlineSync(gcd) => gcd, Self::MemberOnlineSync(gid) => gid,
Self::MemberOnlineSyncResult(gcd, ..) => gcd, Self::MemberOnlineSyncResult(gid, ..) => gid,
Self::GroupName(gcd, ..) => gcd, Self::GroupName(gid, ..) => gid,
Self::GroupClose(gcd) => gcd, Self::GroupClose(gid) => gid,
Self::Sync(gcd, ..) => gcd, Self::Sync(gid, ..) => gid,
Self::SyncReq(gcd, ..) => gcd, Self::SyncReq(gid, ..) => gid,
Self::SyncRes(gcd, ..) => gcd, Self::SyncRes(gid, ..) => gid,
} }
} }
} }

Loading…
Cancel
Save