运用Smark.SocketAsyncs方便实现数据交互服务
Smark.SocketAsyncs是通过SocketAsyncEventArgs对Socket进行包装的处理程序,暂时只封装了对Tcp的支持。以下是通过Smark.SocketAsyncs封装一个简单的数据交互服务。
1)制定基础数据传输描述
实现消息转换适配器
public class MessageAdapter:Smark.SocketAsyncs.IMessage
{
public object Message
{
get;
set;
}
#region IMessage 成员
public void SaveData(Encoding coding, Smark.SocketAsyncs.SendBuffer buffer)
{
buffer.Write(Smark.Core.Functions.SerializeObject(Message));
buffer.WriteRN();
}
public void LoadData(Encoding coding, Smark.SocketAsyncs.ReceiveBuffer buffer)
{
byte[] data = buffer.ToBytes();
Message = Smark.Core.Functions.DeserializeObject(data);
}
#endregion
}
适配器主要功能是对象和byte之前的转换.
实现命令和返回类型描述
public class Command
{
public CommandType Type
{
get;
set;
}
private List<object> mParameters = new List<object>();
public List<object> Parameters
{
get
{
return mParameters;
}
}
public object this[int index]
{
get
{
return Parameters[index];
}
}
}
public enum CommandType
{
ListEmployee,
LoadEmployee
}
[Serializable]
public class Result
{
public object Data { get; set; }
public string ErrorMessage { get; set; }
}
2)服务端代码实现
建立一个控制台程序,定义相关监听对象和启用服务
string dbstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
dbstring += Smark.Core.Functions.GetPath(typeof(Program).Assembly);
dbstring += "Northwind.mdb";
DBContext.SetConnectionString(ConnectionType.Context1, dbstring);
TcpServer<TcpClient<EofAtEnter>> server = new TcpServer<TcpClient<EofAtEnter>>();
server.ClientConnected += (o, e) => {
Functions.WriteLog(LogType.Track, typeof(Program), "{0} On Connected \t {1}", e.Client.Name,DateTime.Now);
};
server.ClientDisposed += (o, e) => {
Functions.WriteLog(LogType.Track, typeof(Program), "{0} On Disposed \t {1}", e.Client.Name,DateTime.Now);
};
server.ClientError += (o, e) => {
Functions.WriteLog(LogType.Track, typeof(Program), "{0} On Error:{1} \t {2}", e.Client.Name,e.Exception.Message, DateTime.Now);
};
server.ClientReceive += (o, e) => {
try
{
Modules.Command cmd = (Modules.Command)Functions.DeserializeObject(e.Buffer.Data, e.Buffer.Count - 2);
Execute(cmd,e.Client);
}
catch (Exception e_)
{
Functions.WriteLog(LogType.Track, typeof(Program), "{0} Data Error:{1} \t {2}", e.Client.Name, e_.Message, DateTime.Now);
e.Client.Dispose();
}
};
server.Open(Functions.AppSettingValue("ip"),Functions.AppSettingValue<int>("port"),100);
Functions.WriteLog(LogType.Track, typeof(Program), "SocketAsyncsForNorthwind.ServerApp Start \t {0}",DateTime.Now);
Console.Read();
以上是构建一个Tcp服务,并以/r/n作为结束分析协议。
命令分发和处理代码
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Execute Command:" + cmd.Type);
foreach(object item in cmd.Parameters)
{
sb.AppendFormat("Parameter:{0}\r\n", item);
}
Functions.WriteLog(LogType.Track, typeof(Program), sb.ToString());
switch (cmd.Type)
{
case SocketAsyncsForNorthwind.Modules.CommandType.LoadEmployee:
LoadEmployee(cmd,client);
break;
case SocketAsyncsForNorthwind.Modules.CommandType.ListEmployee:
ListEmployee(cmd, client);
break;
}
}
static void ListEmployee(Modules.Command cmd, ITcpClient client)
{
Modules.Result resul = new SocketAsyncsForNorthwind.Modules.Result();
try
{
Expression exp = new Expression();
if (cmd.Parameters[0] != null)
exp &= Modules.Employees.firstName.Match(cmd[0]);
if (cmd[1] != null)
exp &= Modules.Employees.lastName.Match(cmd[0]);
if (cmd[2] != null)
exp &= Modules.Employees.region.Match(cmd[0]);
resul.Data = exp.List<Modules.Employees>();
}
catch (Exception e_)
{
resul.ErrorMessage = e_.Message;
}
SendData(resul, client);
}
static void LoadEmployee(Modules.Command cmd,ITcpClient client)
{
Modules.Result resul = new SocketAsyncsForNorthwind.Modules.Result();
try
{
Modules.Employees employee = DBContext.Load<Modules.Employees>(cmd.Parameters[0]);
resul.Data = employee;
}
catch (Exception e_)
{
resul.ErrorMessage = e_.Message;
}
SendData(resul, client);
}
static void SendData(object data, ITcpClient client)
{
Modules.MessageAdapter ma = new SocketAsyncsForNorthwind.Modules.MessageAdapter();
ma.Message = data;
client.Send(ma);
}
3)客户端实调用处理
客户端逻辑包装类
由于Smark.SocketAsyncs是基于异步处理的,所以为了方便调用封装一个基本同步发送和接放的包装类。
{
private System.Threading.EventWaitHandle mHandler = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset);
private TcpClient<EofAtEnter> mClient;
public NorthWindClient(string ip, int port)
{
Init(ip, port);
}
private void Init(string ip,int port)
{
mClient = TcpServer<TcpClient<EofAtEnter>>.CreateClient(ip, port);
mClient.Receive();
mClient.Error += (o, e) => {
Result = new Result();
Result.ErrorMessage = e.Exception.Message;
mHandler.Set();
};
mClient.DataReceive += (o, e) => {
byte[] data = e.Buffer.ToBytes(0, e.Buffer.Count - 2);
Result = (Modules.Result)Functions.DeserializeObject(data);
mHandler.Set();
};
}
public Result Result
{
get;
set;
}
public IList<Employees> ListEmployees(string firstname, string lastname, string region)
{
Result = null;
Modules.Command cmd = new Command();
cmd.Type = CommandType.ListEmployee;
cmd.Parameters.Add(firstname);
cmd.Parameters.Add(lastname);
cmd.Parameters.Add(region);
return (IList<Employees>)SendData(cmd);
}
public Employees LoadEmployee(int id)
{
Result = null;
Modules.Command cmd = new Command();
cmd.Type = CommandType.LoadEmployee;
cmd.Parameters.Add(id);
return (Employees) SendData(cmd);
}
protected object SendData(object data)
{
return SendData(data, 2000);
}
protected object SendData(object data,int timeout)
{
Modules.MessageAdapter ma = new MessageAdapter();
ma.Message = data;
mClient.Send(ma);
mHandler.Reset();
mHandler.WaitOne(timeout);
if (Result == null)
{
throw new Exception("超时!");
}
else if (Result.ErrorMessage != null)
{
throw new Exception(Result.ErrorMessage);
}
return Result.Data;
}
#region IDisposable 成员
public void Dispose()
{
if (mClient != null)
mClient.Dispose();
}
#endregion
}
NorthWindClient功能在初始化的时候接入的服务器,每个逻辑在请求时挂起2秒等待处理,处理错误或超时返回异常。当接收到服务端处理完后取消挂起返回处理值。
客户端UI处理代码
{
private Modules.NorthWindClient Client;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
Smark.SocketAsyncs.Utils.AsyncEventArgsPool_MAX = 10;
Client = new SocketAsyncsForNorthwind.Modules.NorthWindClient(Functions.AppSettingValue("ip"), Functions.AppSettingValue<int>("port"));
dataGridView1.DataSource = Client.ListEmployees(null, null, null);
}
catch (Exception e_)
{
MessageBox.Show(e_.Message);
}
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count>0)
{
Modules.Employees emp = (Modules.Employees)dataGridView1.SelectedRows[0].DataBoundItem;
propertyGrid1.SelectedObject = Client.LoadEmployee(emp.EmployeeID);
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
dataGridView1.DataSource = Client.ListEmployees(textBox1.Text, textBox2.Text, textBox3.Text);
}
catch (Exception e_)
{
MessageBox.Show(e_.Message);
}
}
}
相关程序代码:[url:https://smark.svn.codeplex.com/svn/Samples/SocketAsyncsForNorthwind/]
4)简单负载测试
测试用例获取所有Employee数据
运用Smark.SocketAsyncs方便实现数据交互服务相关推荐
- 干货 | 万字长文全面解析GraphQL,携程微服务背景下的前后端数据交互方案
作者简介 古映杰,携程研发高级经理,负责前端框架和基础设施的设计.研发与维护.开源项目react-lite和react-imvc作者. 前言 随着多终端.多平台.多业务形态.多技术选型等各方面的发展, ...
- 【阿里内部应用】基于Blink为新商业调控打造实时大数据交互查询服务
基于Blink为新商业调控打造实时大数据交互查询服务 案例与解决方案汇总页: 阿里云实时计算产品案例&解决方案汇总 从IT到DT.从电商到新商业,阿里巴巴的每个细胞都存在大数据的DNA,如何挖 ...
- --@angularJS--自定义服务与后台数据交互小实例
1.myService.html: <!DOCTYPE HTML> <html ng-app="app"> <head> <tit ...
- Vue与服务端数据交互 [ axios ]
Vue生命周期 每个Vue实例在被创建到销毁要经过一系列的过程,这整个过程称为Vue实例的生命周期 Vue在生命周期不同的阶段点会自动运行一些函数, 这些函数称为Vue生命周期的钩子(hook)函数 ...
- 关于服务端与客户端的数据交互
一,数据交互 一般在于客户端显而易见的就是给客户展示数据的,而服务器端就是通过拿出数据库中的数据,再通过给数据做些整理,然后这些数据变成计算机能解析的语言,传递给客户端,然后客户端再将这些数据进行展示 ...
- websocket服务端和html客户端进行二进制数据交互
一.概念和理论理解 1.HTTP HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接. 无状态:每次连接只处理一个请求,请求结束后断开连接. 无连接:对于事务处理没有 ...
- 基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互
基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互 一.前言 1.Java服务端程序代码的项目名为TcpSocketServerOfJava,包名为com.exam ...
- web服务器与网站后台程序如何交互,Dragonboard 410c搭载web服务器之后端数据交互...
相关推荐 php的正式环境部署非常简单,改几个文件就OK,用FastCgi方式也是分分钟的事情.相比起来,Py... 发表于 2018-02-09 09:26 • 756次阅读 在python世界,拥 ...
- AngularJs $resource 高大上的数据交互
$resource 创建一个resource对象的工厂函数,可以让你安全的和RESFUL服务端进行数据交互. 需要注入 ngResource 模块.angular-resource[.min].js ...
最新文章
- 检测到目标URL存在http host头攻击漏洞
- hive 常见面试题
- 转:WinForm程序中两份mdf文件问题的解决方法
- 趣学python3(6)-条件语句
- 零基础学Java有哪些必看书?推荐这5本
- 软件测试白皮书-等价类
- dell增强保护套装还原失效_汕头长安欧尚汽车音响改装升级,还原真实音色
- 数据科学学习心得_学习数据科学时如何保持动力
- C/C++中使用的正则表达式库
- linux并发控制方法,linux系统并发控制
- iPhone入门知识普及
- 数学建模主要方法与常用算法概括
- 代码行数统计工具(SourceCounter附下载链接)
- 基站的小区号256变换
- FPGA实现实时运动目标检测verilog
- animation动画全解
- win2008 有几个版本?区别是什么?
- java 美发管理系统_美容美发管理系统毕业论文.doc
- sql内外连接的区别
- Leetcode 剑指 Offer 58 - II. 左旋转字符串 LCOF - Python