diff --git a/.gitignore b/.gitignore
index 75419e8..f475183 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
# Binaries for programs and plugins
*.exe
*.exe~
-*.dll
+#*.dll
*.so
*.dylib
diff --git a/Interact/Strings.cs b/Interact/AttrNames.cs
similarity index 51%
rename from Interact/Strings.cs
rename to Interact/AttrNames.cs
index 508a169..a780338 100644
--- a/Interact/Strings.cs
+++ b/Interact/AttrNames.cs
@@ -5,11 +5,16 @@ using System.Text;
namespace Interact
{
- //字符串常量
- public static class Strings
+ //Json数据的字段访问字符串
+ public static class AttrNames
{
public const string Token = "Token";
public const string Operation = "Operation";
public const string Error = "Error";
+
+ public const string User = "User";
+ public const string NickName = "NickName";
+ public const string Motto = "Motto";
+ public const string UGroup = "UGroup";
}
}
diff --git a/Interact/Client.cs b/Interact/Client.cs
index 5b324cf..c995f73 100644
--- a/Interact/Client.cs
+++ b/Interact/Client.cs
@@ -6,21 +6,59 @@ using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Collections.Concurrent;
-using Newtonsoft.Json.Linq;
+using System.Drawing;
namespace Interact
{
//连接中断
public delegate void DisconnectHandler(Exception ex);
+ //通用请求结果处理
+ public delegate void ResultHandler(ResultHead head);
+ //消息到达事件处理
+ public delegate void MessageHandler(Message msg);
//登录反馈到达
- public delegate void LoginDoneHandler(JObject head, User user);
+ public delegate void LoginDoneHandler(ResultHead head, User user);
+ //获取用户列表结果处理
+ public delegate void GetUserListDoneHandler(ResultHead head, User[] users);
+ //获取用户头像结果处理
+ public delegate void GetUserPhotoDoneHandler(ResultHead head, Image image);
+
+ ///
+ /// 与服务器进行数据通信,并向外部提供一系列通信接口
+ ///
public static partial class StormClient
{
//连接中断事件
public static event DisconnectHandler OnDisconnect;
+ //服务器异常消息处理事件
+ public static event ResultHandler OnPanic;
+ //服务器强制注销登陆事件
+ public static event ResultHandler OnOffline;
+ //消息到达事件
+ public static event MessageHandler OnMessage;
+ //发送消息处理完成反馈事件(仅在DoesSendMessageReturn为true时有效)
+ public static event ResultHandler OnSendMessageDone;
+ //更新用户信息结果处理事件
+ public static event ResultHandler OnUpdateUserInfoDone;
//登录结果处理事件
public static event LoginDoneHandler OnLoginDone;
+ //获取用户列表结果处理事件
+ public static event GetUserListDoneHandler OnGetUserListDone;
+ //获取用户头像结果处理事件
+ public static event GetUserPhotoDoneHandler OnGetUserPhotoDoneHandler;
+ //发送消息时是否要求服务器返回处理结果
+ public static bool DoesSendMessageReturn
+ {
+ get
+ {
+ return doesSendMessageReturn != 0;
+ }
+ set
+ {
+ Interlocked.Exchange(ref StormClient.doesSendMessageReturn, value ? 1 : 0);
+ }
+ }
//TCP客户端
private static TcpClient tcpClient;
@@ -30,12 +68,15 @@ namespace Interact
private static Thread readLoopThread;
//数据发送线程
private static Thread sendLoopThread;
+ //发送消息时是否要求服务器返回处理结果
+ private static volatile int doesSendMessageReturn = 0;
static StormClient()
{
tcpClient = new TcpClient();
sendQueue = new BlockingCollection();
}
+
///
/// 初始化客户端,连接服务器。如果成功则启动数据接收和发送线程
///
@@ -62,7 +103,7 @@ namespace Interact
}
///
- /// 登录。此操作为异步操作,完成后产生OnLoginDone事件。
+ /// 登录。此操作为异步操作,服务器返回结果后产生OnLoginDone事件。
///
/// 成功将请求加入发送队列返回true,否则返回false。
/// 用户名
diff --git a/Interact/Handle.cs b/Interact/Handle.cs
index 1bb74c6..ec30600 100644
--- a/Interact/Handle.cs
+++ b/Interact/Handle.cs
@@ -14,10 +14,10 @@ namespace Interact
{
string head = Encoding.UTF8.GetString(headData);
JObject jsonObj = (JObject)JsonConvert.DeserializeObject(head);
- switch ((Operations)Enum.Parse(typeof(Operations), jsonObj[Strings.Operation].ToString()))
+ switch ((Operations)Enum.Parse(typeof(Operations), jsonObj[AttrNames.Operation].ToString()))
{
case Operations.Login:
- HandleLoginResult(jsonObj, data);
+ HandleLoginResult(GetResultHead(jsonObj), data);
break;
case Operations.Panic:
case Operations.TransMessage:
@@ -32,14 +32,37 @@ namespace Interact
break;
}
}
- //处理登录反馈消息
- private static void HandleLoginResult(JObject head, byte[] data)
+
+ //提取基本结果包头结构
+ private static ResultHead GetResultHead(JObject head)
{
- User user = null;
- if (head[Strings.Error].ToString() == "")
- user = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data)) as User;
+ ResultHead resultHead = new ResultHead
+ {
+ Token = head[AttrNames.Token].ToString(),
+ Operation = head[AttrNames.Operation].ToString(),
+ Error = head[AttrNames.Error].ToString()
+ };
+ return resultHead;
+ }
+
+ //处理登录反馈消息
+ private static void HandleLoginResult(ResultHead head, byte[] data)
+ {
+ //发起登录完成事件
+ if (head.Error != "")
+ OnLoginDone?.Invoke(head, null);
+ JObject dataObj = (JObject)JsonConvert.SerializeObject(data);
+ User user = new User
+ {
+ Name = dataObj[AttrNames.User].ToString(),
+ NickName = dataObj[AttrNames.NickName].ToString(),
+ Motto = dataObj[AttrNames.Motto].ToString(),
+ Group = (UserGroup)Enum.Parse(typeof(UserGroup), dataObj[AttrNames.UGroup].ToString())
+ };
OnLoginDone?.Invoke(head, user);
}
+
+
}
}
diff --git a/Interact/Interact.csproj b/Interact/Interact.csproj
index 7582ed8..331e988 100644
--- a/Interact/Interact.csproj
+++ b/Interact/Interact.csproj
@@ -36,6 +36,7 @@
+
@@ -55,7 +56,7 @@
-
+
diff --git a/Interact/JsonObject.cs b/Interact/JsonObject.cs
index 8498d7e..fd2ef53 100644
--- a/Interact/JsonObject.cs
+++ b/Interact/JsonObject.cs
@@ -3,10 +3,26 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
-//此文件定义Json序列化与反序列化时使用的数据结构,仅内部使用
-
namespace Interact
{
+ #region 定义数据交互用到的数据结构(可能作为事件或回调函数的参数)
+ //包头基本结构
+ public class BaseHead
+ {
+ //请求ID,由发送方定义的随机字符串。如果接受方有返回数据应包含相同的Token
+ public string Token;
+ //操作类型,决定数据的其他内容
+ public string Operation;
+ }
+ // 接受方返回的执行结果反馈包头,包含错误文本
+ public class ResultHead : BaseHead
+ {
+ //错误文本,为空则执行成功
+ public string Error;
+ }
+ #endregion
+
+ #region 定义Json序列化与反序列化时使用的数据结构,仅内部使用
//登录信息包头
internal class JsonLogInfoHead : BaseHead
{
@@ -14,4 +30,13 @@ namespace Interact
public string Pwd;
}
+ //用户信息
+ internal class JsonUserInfo
+ {
+ public string User; //用户名
+ public string NickName; //昵称
+ public string Motto; //个性签名
+ public string UGroup; //用户组
+ }
+ #endregion
}
diff --git a/Interact/Message.cs b/Interact/Message.cs
index 664320f..1ea5db5 100644
--- a/Interact/Message.cs
+++ b/Interact/Message.cs
@@ -6,30 +6,19 @@ using System.Threading.Tasks;
namespace Interact
{
- //定义一则用户消息
+ //定义一则用户接收到的消息
public class Message
{
- public static UInt32 MaxHeadLength; //最大包头长度
- public static UInt32 MaxMessageLength; //最大消息长度
-
+ /*保留
+ public const UInt32 MaxHeadLength = 4096; //最大包头长度
+ public const UInt32 MaxMessageLength = 0x6400000; //最大数据长度
+ */
public DateTime When { get; } //服务器接收时间
public User From; //发送者
public string Content; //消息内容
- }
-
- //包头基本结构
- public class BaseHead
- {
- //请求ID,由发送方定义的随机字符串。如果接受方有返回数据应包含相同的Token
- public string Token;
- //操作类型,决定数据的其他内容
- public string Operation;
- }
- // 接受方返回的执行结果反馈包头,包含错误文本
- public class ResultHead : BaseHead
- {
- //错误文本,为空则执行成功
- public string Error;
+
+ //将消息保存到数据库(保留)
+ protected bool Save() { return false; }
}
//从服务器接收的原始数据封包
diff --git a/Interact/Newtonsoft.Json.dll b/Interact/Newtonsoft.Json.dll
new file mode 100644
index 0000000..5b3a1eb
Binary files /dev/null and b/Interact/Newtonsoft.Json.dll differ
diff --git a/StormChat/LogForm.cs b/StormChat/LogForm.cs
index c00319b..7b99280 100644
--- a/StormChat/LogForm.cs
+++ b/StormChat/LogForm.cs
@@ -36,16 +36,17 @@ namespace StormChat
}
//登录结果处理
- private void LoginDone(JObject head, User user)
+ private void LoginDone(ResultHead head, User user)
{
Action f = delegate ()
{
btnLogin.Enabled = true;
- if (head[Strings.Error].ToString() != "")
+ if (head.Error != "")
{
- MessageBox.Show("登录失败:" + head[Strings.Error].ToString());
+ MessageBox.Show("登录失败:" + head.Error);
return;
}
+ User.Me = user;
_mainForm.Opacity = 1;
_mainForm.Show();
this.Close();
diff --git a/StormChat/StormChat.csproj b/StormChat/StormChat.csproj
index 84e4023..8931dc1 100644
--- a/StormChat/StormChat.csproj
+++ b/StormChat/StormChat.csproj
@@ -44,8 +44,7 @@
Properties\app.manifest
-
- False
+
..\Interact\Newtonsoft.Json.dll