最近在做区域医疗中PIX时, 需要让PIX Manager同时支持HL7的V2和V3版本。思路是利用WCF来同时支持V2版本的c/s架构式的消息协议和V3版本WebService的Soap协议。

 实现步骤

1.发现WCF默认不支持原始字节流传输, 即访问WCF的Server端的消息都已被MSFT封装(内部是xml),即使用各种MessageEncoder也不可以, WCF会把需要传输的数据封装到xml的body部分。
2.经过试验, 想要实现传输原始字节流, 从下到上必须实现自定义IChannel,自定义ChannelBase,自定义RequestContext,自定义Listener和Factory,自定义TransportBindingElement,自定义MessageEncoder,自定义MessageEncoderFactory,自定义MessageEncoderBindingElement, 自定义Binding,以上部分组合即可以实现Channel级接受原始数据。
3.如果想要把自定义Channel的实现封装成Endpoint, 还需要实现ChannelDispatcherBase和ServiceHostBase
4.如果WCF宿主在Windows服务或者IIS中,还需要实现ServiceHostFatoryBase

实现过程中需要注意几点:
1.默认Channel都是Message结构, 即WCF封装的消息结构,无法接受原始数据流, 因此必须实现自定义Channel。
2.如果实现自定义Channel,则默认的Endpoint不支持此Channel, 因为ServiceHost内部默认调用DispatcherBuilder 的 GetSupportedChannelTypes, 此方法返回默认的几个Channel, 比如IReplyChannel,IRequestChannel,IInputChannel等等。
3.可以利用Behavior来对Service,Endpoint,Contract等等各个级别进行过滤, 需要利用MessageFilter
4.使用Behavior时, 在调用Service的Open方法之前加入。
5.在实现ServiceHostBase时,重载的CreateDescription必须返回新的ServiceDescription。另外out IDictionary<string, ContractDescription> implementedContracts 的输出参数也必须实现, 基本思路就是根据要加入的Service类型,反射后得到利用ContractDescription.GetContract得到Service声明的接口的各个ContractDescription,然后添加到字典里。字典的key为ContractDescription.ConfigurationName
6.在实现ServiceHostBase时, 构造里必须调用InitializeDescription(new UriSchemeKeyedCollection(baseAddresses));, 不然后续的AddServiceEndpoint会失败。
7.自定义实现的此原始Socket数据流Channel的ServiceHost可能和其他的默认ServiceHost有冲突, 无法共存, 即此ServiceHost只能监听自定义Channel而无法初始化默认Channel的BuildChannelListener。 解决办法是:(1)创建2个ServcieHost, 比如PIX,一个ServiceHost支持V2,另一个支持V3. (2)就是在ServiceHost的InitializeRuntime里调用Base.InitializeRuntime,但是由于此方法会把Endpoints里的所有channel都初始化,而系统不支持其他自定义Channel接口,导致初始化失败。使用此方法时就需要把自定义channel的endpoint放到最后调用AddServiceEndpoint。然后在出现异常时, 主动调用自定义Binding的BuildChannelListener,然后通过自定义ChannelDispatcher,把Listener放到ServiceHost里。
8.在实现自定义ChannelBase时, 内部使用TcpListener和TcpClient来接受Client发来的请求,然后利用NetworkStream来解析byte数组。BufferManager来负责数据的缓冲区。
9.实现自定义Router时, 即把接受字节流路由到对应方法时, 可以根据自己业务规则, 解析字节流, 然后根据ServiceHost.Description.Endpoints的ContractDescription.Operations获取对应方法后, 调用传参。

参考链接:
9.通用的自定义ChannelBase如何实现:http://www.cnblogs.com/artech/archive/2008/07/09/1238626.html

最新文章

  1. Wix 安装部署教程(十六) -- 自动生成多语言文件
  2. Oracle数据库,模糊查询、去重查询
  3. [LintCode] Wiggle Sort 扭动排序
  4. Codeforces Round #222 (Div. 1) C. Captains Mode 对弈+dp
  5. T-SQL XQuery (XML路径查询) (转)http://blog.csdn.net/Beirut/article/details/8150116
  6. yii2 日志(log)的配置与使用
  7. WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键
  8. Sass与Compress实战:第四章
  9. 配置mac自带的Apache服务器
  10. Java中的内存分配
  11. 云数据库PolarDB(一)
  12. linux命令之df
  13. PHP爬虫框架Beanbun使用
  14. bzoj3992
  15. i2c总线,核心,驱动详解
  16. Android View之布局加载流程
  17. 火狐FireFox看视频不能全屏显示的问题
  18. csrf_token之全局认证与局部认证
  19. java基础强化——深入理解java注解(附简单ORM功能实现)
  20. 02.树的序列化与反序列化(C++)

热门文章

  1. 【Linux】OpenWRT的无线设置注意事项——从2.4G到5G,hwmode不简单
  2. 【转】iOS安全之RSA加密/生成公钥、秘钥 pem文件
  3. pjax简单实例
  4. POJ 2965:The Pilots Brothers&amp;#39; refrigerator
  5. inclusion_tag 看图
  6. C#Panel 控件的使用
  7. 字符串的朴素模式和KMP模式匹配
  8. [IR课程笔记]Hyperlink-Induced Topic Search(HITS)
  9. Java for LeetCode 131 Palindrome Partitioning
  10. mac下编译FFmpeg-Android