WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(二)实现IRequestChannel(2016-03-15 12:35)
这是这个系列的第二篇,其他的文章请点击下列目录
WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(一)概要设计
WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(二)实现IRequestChannel
WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(三)实现ReplyChannel
从今天开始,一步步介绍我是如何实现自定义的ZeroMQ绑定和protocolBuffer消息编码的。
本系列的想法主要来源于蒋金楠Artech的系列博客-WCF后续之旅,和WCF开发团队成员carlosfigueira的WCF Extension系列博客。
首先要明确的是,通信和编码的实现是分离的。WCF也是这样设计的。自定义Binding包含BindingElementCollection集合,这个集合可以添加多个ElementBinding。但是有两个ElementBinding必不可少,TransportBindingElement、MessageEncodingBindingElement。而ZeroMQ只是提供了通信技术,不涉及具体的编码,它的传输数据是指定长度的字符串,至于字符串以用何种方式编码,ZeroMQ是不知道的。因此使得ZeroMQ作为WCF的自定义Binding中的TransportBindingElement的实现成为可能。我们先不管编码,先考虑传输。
WCF的通道栈在上述两个系列博客中已经有详细的介绍,我就不想重复了,直接说说我是如何将WCF和ZeroMQ衔接的。
实现IRequestChannel
新建类型ZMQRequestChannel,继承于ChannelBase,ChannelBase是WCF提供的通道基类。
首先要创建ZeroMQ的socket,类型是REQ。
socket = this.zmqContext.CreateSocket(SocketType.REQ);
socket.Connect(zmqAddress);
实现IRequestChannel的方法
public Message Request(Message message, TimeSpan timeout)
Request负责发送请求,阻塞当前线程,直到接收到服务器的回复。发送请求时,将Message转换为byte[],交给ZeroMQ发送
ArraySegment<byte> requestData = encoder.WriteMessage(message, , bufferManager);
socket.Send(requestData.Array);
转换的方式是通过encoder对象获得的,encoder就是通过MessageEncodingBindingElement创建的。MessageEncodingBindingElement是WCF信道栈的一部分,但是Message并不是沿着每个信道穿过,MessageEncodingBindingElement就是这样的信道,它只是被TransportBindingElement使用,在TransportChannel需要编码和解码时,TransportBindingElement的encoder会站出来执行自己的职责。
接收服务端的回复时,是这样做的:
byte[] replyData = bufferManager.TakeBuffer();
int replaySize = socket.Receive(replyData);
Message response = encoder.ReadMessage(
new ArraySegment<byte>(replyData, , replaySize), bufferManager);
bufferManager.ReturnBuffer(replyData);
这里使用了BufferManager提供一个接收缓存,缓存的大小暂时设为1000。使用缓存的目的在于分配时的效率更高。当接收完成时,记得回收。
IRequestChannel还需要实现异步的发送方法
IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state);
IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state);
Message EndRequest(IAsyncResult result);
参考刚才的同步方法,发送分为编码、发送。其中编码在本地完成,不会超时,发送由于依赖网络环境和服务器状态,需要将这部分移到异步过程中。
由于发送异步方法在ReplyChannel中也会使用,因此我创建了ZMQChannelBase基类,派生于ChannelBase,ZMQRequestChannel继承于新的ZMQChannelBase基类。把异步发送方法放在ZMQChannelBase中。
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
{
return base.BeginSendMessage(message, this.DefaultSendTimeout, callback, state);
}
public IAsyncResult BeginSendMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
base.ThrowIfDisposedOrNotOpen();
ArraySegment<byte> requestData = encoder.WriteMessage(message, , bufferManager); return this.BeginWriteData(requestData, timeout, callback, state);
}
BeginWriteData方法返回一个AsyncResult对象,实现异步接口IAsyncResult
class SocketSendAsyncResult : AsyncResult
{
ZMQChannelBase channel;
ArraySegment<byte> buffer; public SocketSendAsyncResult(ArraySegment<byte> buffer, ZMQChannelBase channel, AsyncCallback callback, object state)
: base(callback, state)
{
this.channel = channel;
this.buffer = buffer; this.StartSending();
} void StartSending()
{
SocketSendHandle handler = new SocketSendHandle(delegate(ZmqSocket socket, byte[] data)
{
socket.Send(data);
serviceHanledDone.Set();
}); IAsyncResult sendResult = handler.BeginInvoke(channel.socket, buffer.Array, OnSend, null); } static void OnSend(IAsyncResult result)
{
if (result.CompletedSynchronously)
{
return;
} SocketSendAsyncResult thisPtr = (SocketSendAsyncResult)result.AsyncState;
Exception completionException = null;
bool shouldComplete = false; if (shouldComplete)
{
thisPtr.Complete(false, completionException);
}
} public static void End(IAsyncResult result)
{
AsyncResult.End<SocketSendAsyncResult>(result);
}
}
至此,RequestChannel就完成了,相比ReplyChannel,RequestChannel比较简单。下一篇介绍ReplyChannel。
WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(二)实现IRequestChannel(2016-03-15 12:35)的更多相关文章
- WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(三)实现ReplyChannel(2016-03-15 12:35)
这是这个系列的第三篇,其他的文章请点击下列目录 WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(一)概要设计 WCF扩展之实现ZeroMQ绑定和protocolBuffer消息 ...
- WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(一)概要设计
在我工作的项目中含有多种操作系统.多种设备.多种开发语言,因此需要使用跨平台的通信技术和自定义的消息编码.经过技术调研,ZeroMQ+ProtocolBuffer最终成为通信技术和编码方式.但是如 ...
- WCF扩展系列 - 行为扩展(Behaviors)
原文地址:http://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html 这个系列的第一部分将会重点关注WCF行为(behaviors), ...
- 【转】WCF扩展系列 - 行为扩展(Behaviors)
原文:https://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html 这个系列的第一部分将会重点关注WCF行为(behaviors),W ...
- 真实世界:使用WCF扩展记录服务调用时间
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- WCF 服务的ABC之绑定(六)
绑定 Binding 绑定是开发人员控制WCF程序与其他消息交互的主要手段.从功能上看,绑定创建了通道工厂惑通道侦听器的堆栈对象.绑定直接惑间接创建的对象是WCF实现各种消息功能(例如,传输.安全性. ...
- WCF扩展
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- 扩展SpringMVC以支持绑定JSON格式的请求参数
此方案是把请求参数(JSON字符串)绑定到java对象,,@RequestBody是绑定内容体到java对象的. 问题描述: <span style="font-size: x-sma ...
- WCF 项目应用连载[8] - 绑定、服务、行为 大数据传输与限流 - 下 (ServiceThrottlingAttribute)
因为ORM的原因,对Attribute编程有一种情节..所以这节的出现,完全是因为在WCF对自定义Attribute的一种应用. WCF 项目应用连载[7] - 绑定.服务.行为 大数据传输与限流 - ...
随机推荐
- POJ 1166 The Clocks
高斯消元法第四个冠军,这个称号是非常令人兴奋~~ 题目大意: 给出9个钟表的状态.给出九种操作,问最少要操作几次能把全部的钟表调回12点. 解题思路: 对于9个钟表分别列方程,然后高斯消元就可以.因为 ...
- virus.win32.parite.H病毒的查杀方法
virus.win32.parite.H病毒的查杀方法 昨天电脑中了virus.win32.parite.H病毒,搞了2个多小时最终搞定了.以下记录下我的解决方法. 第一步:下载Win32.Parit ...
- poj3621 Sightseeing Cows --- 01分数规划
典型的求最优比例环问题 參考资料: http://blog.csdn.net/hhaile/article/details/8883652 此题中,给出每一个点和每条边的权值,求一个环使 ans=∑点 ...
- scala 函数编程
scala 函数编程 Effective Scala.pdf: http://www.t00y.com/file/76767869 Functional_Programming_in_Scal ...
- c#中的jQuery——HtmlAgilityPack
原文:c#中的jQuery--HtmlAgilityPack c#中是否有javascript中的jQuery类库? jQuery在访问和操作HTML 的DOM的便捷是前端开发工程师的一种福音,在c# ...
- RIA Test:try catch 对 Error #1009 (无法访问空对象引用的属性或方法)的处理
功能: 实现登录账户的强制登录, 用If 判断当前账户是否可用.若可用,则跳出if体直接登录,若不可用,则进入If体点击 “强制登录” 按钮. 问题:如果不可用,则if 条件中的对象不可见,这样程序会 ...
- haskell,lisp,erlang你们更喜欢哪个?
haskell,lisp,erlang你们更喜欢哪个? haskell,lisp,erlang你们更喜欢哪个?
- 从零開始制作H5应用(4)——V4.0,增加文字并给文字加特效
之前,我们分三次完毕了我们第一个H5应用的三个迭代版本号: V1.0--简单页面滑动切换 V2.0--多页切换,透明过渡及交互指示 V3.0--加入loading,music及自己主动切换 这已经是一 ...
- 我在开发网站后得出的asp.Net网站优化总结
原文:我在开发网站后得出的asp.Net网站优化总结 asp.Net网站优化总结: 1.数据库优化: 首先是对查询语句的优化,开发时为了图快可以不考虑,但是后期维护时就必须要优化(比如:你调用代码生成 ...
- CC 3-Palindromes(manacher)
传送门:3-Palindromes 题意:求为回文串且能整除3且不前导0的子串个数. 分析:由 manacher算法O(N)可算出以i为坐标的最长为p[i]回文子串,且Si-k,Si-k+1..... ...