From 1063dbfc8459e4f47972aad5a026ec537980d924 Mon Sep 17 00:00:00 2001 From: mattuy Date: Thu, 20 Dec 2018 16:52:29 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99=E5=90=8E=E5=8F=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BA=A4=E4=BA=92API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interact/{Fields.cs => Client-Fields.cs} | 4 +- Interact/{Handle.cs => Client-Handle.cs} | 28 ++++++++-- Interact/{Read.cs => Client-Read.cs} | 0 Interact/{Send.cs => Client-Send.cs} | 6 ++- Interact/Client.cs | 66 +++++++++++++++++------- Interact/Exception.cs | 2 +- Interact/Interact.csproj | 10 ++-- 7 files changed, 84 insertions(+), 32 deletions(-) rename Interact/{Fields.cs => Client-Fields.cs} (89%) rename Interact/{Handle.cs => Client-Handle.cs} (87%) rename Interact/{Read.cs => Client-Read.cs} (100%) rename Interact/{Send.cs => Client-Send.cs} (90%) diff --git a/Interact/Fields.cs b/Interact/Client-Fields.cs similarity index 89% rename from Interact/Fields.cs rename to Interact/Client-Fields.cs index 9f95fd0..e3aaaf5 100644 --- a/Interact/Fields.cs +++ b/Interact/Client-Fields.cs @@ -18,8 +18,8 @@ namespace Interact private static Thread readLoopThread; //数据发送线程 private static Thread sendLoopThread; - //某些请求需要持续的等待服务器返回数据包,然后将所有数据包处理后提供给用户 - // ,此字段用于暂存这些未接收完全的数据包。它的key是对应请求的Token字串。 + //某些请求需要持续的等待服务器返回数据包,然后将所有数据包处理后提供给用户, + // 此字段用于暂存这些未接收完全的数据包。它的key是对应请求的Token字串。 private static Dictionary workingDictionary; //属性控制字段,任何地方都不应该修改它们 diff --git a/Interact/Handle.cs b/Interact/Client-Handle.cs similarity index 87% rename from Interact/Handle.cs rename to Interact/Client-Handle.cs index 0fe1728..4d66c96 100644 --- a/Interact/Handle.cs +++ b/Interact/Client-Handle.cs @@ -13,7 +13,7 @@ namespace Interact { public partial class StormClient { - //处理连接中断异常 + //处理连接中断异常。 private static void HandleConnectionBroken(Exception ex) { lock (statusLocker) @@ -44,10 +44,13 @@ namespace Interact HandleMessage(jsonObj, data); break; case Operations.SendMessage: + HandleSendMessageResult(GetResultHead(jsonObj)); break; case Operations.Offline: + HandlePanic(GetResultHead(jsonObj)); break; case Operations.UpdateUserInfo: + HandleUpdateUserInfoDone(GetResultHead(jsonObj)); break; case Operations.GetUsers: HandleGetUsersPack(jsonObj, data); @@ -72,8 +75,8 @@ namespace Interact //处理服务器异常断开连接消息 private static void HandlePanic(ResultHead head) { - ConnectionBrokenException ex = new ConnectionBrokenException(head.Error); - HandleConnectionBroken(ex); + SetStatus(ClientStatus.Stopped); + OnPanic?.Invoke(head); } //处理登录反馈消息 @@ -118,6 +121,25 @@ namespace Interact OnMessage?.Invoke(message); } + //发送消息执行结果 + private static void HandleSendMessageResult(ResultHead head) + { + OnSendMessageDone?.Invoke(head); + } + + //处理掉线、强制登出 + private static void HandleOffiline(ResultHead head) + { + SetStatus(ClientStatus.Stopped); + OnOffline?.Invoke(head); + } + + //处理更改信息结果 + private static void HandleUpdateUserInfoDone(ResultHead head) + { + OnUpdateUserInfoDone?.Invoke(head); + } + //处理获取用户列表的不连续返回包。当所有包接收完毕后返回给客户 private static void HandleGetUsersPack(JObject head, byte[] data) { diff --git a/Interact/Read.cs b/Interact/Client-Read.cs similarity index 100% rename from Interact/Read.cs rename to Interact/Client-Read.cs diff --git a/Interact/Send.cs b/Interact/Client-Send.cs similarity index 90% rename from Interact/Send.cs rename to Interact/Client-Send.cs index 6079300..589655f 100644 --- a/Interact/Send.cs +++ b/Interact/Client-Send.cs @@ -16,8 +16,12 @@ namespace Interact { Packet packet = null; NetworkStream stream = tcpClient.GetStream(); + //json序列化时忽略值为null的项 + JsonSerializerSettings setting = new JsonSerializerSettings(); + setting.NullValueHandling = NullValueHandling.Ignore; try { + //阻塞式的从发送队列中取出数据 foreach (Packet i in sendQueue.GetConsumingEnumerable()) { packet = i; //为了在代码块外引用i @@ -26,7 +30,7 @@ namespace Interact break; //向tcp连接写数据 byte[] lenBuffer; //数据长度缓存 - byte[] headData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(packet.Head)); + byte[] headData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(packet.Head, setting)); //写包头 lenBuffer = BitConverter.GetBytes((UInt32)IPAddress.HostToNetworkOrder(headData.Length)); stream.Write(lenBuffer, 0, 4); diff --git a/Interact/Client.cs b/Interact/Client.cs index 70e00e6..c0560c5 100644 --- a/Interact/Client.cs +++ b/Interact/Client.cs @@ -24,28 +24,43 @@ namespace Interact /// public static partial class StormClient { - //连接中断事件 + /// + /// 连接中断事件。注意,此事件并不保证连接中断时总是触发,例如主动关闭连接、登出操作 + /// public static event ConnectionBrokenHandler OnDisconnect; - //服务器异常消息处理事件 + /// + /// 服务器异常消息处理事件 + /// public static event ResultHandler OnPanic; - //服务器强制注销登陆事件 + /// + /// 服务器强制注销登陆事件 + /// public static event ResultHandler OnOffline; - //消息到达事件 + /// + /// 消息到达事件 + /// public static event MessageHandler OnMessage; - //发送消息处理完成反馈事件(仅在DoesSendMessageReturn为true时有效) + /// + /// 发送消息处理完成反馈事件(仅在DoesSendMessageReturn为true时有效) + /// public static event ResultHandler OnSendMessageDone; - //更新用户信息结果处理事件 + /// + /// 更新用户信息结果处理事件 + /// public static event ResultHandler OnUpdateUserInfoDone; - //登录结果处理事件 + /// + /// 登录结果处理事件 + /// public static event LoginDoneHandler OnLoginDone; - //获取用户列表结果处理事件 + /// + /// 获取用户列表结果处理事件 + /// public static event GetUserListDoneHandler OnGetUserListDone; //当前连接状态 public static ClientStatus Status { get { lock (statusLocker) { return clientStatus; } } - set { lock (statusLocker) { clientStatus = value; } } } //发送消息时是否要求服务器返回处理结果 public static bool DoesSendMessageReturn @@ -60,7 +75,13 @@ namespace Interact tcpClient = new TcpClient(); sendQueue = new BlockingCollection(); workingDictionary = new Dictionary(); - Status = ClientStatus.Uninitialized; + SetStatus(ClientStatus.Uninitialized); + } + + //设置当前连接状态 + internal static void SetStatus(ClientStatus value) + { + lock (statusLocker) { clientStatus = value; } } /// @@ -89,7 +110,7 @@ namespace Interact sendLoopThread = new Thread(new ThreadStart(SendLoop)); readLoopThread = new Thread(new ThreadStart(ReadLoop)); sendLoopThread.IsBackground = readLoopThread.IsBackground = true; - StormClient.Status = ClientStatus.Running; + SetStatus(ClientStatus.Running); sendLoopThread.Start(); readLoopThread.Start(); return true; @@ -125,7 +146,7 @@ namespace Interact /// /// 要发送的消息文本 /// 消息接收者 - /// 数据发送完毕时回调函数 + /// 数据发送完毕时回调函数。 /// 成功将请求加入发送队列返回true,否则返回false。 public static bool QueueSendMessage(Message message, Action callback = null) { @@ -148,7 +169,7 @@ namespace Interact /// /// 请求登出。异步,此方法将请求放入请求队列后返回。 /// - /// 数据发送完毕时回调函数 + /// 数据发送完毕时回调函数。 /// 成功将请求加入发送队列返回true,否则返回false。 public static bool QueueLogout(Action callback = null) { @@ -163,13 +184,15 @@ namespace Interact Data = null, CallBack = callback }; - return Send(packet); + bool success = Send(packet); + SetStatus(ClientStatus.Stopped); + return success; } /// /// 请求用户列表。异步,此方法将请求放入请求队列后返回。 /// - /// 数据发送完毕时回调函数 + /// 数据发送完毕时回调函数。 /// 成功将请求加入发送队列返回true,否则返回false。 public static bool QueueGetUserList(Action callback = null) { @@ -190,12 +213,13 @@ namespace Interact /// /// 请求更新当前登录用户信息。异步,此方法将请求放入请求队列后返回。 /// - /// 数据发送完毕时回调函数 + /// 新的用户信息,如果某项值为null,则不改变该项。 + /// 数据发送完毕时回调函数。 /// 成功将请求加入发送队列返回true,否则返回false。 public static bool QueueUpdateUserInfo(UserInfo userInfo, Action callback = null) { - byte[] photoData = null; //头像数据 - //将头像数据转换到字符数组 + byte[] photoData = null; //头像数据 + //将头像数据转换到字符数组 if (userInfo.Photo != null) { MemoryStream memStream = new MemoryStream(); @@ -207,7 +231,7 @@ namespace Interact //构建数据包 JsonUserInfoHead jsonObj = new JsonUserInfoHead() { - Token = "", + Token = Guid.NewGuid().ToString(), Operation = Operations.UpdateUserInfo, NickName = userInfo.NickName, Password = userInfo.Password, @@ -223,7 +247,9 @@ namespace Interact return Send(packet); } - //客户端连接状态 + /// + /// 客户端连接状态 + /// public enum ClientStatus { Uninitialized, //未启动 diff --git a/Interact/Exception.cs b/Interact/Exception.cs index 9e5d777..6634055 100644 --- a/Interact/Exception.cs +++ b/Interact/Exception.cs @@ -5,7 +5,7 @@ using System.Text; namespace Interact { - class ConnectionBrokenException : Exception + public class ConnectionBrokenException : Exception { public ConnectionBrokenException(string message) : base(message) { } } diff --git a/Interact/Interact.csproj b/Interact/Interact.csproj index bdb6e97..7b2a3cb 100644 --- a/Interact/Interact.csproj +++ b/Interact/Interact.csproj @@ -46,9 +46,9 @@ - - - + + + @@ -56,8 +56,8 @@ True Resources.resx - - + +