* LCIMChatRoom.cs:
* LCConnection.cs: * LCIMController.cs: * LCIMMessageController.cs: * LCIMSessionController.cs: * LCIMConversationController.cs: * LCIMClient.cs: chore
parent
88f2b64eba
commit
bb3baf2ce8
|
@ -1,7 +1,5 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using LeanCloud.Realtime.Protocol;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
public class LCIMChatRoom : LCIMConversation {
|
||||
|
@ -13,16 +11,8 @@ namespace LeanCloud.Realtime {
|
|||
return await GetMembersCount();
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetOnlineMembers(int limit = 50) {
|
||||
ConvCommand conv = new ConvCommand {
|
||||
Cid = Id,
|
||||
Limit = limit
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Members);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
List<string> memberList = response.ConvMessage.M.ToList();
|
||||
return memberList;
|
||||
public async Task<ReadOnlyCollection<string>> GetOnlineMembers(int limit = 50) {
|
||||
return await Client.ConversationController.GetOnlineMembers(Id, limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,24 @@ namespace LeanCloud.Realtime.Internal.Connection {
|
|||
/// 连接层,只与数据协议相关
|
||||
/// </summary>
|
||||
internal class LCConnection {
|
||||
/// <summary>
|
||||
/// 发送超时
|
||||
/// </summary>
|
||||
private const int SEND_TIMEOUT = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// 最大重连次数,超过后重置 Router 缓存后再次尝试重连
|
||||
/// </summary>
|
||||
private const int MAX_RECONNECT_TIMES = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 重连间隔
|
||||
/// </summary>
|
||||
private const int RECONNECT_INTERVAL = 5000;
|
||||
|
||||
/// <summary>
|
||||
/// 心跳间隔
|
||||
/// </summary>
|
||||
private const int HEART_BEAT_INTERVAL = 5000;
|
||||
|
||||
internal Action<GenericCommand> OnNotification;
|
||||
|
|
|
@ -19,5 +19,19 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
return Client.Connection;
|
||||
}
|
||||
}
|
||||
|
||||
protected GenericCommand NewCommand(CommandType cmd, OpType op) {
|
||||
GenericCommand command = NewCommand(cmd);
|
||||
command.Op = op;
|
||||
return command;
|
||||
}
|
||||
|
||||
protected GenericCommand NewCommand(CommandType cmd) {
|
||||
return new GenericCommand {
|
||||
Cmd = cmd,
|
||||
AppId = LCApplication.AppId,
|
||||
PeerId = Client.Id,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
bool temporary = false,
|
||||
int temporaryTtl = 86400,
|
||||
Dictionary<string, object> properties = null) {
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Start);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Start);
|
||||
ConvCommand conv = new ConvCommand {
|
||||
Transient = transient,
|
||||
Unique = unique,
|
||||
|
@ -99,7 +99,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
ConvCommand conv = new ConvCommand {
|
||||
Cid = convId,
|
||||
};
|
||||
GenericCommand command = Client.NewCommand(CommandType.Conv, OpType.Count);
|
||||
GenericCommand command = NewCommand(CommandType.Conv, OpType.Count);
|
||||
command.ConvMessage = conv;
|
||||
GenericCommand response = await Connection.SendRequest(command);
|
||||
return response.ConvMessage.Count;
|
||||
|
@ -120,7 +120,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Timestamp = message.SentTimestamp
|
||||
};
|
||||
read.Convs.Add(tuple);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Read, OpType.Open);
|
||||
GenericCommand request = NewCommand(CommandType.Read, OpType.Open);
|
||||
request.ReadMessage = read;
|
||||
await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
conv.Attr = new JsonObjectMessage {
|
||||
Data = JsonConvert.SerializeObject(attributes)
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Update);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Update);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
JsonObjectMessage attr = response.ConvMessage.AttrModified;
|
||||
|
@ -173,7 +173,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
conv.T = signature.Timestamp;
|
||||
conv.N = signature.Nonce;
|
||||
}
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Add);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Add);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
|
||||
|
@ -203,7 +203,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
conv.T = signature.Timestamp;
|
||||
conv.N = signature.Nonce;
|
||||
}
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Remove);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
|
||||
|
@ -220,7 +220,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
ConvCommand conv = new ConvCommand {
|
||||
Cid = convId
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Mute);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Mute);
|
||||
request.ConvMessage = conv;
|
||||
await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
ConvCommand conv = new ConvCommand {
|
||||
Cid = convId
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Unmute);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Unmute);
|
||||
request.ConvMessage = conv;
|
||||
await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Cid = convId
|
||||
};
|
||||
conv.M.AddRange(clientIds);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.AddShutup);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.AddShutup);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
|
||||
|
@ -272,7 +272,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Cid = convId
|
||||
};
|
||||
conv.M.AddRange(clientIds);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Remove);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
|
||||
|
@ -299,7 +299,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
blacklist.T = signature.Timestamp;
|
||||
blacklist.N = signature.Nonce;
|
||||
}
|
||||
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Block);
|
||||
GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Block);
|
||||
request.BlacklistMessage = blacklist;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
|
||||
|
@ -326,7 +326,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
blacklist.T = signature.Timestamp;
|
||||
blacklist.N = signature.Nonce;
|
||||
}
|
||||
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Unblock);
|
||||
GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Unblock);
|
||||
request.BlacklistMessage = blacklist;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
|
||||
|
@ -350,7 +350,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Role = role
|
||||
}
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.MemberInfoUpdate);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.MemberInfoUpdate);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Limit = limit,
|
||||
Next = next
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.QueryShutup);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.QueryShutup);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return new LCIMPageResult {
|
||||
|
@ -422,7 +422,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Limit = limit,
|
||||
Next = next
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Query);
|
||||
GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Query);
|
||||
request.BlacklistMessage = black;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
return new LCIMPageResult {
|
||||
|
@ -479,13 +479,18 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
}).ToList().AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取临时对话
|
||||
/// </summary>
|
||||
/// <param name="convIds"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<List<LCIMTemporaryConversation>> GetTemporaryConversations(IEnumerable<string> convIds) {
|
||||
if (convIds == null || convIds.Count() == 0) {
|
||||
return null;
|
||||
}
|
||||
ConvCommand convMessage = new ConvCommand();
|
||||
convMessage.TempConvIds.AddRange(convIds);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Query);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Query);
|
||||
request.ConvMessage = convMessage;
|
||||
GenericCommand response = await Connection.SendRequest(request);
|
||||
JsonObjectMessage results = response.ConvMessage.Results;
|
||||
|
@ -498,11 +503,16 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
return convList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拉取对话接收/已读情况
|
||||
/// </summary>
|
||||
/// <param name="convId"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task FetchReciptTimestamp(string convId) {
|
||||
ConvCommand convCommand = new ConvCommand {
|
||||
Cid = convId
|
||||
};
|
||||
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.MaxRead);
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.MaxRead);
|
||||
request.ConvMessage = convCommand;
|
||||
GenericCommand response = await Connection.SendRequest(request);
|
||||
convCommand = response.ConvMessage;
|
||||
|
@ -511,6 +521,26 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
conversation.LastReadTimestamp = convCommand.MaxReadTimestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取在线成员
|
||||
/// </summary>
|
||||
/// <param name="convId"></param>
|
||||
/// <param name="limit"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<ReadOnlyCollection<string>> GetOnlineMembers(string convId,
|
||||
int limit) {
|
||||
ConvCommand conv = new ConvCommand {
|
||||
Cid = convId,
|
||||
Limit = limit
|
||||
};
|
||||
GenericCommand request = NewCommand(CommandType.Conv, OpType.Members);
|
||||
request.ConvMessage = conv;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
ReadOnlyCollection<string> members = response.ConvMessage.M
|
||||
.ToList().AsReadOnly();
|
||||
return members;
|
||||
}
|
||||
|
||||
private LCIMPartiallySuccessResult NewPartiallySuccessResult(IEnumerable<string> succesfulIds,
|
||||
IEnumerable<ErrorCommand> errors) {
|
||||
LCIMPartiallySuccessResult result = new LCIMPartiallySuccessResult {
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
} else {
|
||||
throw new ArgumentException("Message MUST BE LCIMTypedMessage or LCIMBinaryMessage.");
|
||||
}
|
||||
GenericCommand command = Client.NewDirectCommand();
|
||||
GenericCommand command = NewCommand(CommandType.Direct);
|
||||
command.DirectMessage = direct;
|
||||
GenericCommand response = await Client.Connection.SendRequest(command);
|
||||
// 消息发送应答
|
||||
|
@ -57,7 +57,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
Recall = true
|
||||
};
|
||||
patch.Patches.Add(item);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Patch, OpType.Modify);
|
||||
GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
|
||||
request.PatchMessage = patch;
|
||||
await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
item.MentionAll = newMessage.MentionAll;
|
||||
}
|
||||
patch.Patches.Add(item);
|
||||
GenericCommand request = Client.NewCommand(CommandType.Patch, OpType.Modify);
|
||||
GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
|
||||
request.PatchMessage = patch;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
if (messageType != 0) {
|
||||
logs.Lctype = messageType;
|
||||
}
|
||||
GenericCommand request = Client.NewCommand(CommandType.Logs, OpType.Open);
|
||||
GenericCommand request = NewCommand(CommandType.Logs, OpType.Open);
|
||||
request.LogsMessage = logs;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
// TODO 反序列化聊天记录
|
||||
|
|
|
@ -18,9 +18,23 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
/// 打开会话
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task Open() {
|
||||
internal async Task Open(bool reconnect) {
|
||||
SessionCommand session = NewSessionCommand();
|
||||
GenericCommand request = Client.NewCommand(CommandType.Session, OpType.Open);
|
||||
session.R = reconnect;
|
||||
GenericCommand request = NewCommand(CommandType.Session, OpType.Open);
|
||||
request.SessionMessage = session;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
UpdateSession(response.SessionMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新打开会话,重连时调用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task Reopen() {
|
||||
SessionCommand session = NewSessionCommand();
|
||||
session.R = true;
|
||||
GenericCommand request = NewCommand(CommandType.Session, OpType.Open);
|
||||
request.SessionMessage = session;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
UpdateSession(response.SessionMessage);
|
||||
|
@ -31,7 +45,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task Close() {
|
||||
GenericCommand request = Client.NewCommand(CommandType.Session, OpType.Close);
|
||||
GenericCommand request = NewCommand(CommandType.Session, OpType.Close);
|
||||
await Client.Connection.SendRequest(request);
|
||||
}
|
||||
|
||||
|
@ -50,7 +64,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
|
||||
private async Task Refresh() {
|
||||
SessionCommand session = NewSessionCommand();
|
||||
GenericCommand request = Client.NewCommand(CommandType.Session, OpType.Refresh);
|
||||
GenericCommand request = NewCommand(CommandType.Session, OpType.Refresh);
|
||||
request.SessionMessage = session;
|
||||
GenericCommand response = await Client.Connection.SendRequest(request);
|
||||
UpdateSession(response.SessionMessage);
|
||||
|
@ -58,6 +72,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
|
||||
private SessionCommand NewSessionCommand() {
|
||||
SessionCommand session = new SessionCommand();
|
||||
if (Client.Tag != null) {
|
||||
session.Tag = Client.Tag;
|
||||
session.DeviceId = Guid.NewGuid().ToString();
|
||||
}
|
||||
if (Client.SignatureFactory != null) {
|
||||
LCIMSignature signature = Client.SignatureFactory.CreateConnectSignature(Client.Id);
|
||||
session.S = signature.Signature;
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace LeanCloud.Realtime {
|
|||
get; private set;
|
||||
}
|
||||
|
||||
public string Tag {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <summary>
|
||||
|
@ -87,13 +91,6 @@ namespace LeanCloud.Realtime {
|
|||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户端重连失败,连接成功,登录失败
|
||||
/// </summary>
|
||||
public Action OnReconnectError {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户在其他客户端登录,当前客户端被服务端强行下线
|
||||
/// </summary>
|
||||
|
@ -257,11 +254,15 @@ namespace LeanCloud.Realtime {
|
|||
#region 接口
|
||||
|
||||
public LCIMClient(string clientId,
|
||||
string tag = null,
|
||||
ILCIMSignatureFactory signatureFactory = null) {
|
||||
Id = clientId;
|
||||
Tag = tag;
|
||||
SignatureFactory = signatureFactory;
|
||||
|
||||
ConversationDict = new Dictionary<string, LCIMConversation>();
|
||||
|
||||
// 模块
|
||||
SessionController = new LCIMSessionController(this);
|
||||
ConversationController = new LCIMConversationController(this);
|
||||
MessageController = new LCIMMessageController(this);
|
||||
|
@ -280,10 +281,10 @@ namespace LeanCloud.Realtime {
|
|||
/// 连接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task Open() {
|
||||
public async Task Open(bool reconnect = false) {
|
||||
await Connection.Connect();
|
||||
// 打开 Session
|
||||
await SessionController.Open();
|
||||
await SessionController.Open(reconnect);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -451,13 +452,14 @@ namespace LeanCloud.Realtime {
|
|||
private async Task HandleReconnected() {
|
||||
try {
|
||||
// 打开 Session
|
||||
await SessionController.Open();
|
||||
await SessionController.Reopen();
|
||||
// 回调用户
|
||||
OnReconnected?.Invoke();
|
||||
} catch (Exception e) {
|
||||
LCLogger.Error(e);
|
||||
await Connection.Close();
|
||||
OnReconnectError?.Invoke();
|
||||
// TODO 告知
|
||||
//OnClose?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,27 +470,5 @@ namespace LeanCloud.Realtime {
|
|||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue