* LCIMChatRoom.cs:

* LCConnection.cs:
* LCIMController.cs:
* LCIMMessageController.cs:
* LCIMSessionController.cs:
* LCIMConversationController.cs:

* LCIMClient.cs: chore
oneRain 2020-04-14 14:51:14 +08:00
parent 88f2b64eba
commit bb3baf2ce8
7 changed files with 115 additions and 71 deletions

View File

@ -1,7 +1,5 @@
using System.Linq; using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Realtime.Protocol;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
public class LCIMChatRoom : LCIMConversation { public class LCIMChatRoom : LCIMConversation {
@ -13,16 +11,8 @@ namespace LeanCloud.Realtime {
return await GetMembersCount(); return await GetMembersCount();
} }
public async Task<List<string>> GetOnlineMembers(int limit = 50) { public async Task<ReadOnlyCollection<string>> GetOnlineMembers(int limit = 50) {
ConvCommand conv = new ConvCommand { return await Client.ConversationController.GetOnlineMembers(Id, limit);
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;
} }
} }
} }

View File

@ -14,12 +14,24 @@ namespace LeanCloud.Realtime.Internal.Connection {
/// 连接层,只与数据协议相关 /// 连接层,只与数据协议相关
/// </summary> /// </summary>
internal class LCConnection { internal class LCConnection {
/// <summary>
/// 发送超时
/// </summary>
private const int SEND_TIMEOUT = 10000; private const int SEND_TIMEOUT = 10000;
/// <summary>
/// 最大重连次数,超过后重置 Router 缓存后再次尝试重连
/// </summary>
private const int MAX_RECONNECT_TIMES = 3; private const int MAX_RECONNECT_TIMES = 3;
/// <summary>
/// 重连间隔
/// </summary>
private const int RECONNECT_INTERVAL = 5000; private const int RECONNECT_INTERVAL = 5000;
/// <summary>
/// 心跳间隔
/// </summary>
private const int HEART_BEAT_INTERVAL = 5000; private const int HEART_BEAT_INTERVAL = 5000;
internal Action<GenericCommand> OnNotification; internal Action<GenericCommand> OnNotification;

View File

@ -19,5 +19,19 @@ namespace LeanCloud.Realtime.Internal.Controller {
return Client.Connection; 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,
};
}
} }
} }

View File

