using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; using LeanCloud.Realtime.Internal.WebSocket; using LeanCloud.Realtime.Protocol; using LeanCloud.Realtime.Internal.Controller; namespace LeanCloud.Realtime { public class LCIMClient { internal Dictionary ConversationDict; public string Id { get; private set; } #region 事件 /// /// 当前用户被加入某个对话的黑名单 /// public Action OnBlocked { get; set; } /// /// 当用户被解除黑名单 /// public Action OnUnblocked { get; set; } /// /// 当前用户在某个对话中被禁言 /// public Action OnMuted; /// /// 当前用户在某个对话中被解除禁言 /// public Action OnUnmuted; /// /// 客户端连接断开 /// public Action OnPaused { get; set; } /// /// 客户端连接恢复正常 /// public Action OnResume { get; set; } /// /// 当前客户端被服务端强行下线 /// public Action OnClose { get; set; } /// /// 客户端连接断开 /// public Action OnDisconnect { get; set; } /// /// 用户在其他客户端登录,当前客户端被服务端强行下线 /// public Action OnConflict { get; set; } /// /// 该对话信息被更新 /// public Action, string> OnConversationInfoUpdated; /// /// 当前用户被添加至某个对话 /// public Action OnInvited { get; set; } /// /// 当前用户被从某个对话中移除 /// public Action OnKicked { get; set; } /// /// 有用户被添加至某个对话 /// public Action, string> OnMembersJoined { get; set; } /// /// 有成员被从某个对话中移除 /// public Action, string> OnMembersLeft { get; set; } /// /// 有成员被加入某个对话的黑名单 /// public Action, string> OnMembersBlocked { get; set; } /// /// 有成员被移出某个对话的黑名单 /// public Action, string> OnMembersUnblocked { get; set; } /// /// 有成员在某个对话中被禁言 /// public Action, string> OnMembersMuted { get; set; } /// /// 有成员被移出某个对话的黑名单 /// public Action, string> OnMembersUnmuted { get; set; } /// /// 有成员的对话信息被更新 /// public Action OnMemberInfoUpdated; /// /// 当前用户收到消息 /// public Action OnMessage { get; set; } /// /// 消息被撤回 /// public Action OnMessageRecalled { get; set; } /// /// 消息被修改 /// public Action OnMessageUpdated { get; set; } /// /// 未读消息数目更新 /// public Action> OnUnreadMessagesCountUpdated { get; set; } /// /// /// public Action OnLastDeliveredAtUpdated { get; set; } public Action OnLastReadAtUpdated { get; set; } #endregion internal ILCIMSignatureFactory SignatureFactory { get; private set; } internal LCWebSocketConnection Connection { get; set; } internal LCIMSessionController SessionController { get; private set; } internal LCIMMessageController MessageController { get; private set; } internal LCIMUnreadController UnreadController { get; private set; } internal LCIMGoAwayController GoAwayController { get; private set; } internal LCIMConversationController ConversationController { get; private set; } public LCIMClient(string clientId, ILCIMSignatureFactory signatureFactory = null) { Id = clientId; SignatureFactory = signatureFactory; ConversationDict = new Dictionary(); SessionController = new LCIMSessionController(this); ConversationController = new LCIMConversationController(this); MessageController = new LCIMMessageController(this); UnreadController = new LCIMUnreadController(this); GoAwayController = new LCIMGoAwayController(this); Connection = new LCWebSocketConnection(Id) { OnNotification = OnNotification }; } /// /// 连接 /// /// public async Task Open() { await Connection.Connect(); // 打开 Session await SessionController.Open(); } /// /// 关闭 /// /// public async Task Close() { // 关闭 session await SessionController.Close(); await Connection.Close(); } /// /// 创建普通对话 /// /// /// /// /// /// public async Task CreateConversation( IEnumerable members, string name = null, bool unique = true, Dictionary properties = null) { return await ConversationController.CreateConv(members: members, name: name, unique: unique, properties: properties); } /// /// 创建聊天室 /// /// /// /// public async Task CreateChatRoom( string name, Dictionary properties = null) { LCIMChatRoom chatRoom = await ConversationController.CreateConv(name: name, transient: true, properties: properties) as LCIMChatRoom; return chatRoom; } /// /// 创建临时对话 /// /// /// /// /// public async Task CreateTemporaryConversation( IEnumerable members, int ttl = 86400, Dictionary properties = null) { LCIMTemporaryConversation tempConversation = await ConversationController.CreateConv(members: members, temporary: true, temporaryTtl: ttl, properties: properties) as LCIMTemporaryConversation; return tempConversation; } /// /// 根据 id 获取对话 /// /// /// public async Task GetConversation(string id) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException(nameof(id)); } if (LCIMConversation.IsTemporayConversation(id)) { List temporaryConversationList = await ConversationController.GetTemporaryConversations(new string[] { id }); if (temporaryConversationList == null || temporaryConversationList.Count < 1) { return null; } return temporaryConversationList[0]; } LCIMConversationQuery query = GetQuery() .WhereEqualTo("objectId", id) .Limit(1); List results = await ConversationController.Find(query); if (results == null || results.Count < 1) { return null; } return results[0]; } /// /// 获取某些特定的对话 /// /// /// public async Task> GetConversationList(IEnumerable ids) { if (ids == null || ids.Count() == 0) { throw new ArgumentNullException(nameof(ids)); } // 区分临时对话 IEnumerable tempConvIds = ids.Where(item => { return LCIMConversation.IsTemporayConversation(item); }); IEnumerable convIds = ids.Where(item => { return !tempConvIds.Contains(item); }); List temporaryConversations = await ConversationController.GetTemporaryConversations(tempConvIds); LCIMConversationQuery query = GetQuery() .WhereContainedIn("objectId", convIds) .Limit(999); List conversations = await ConversationController.Find(query); conversations.AddRange(temporaryConversations); return conversations; } /// /// 获取对话查询对象 /// /// public LCIMConversationQuery GetQuery() { return new LCIMConversationQuery(this); } private async Task OnNotification(GenericCommand notification) { switch (notification.Cmd) { case CommandType.Session: await SessionController.OnNotification(notification); break; case CommandType.Conv: await ConversationController.OnNotification(notification); break; case CommandType.Direct: await MessageController.OnNotification(notification); break; case CommandType.Unread: await UnreadController.OnNotification(notification); break; case CommandType.Goaway: await GoAwayController.OnNotification(notification); break; default: break; } } internal async Task GetOrQueryConversation(string convId) { if (ConversationDict.TryGetValue(convId, out LCIMConversation conversation)) { return conversation; } conversation = await GetConversation(convId); return conversation; } internal GenericCommand NewCommand(CommandType cmd, OpType op) { GenericCommand command = NewCommand(cmd); command.Op = op; return command; } internal GenericCommand NewCommand(CommandType cmd) { return new GenericCommand { Cmd = cmd, AppId = LCApplication.AppId, PeerId = Id, }; } internal GenericCommand NewDirectCommand() { return new GenericCommand { Cmd = CommandType.Direct, AppId = LCApplication.AppId, PeerId = Id, }; } } }