@ -36,7 +36,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
bool temporary = false, bool temporary = false,
int temporaryTtl = 86400, int temporaryTtl = 86400,
Dictionary<string, object> properties = null) { Dictionary<string, object> properties = null) {
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Start); GenericCommand request = NewCommand(CommandType.Conv, OpType.Start);
ConvCommand conv = new ConvCommand { ConvCommand conv = new ConvCommand {
Transient = transient, Transient = transient,
Unique = unique, Unique = unique,
@ -99,7 +99,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
ConvCommand conv = new ConvCommand { ConvCommand conv = new ConvCommand {
Cid = convId, Cid = convId,
}; };
GenericCommand command = Client.NewCommand(CommandType.Conv, OpType.Count); GenericCommand command = NewCommand(CommandType.Conv, OpType.Count);
command.ConvMessage = conv; command.ConvMessage = conv;
GenericCommand response = await Connection.SendRequest(command); GenericCommand response = await Connection.SendRequest(command);
return response.ConvMessage.Count; return response.ConvMessage.Count;
@ -120,7 +120,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Timestamp = message.SentTimestamp Timestamp = message.SentTimestamp
}; };
read.Convs.Add(tuple); read.Convs.Add(tuple);
GenericCommand request = Client.NewCommand(CommandType.Read, OpType.Open); GenericCommand request = NewCommand(CommandType.Read, OpType.Open);
request.ReadMessage = read; request.ReadMessage = read;
await Client.Connection.SendRequest(request); await Client.Connection.SendRequest(request);
} }
@ -139,7 +139,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
conv.Attr = new JsonObjectMessage { conv.Attr = new JsonObjectMessage {
Data = JsonConvert.SerializeObject(attributes) Data = JsonConvert.SerializeObject(attributes)
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Update); GenericCommand request = NewCommand(CommandType.Conv, OpType.Update);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
JsonObjectMessage attr = response.ConvMessage.AttrModified; JsonObjectMessage attr = response.ConvMessage.AttrModified;
@ -173,7 +173,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
conv.T = signature.Timestamp; conv.T = signature.Timestamp;
conv.N = signature.Nonce; conv.N = signature.Nonce;
} }
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Add); GenericCommand request = NewCommand(CommandType.Conv, OpType.Add);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList(); List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
@ -203,7 +203,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
conv.T = signature.Timestamp; conv.T = signature.Timestamp;
conv.N = signature.Nonce; conv.N = signature.Nonce;
} }
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove); GenericCommand request = NewCommand(CommandType.Conv, OpType.Remove);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList(); List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
@ -220,7 +220,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
ConvCommand conv = new ConvCommand { ConvCommand conv = new ConvCommand {
Cid = convId Cid = convId
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Mute); GenericCommand request = NewCommand(CommandType.Conv, OpType.Mute);
request.ConvMessage = conv; request.ConvMessage = conv;
await Client.Connection.SendRequest(request); await Client.Connection.SendRequest(request);
} }
@ -234,7 +234,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
ConvCommand conv = new ConvCommand { ConvCommand conv = new ConvCommand {
Cid = convId Cid = convId
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Unmute); GenericCommand request = NewCommand(CommandType.Conv, OpType.Unmute);
request.ConvMessage = conv; request.ConvMessage = conv;
await Client.Connection.SendRequest(request); await Client.Connection.SendRequest(request);
} }
@ -254,7 +254,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Cid = convId Cid = convId
}; };
conv.M.AddRange(clientIds); conv.M.AddRange(clientIds);
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.AddShutup); GenericCommand request = NewCommand(CommandType.Conv, OpType.AddShutup);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids); return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
@ -272,7 +272,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Cid = convId Cid = convId
}; };
conv.M.AddRange(clientIds); conv.M.AddRange(clientIds);
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove); GenericCommand request = NewCommand(CommandType.Conv, OpType.Remove);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids); return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
@ -299,7 +299,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
blacklist.T = signature.Timestamp; blacklist.T = signature.Timestamp;
blacklist.N = signature.Nonce; blacklist.N = signature.Nonce;
} }
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Block); GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Block);
request.BlacklistMessage = blacklist; request.BlacklistMessage = blacklist;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids); return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
@ -326,7 +326,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
blacklist.T = signature.Timestamp; blacklist.T = signature.Timestamp;
blacklist.N = signature.Nonce; blacklist.N = signature.Nonce;
} }
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Unblock); GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Unblock);
request.BlacklistMessage = blacklist; request.BlacklistMessage = blacklist;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids); return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
@ -350,7 +350,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Role = role Role = role
} }
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.MemberInfoUpdate); GenericCommand request = NewCommand(CommandType.Conv, OpType.MemberInfoUpdate);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
} }
@ -398,7 +398,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Limit = limit, Limit = limit,
Next = next Next = next
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.QueryShutup); GenericCommand request = NewCommand(CommandType.Conv, OpType.QueryShutup);
request.ConvMessage = conv; request.ConvMessage = conv;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return new LCIMPageResult { return new LCIMPageResult {
@ -422,7 +422,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Limit = limit, Limit = limit,
Next = next Next = next
}; };
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Query); GenericCommand request = NewCommand(CommandType.Blacklist, OpType.Query);
request.BlacklistMessage = black; request.BlacklistMessage = black;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
return new LCIMPageResult { return new LCIMPageResult {
@ -479,13 +479,18 @@ namespace LeanCloud.Realtime.Internal.Controller {
}).ToList().AsReadOnly(); }).ToList().AsReadOnly();
} }
/// <summary>
/// 获取临时对话
/// </summary>
/// <param name="convIds"></param>
/// <returns></returns>
internal async Task<List<LCIMTemporaryConversation>> GetTemporaryConversations(IEnumerable<string> convIds) { internal async Task<List<LCIMTemporaryConversation>> GetTemporaryConversations(IEnumerable<string> convIds) {
if (convIds == null || convIds.Count() == 0) { if (convIds == null || convIds.Count() == 0) {
return null; return null;
} }
ConvCommand convMessage = new ConvCommand(); ConvCommand convMessage = new ConvCommand();
convMessage.TempConvIds.AddRange(convIds); convMessage.TempConvIds.AddRange(convIds);
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Query); GenericCommand request = NewCommand(CommandType.Conv, OpType.Query);
request.ConvMessage = convMessage; request.ConvMessage = convMessage;
GenericCommand response = await Connection.SendRequest(request); GenericCommand response = await Connection.SendRequest(request);
JsonObjectMessage results = response.ConvMessage.Results; JsonObjectMessage results = response.ConvMessage.Results;
@ -498,11 +503,16 @@ namespace LeanCloud.Realtime.Internal.Controller {
return convList; return convList;
} }
/// <summary>
/// 拉取对话接收/已读情况
/// </summary>
/// <param name="convId"></param>
/// <returns></returns>
internal async Task FetchReciptTimestamp(string convId) { internal async Task FetchReciptTimestamp(string convId) {
ConvCommand convCommand = new ConvCommand { ConvCommand convCommand = new ConvCommand {
Cid = convId Cid = convId
}; };
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.MaxRead); GenericCommand request = NewCommand(CommandType.Conv, OpType.MaxRead);
request.ConvMessage = convCommand; request.ConvMessage = convCommand;
GenericCommand response = await Connection.SendRequest(request); GenericCommand response = await Connection.SendRequest(request);
convCommand = response.ConvMessage; convCommand = response.ConvMessage;
@ -511,6 +521,26 @@ namespace LeanCloud.Realtime.Internal.Controller {
conversation.LastReadTimestamp = convCommand.MaxReadTimestamp; 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, private LCIMPartiallySuccessResult NewPartiallySuccessResult(IEnumerable<string> succesfulIds,
IEnumerable<ErrorCommand> errors) { IEnumerable<ErrorCommand> errors) {
LCIMPartiallySuccessResult result = new LCIMPartiallySuccessResult { LCIMPartiallySuccessResult result = new LCIMPartiallySuccessResult {

View File

@ -32,7 +32,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
} else { } else {
throw new ArgumentException("Message MUST BE LCIMTypedMessage or LCIMBinaryMessage."); throw new ArgumentException("Message MUST BE LCIMTypedMessage or LCIMBinaryMessage.");
} }
GenericCommand command = Client.NewDirectCommand(); GenericCommand command = NewCommand(CommandType.Direct);
command.DirectMessage = direct; command.DirectMessage = direct;
GenericCommand response = await Client.Connection.SendRequest(command); GenericCommand response = await Client.Connection.SendRequest(command);
// 消息发送应答 // 消息发送应答
@ -57,7 +57,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
Recall = true Recall = true
}; };
patch.Patches.Add(item); patch.Patches.Add(item);
GenericCommand request = Client.NewCommand(CommandType.Patch, OpType.Modify); GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
request.PatchMessage = patch; request.PatchMessage = patch;
await Client.Connection.SendRequest(request); await Client.Connection.SendRequest(request);
} }
@ -91,7 +91,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
item.MentionAll = newMessage.MentionAll; item.MentionAll = newMessage.MentionAll;
} }
patch.Patches.Add(item); patch.Patches.Add(item);
GenericCommand request = Client.NewCommand(CommandType.Patch, OpType.Modify); GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
request.PatchMessage = patch; request.PatchMessage = patch;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
} }
@ -131,7 +131,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
if (messageType != 0) { if (messageType != 0) {
logs.Lctype = messageType; logs.Lctype = messageType;
} }
GenericCommand request = Client.NewCommand(CommandType.Logs, OpType.Open); GenericCommand request = NewCommand(CommandType.Logs, OpType.Open);
request.LogsMessage = logs; request.LogsMessage = logs;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
// TODO 反序列化聊天记录 // TODO 反序列化聊天记录

View File

@ -18,9 +18,23 @@ namespace LeanCloud.Realtime.Internal.Controller {
/// 打开会话 /// 打开会话
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal async Task Open() { internal async Task Open(bool reconnect) {
SessionCommand session = NewSessionCommand(); 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; request.SessionMessage = session;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
UpdateSession(response.SessionMessage); UpdateSession(response.SessionMessage);
@ -31,7 +45,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal async Task Close() { internal async Task Close() {
GenericCommand request = Client.NewCommand(CommandType.Session, OpType.Close); GenericCommand request = NewCommand(CommandType.Session, OpType.Close);
await Client.Connection.SendRequest(request); await Client.Connection.SendRequest(request);
} }
@ -50,7 +64,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
private async Task Refresh() { private async Task Refresh() {
SessionCommand session = NewSessionCommand(); SessionCommand session = NewSessionCommand();
GenericCommand request = Client.NewCommand(CommandType.Session, OpType.Refresh); GenericCommand request = NewCommand(CommandType.Session, OpType.Refresh);
request.SessionMessage = session; request.SessionMessage = session;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);
UpdateSession(response.SessionMessage); UpdateSession(response.SessionMessage);
@ -58,6 +72,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
private SessionCommand NewSessionCommand() { private SessionCommand NewSessionCommand() {
SessionCommand session = new SessionCommand(); SessionCommand session = new SessionCommand();
if (Client.Tag != null) {
session.Tag = Client.Tag;
session.DeviceId = Guid.NewGuid().ToString();
}
if (Client.SignatureFactory != null) { if (Client.SignatureFactory != null) {
LCIMSignature signature = Client.SignatureFactory.CreateConnectSignature(Client.Id); LCIMSignature signature = Client.SignatureFactory.CreateConnectSignature(Client.Id);
session.S = signature.Signature; session.S = signature.Signature;

View File

@ -19,6 +19,10 @@ namespace LeanCloud.Realtime {
get; private set; get; private set;
} }
public string Tag {
get; private set;
}
#region 事件 #region 事件
/// <summary> /// <summary>
@ -87,13 +91,6 @@ namespace LeanCloud.Realtime {
get; set; get; set;
} }
/// <summary>
/// 客户端重连失败,连接成功,登录失败
/// </summary>
public Action OnReconnectError {
get; set;
}
/// <summary> /// <summary>
/// 用户在其他客户端登录,当前客户端被服务端强行下线 /// 用户在其他客户端登录,当前客户端被服务端强行下线
/// </summary> /// </summary>
@ -257,11 +254,15 @@ namespace LeanCloud.Realtime {
#region 接口 #region 接口
public LCIMClient(string clientId, public LCIMClient(string clientId,
string tag = null,
ILCIMSignatureFactory signatureFactory = null) { ILCIMSignatureFactory signatureFactory = null) {
Id = clientId; Id = clientId;
Tag = tag;
SignatureFactory = signatureFactory; SignatureFactory = signatureFactory;
ConversationDict = new Dictionary<string, LCIMConversation>(); ConversationDict = new Dictionary<string, LCIMConversation>();
// 模块
SessionController = new LCIMSessionController(this); SessionController = new LCIMSessionController(this);
ConversationController = new LCIMConversationController(this); ConversationController = new LCIMConversationController(this);
MessageController = new LCIMMessageController(this); MessageController = new LCIMMessageController(this);
@ -280,10 +281,10 @@ namespace LeanCloud.Realtime {
/// 连接 /// 连接
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public async Task Open() { public async Task Open(bool reconnect = false) {
await Connection.Connect(); await Connection.Connect();
// 打开 Session // 打开 Session
await SessionController.Open(); await SessionController.Open(reconnect);
} }
/// <summary> /// <summary>
@ -451,13 +452,14 @@ namespace LeanCloud.Realtime {
private async Task HandleReconnected() { private async Task HandleReconnected() {
try { try {
// 打开 Session // 打开 Session
await SessionController.Open(); await SessionController.Reopen();
// 回调用户 // 回调用户
OnReconnected?.Invoke(); OnReconnected?.Invoke();
} catch (Exception e) { } catch (Exception e) {
LCLogger.Error(e); LCLogger.Error(e);
await Connection.Close(); await Connection.Close();
OnReconnectError?.Invoke(); // TODO 告知
//OnClose?.Invoke();
} }
} }
@ -468,27 +470,5 @@ namespace LeanCloud.Realtime {
conversation = await GetConversation(convId); conversation = await GetConversation(convId);
return conversation; 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,
};
}
} }
} }