基于WCF的通道网络传输数据压缩技术的应用研究

简介:
本文及程序不是介绍WCF怎么用,而是研究如何在WCF通信时的通道两端自动进行数据压缩和解压缩,从而增加分布式数据传输速度。
 
而且,这个过程是完全透明的,用户及编程人员根本不需要知道它的存在,相当于HOOK在两端的一个组件。可以使用中网络带宽较小
的网络环境中。当WCF在两个实体间通讯的时候,便自动创建一个信息通道转接通讯,这个消息包含数据请求和相应。WCF使用特殊的
编码器将请求和响应数据转换成一系列的字节。
 
    我所带的项目里遇到大文件分布式传输问题,经过分析考虑采用WCF通道压缩技术来解决此问题。执行这样的编码是需要传输大文件(XML格式)由一台机器到另一台机器传输,而连接有速度限制。经过查看了一些国外英文网站,发现我不用写一个特殊的函数边压缩和边解压,而是配置传输通道可以做到这一点,这种方式压缩可重复使用的任何契约。我发现自己编写的消息编码器是最简单的方式来实现功能,真正的问题是如何编写信息编码器,在MSDN上没有找到任何关于此应用的实例。消息契约编码器的想法是Hook连接两端发送和接收信息的渠道。程序是采用Microsoft Visual Studio 2008 WCF设计。
              
                                   图1 WCF消息通道编码过程时序图    
 
发送方:代码中加入方法,该方法及其参数的序列化成SOAP消息,消息编码序列化的信息将成为一个字节数组,字节数组发送传输层。
 接收方:传输层接收字节数组,消息编码器并行化字节数组到一条消息,该方法及其参数并行化到一个SOAP消息,方法是被监听的。 当加入压缩信息编码器,该方法要求有一点改变:发送方:代码中加入方法,该方法及其参数的序列化成SOAP消息,消息契约编码让其内在的信息编码序列的信息成为一个字节数组,消息契约编码压缩的字节数组第二个字节数组,字节数组发送传输层。

     接收方:传输层接收字节数组,消息契约编码的字节数组解压到第二字节数组,消息契约编码让其内在的信息编码化的第二个字节数组消息,该方法及其参并行化到SOAP消息,方法是被监听的。
 
     这个消息契约编码分为几个类:

     CompactMessageEncoder //这个类提供了信息编码实施。

     CompactMessageEncoderFactory //这个类是负责提供契约信息编码实例。

     CompactMessageEncodingBindingElement //这个类负责通道的协议约束规范。
 
     CompactMessageEncodingElement //这个类使信息编码通过增加应用程序配置文件。
                 
                               图2 消息通道编码器静态类图 
 
     压缩方法:契约消息编码器是使用gzip压缩的NET Framework范围内执行的,是调用System.IO.Compression.GZipStream名字空间类中。

     加入引用CompactMessageEncoder.dll,修改app.config文件引用,应用程序必须要在客户端和服务器端。
压缩缓冲代码:
private   static  ArraySegment < byte >  CompressBuffer(ArraySegment < byte >  buffer, BufferManager bufferManager,  int  messageOffset)
        {
            
//  Create a memory stream for the final message
            MemoryStream memoryStream  =   new  MemoryStream();

            
//  Copy the bytes that should not be compressed into the stream
            memoryStream.Write(buffer.Array,  0 , messageOffset);

            
//  Compress the message into the stream
             using  (GZipStream gzStream  =   new  GZipStream(memoryStream, CompressionMode.Compress,  true ))
            {
                gzStream.Write(buffer.Array, messageOffset, buffer.Count);
            }

            
//  Convert the stream into a bytes array
             byte [] compressedBytes  =  memoryStream.ToArray();

            
//  Allocate a new buffer to hold the new bytes array
             byte [] bufferedBytes  =  bufferManager.TakeBuffer(compressedBytes.Length);

            
//  Copy the compressed data into the allocated buffer
            Array.Copy(compressedBytes,  0 , bufferedBytes,  0 , compressedBytes.Length);

             
//  Release the original buffer we got as an argument
            bufferManager.ReturnBuffer(buffer.Array);

            
//  Create a new ArraySegment that points to the new message buffer
            ArraySegment < byte >  byteArray  =   new  ArraySegment < byte > (bufferedBytes, messageOffset, compressedBytes.Length  -  messageOffset);

            
return  byteArray;
        }
解压缓冲代码:
Code
   
private   static  ArraySegment < byte >  DecompressBuffer(ArraySegment < byte >  buffer, BufferManager bufferManager)
        {
            
//  Create a new memory stream, and copy into it the buffer to decompress
            MemoryStream memoryStream  =   new  MemoryStream(buffer.Array, buffer.Offset, buffer.Count);

            
//  Create a memory stream to store the decompressed data
            MemoryStream decompressedStream  =   new  MemoryStream();

            
//  The totalRead stores the number of decompressed bytes
             int  totalRead  =   0 ;

            
int  blockSize  =   1024 ;

            
//  Allocate a temporary buffer to use with the decompression
             byte [] tempBuffer  =  bufferManager.TakeBuffer(blockSize);

            
//  Uncompress the compressed data
             using  (GZipStream gzStream  =   new  GZipStream(memoryStream, CompressionMode.Decompress))
            {
                
while  ( true )
                {
                    
//  Read from the compressed data stream
                     int  bytesRead  =  gzStream.Read(tempBuffer,  0 , blockSize);
                    
if  (bytesRead  ==   0 )
                        
break ;
                    
//  Write to the decompressed data stream
                    decompressedStream.Write(tempBuffer,  0 , bytesRead);
                    totalRead 
+=  bytesRead;
                }
            }
            
//  Release the temporary buffer
            bufferManager.ReturnBuffer(tempBuffer);

            
//  Convert the decompressed data stream into bytes array
             byte [] decompressedBytes  =  decompressedStream.ToArray();

            
//  Allocate a new buffer to store the message 
             byte [] bufferManagerBuffer  =  bufferManager.TakeBuffer(decompressedBytes.Length  +  buffer.Offset);

            
//  Copy the bytes that comes before the compressed message in the buffer argument
            Array.Copy(buffer.Array,  0 , bufferManagerBuffer,  0 , buffer.Offset);

            
//  Copy the decompressed data
            Array.Copy(decompressedBytes,  0 , bufferManagerBuffer, buffer.Offset, decompressedBytes.Length);

            
//  Create a new ArraySegment that points to the new message buffer
            ArraySegment < byte >  byteArray  =   new  ArraySegment < byte > (bufferManagerBuffer, buffer.Offset, decompressedBytes.Length);

            
//  Release the original message buffer
            bufferManager.ReturnBuffer(buffer.Array);

            
return  byteArray;
        }
改变服务端配置
    加入消息契约编码器之前 app.config 的实例:
<? xml version="1.0" encoding="utf-8"  ?>
< configuration >  
    
< system.serviceModel >  
        
< services >  
            
< service  name ="Server.MyService" >
                
< endpoint 
                    
address ="net.tcp://localhost:1234/MyService"  
                    binding
="netTcpBinding"
                    contract
="Server.IMyService"   />  
            
</ service >  
        
</ services >  
    
</ system.serviceModel >
</ configuration >
加入消息契约编码器后 app.config 的例子:
Code
<? xml version="1.0" encoding="utf-8"  ?>
< configuration >  
    
< system.serviceModel >  
        
< services >  
            
< service  name ="Server.MyService" >

            
<!--  Set the binding of the endpoint to customBinding  -->                  
            
< endpoint 
                    
address ="net.tcp://localhost:1234/MyService"  
                    binding
="customBinding"
                    contract
="Server.IMyService"   />  
            
</ service >  
        
</ services >  

        
<!--  Defines a new customBinding that contains the compactMessageEncoding  -->          
        
< bindings >  
            
< customBinding >  
                
< binding  name ="compactBinding" >  
                    
< compactMessageEncoding >

                
<!--  Defines the inner message encoder as binary encoder  -->                         
                
< binaryMessageEncoding  />  
                    
</ compactMessageEncoding >  
                    
< tcpTransport  />  
                
</ binding >  
            
</ customBinding >  
        
</ bindings >  

    
<!--  Adds the extension dll so the WCF can find the compactMessageEncoding  -->
        
< extensions >  
            
< bindingElementExtensions >  
                
< add  name ="compactMessageEncoding"  type ="Amib.WCF.CompactMessageEncodingElement, CompactMessageEncoder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
            
</ bindingElementExtensions >  
        
</ extensions >  

     
</ system.serviceModel >
</ configuration >
客户端配置变化
加入消息契约编码器之前 app.config 的实例:
Code
加入消息契约编码器后 app.config 的例子:
Code
  
这种压缩方法,消息堵塞的几率很小。 使用 CompactMessageEncoder 在同一台机器运行客户端和服务器上可能会降低效率。

 

本文转自高阳 51CTO博客,原文链接:http://blog.51cto.com/xiaoyinnet/196083 ,如需转载请自行联系原作者

相关文章
|
10天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
38 11
|
2天前
|
机器学习/深度学习 安全 网络安全
网络安全词云图与技术浅谈
### 网络安全词云图与技术浅谈 本文介绍了通过词云图展示网络安全关键术语的方法,并探讨了构建现代网络安全体系的关键要素。词云图利用字体大小和颜色突出高频词汇,如恶意软件、防火墙、入侵检测系统等。文中提供了生成词云图的Python代码示例,包括安装依赖库和调整参数。此外,文章详细讨论了恶意软件防护、加密技术、身份验证、DDoS防御、社会工程学防范及威胁情报等核心技术,强调了多层次、多维度的安全策略的重要性。
30 11
网络安全词云图与技术浅谈
|
10天前
|
机器学习/深度学习 算法 PyTorch
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
本文探讨了图神经网络(GNN)与大型语言模型(LLM)结合在知识图谱问答中的应用。研究首先基于G-Retriever构建了探索性模型,然后深入分析了GNN-RAG架构,通过敏感性研究和架构改进,显著提升了模型的推理能力和答案质量。实验结果表明,改进后的模型在多个评估指标上取得了显著提升,特别是在精确率和召回率方面。最后,文章提出了反思机制和教师网络的概念,进一步增强了模型的推理能力。
33 4
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
|
15天前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
39 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
22天前
|
存储 安全 网络安全
云计算与网络安全:技术融合的双刃剑
在数字化浪潮中,云计算如同一股不可阻挡的力量,推动着企业和个人用户步入一个高效、便捷的新时代。然而,随之而来的网络安全问题也如影随形,成为制约云计算发展的阿喀琉斯之踵。本文将探讨云计算服务中的网络安全挑战,揭示信息保护的重要性,并提供实用的安全策略,旨在为读者呈现一场技术与安全的较量,同时指出如何在享受云服务带来的便利的同时,确保数据的安全和隐私。
26 6
|
26天前
|
供应链 安全 物联网安全
NIST(美国国家标准与技术研究院)在网络安全领域进行了多项创新
NIST(美国国家标准与技术研究院)在网络安全领域进行了多项创新
47 10
|
21天前
|
存储 人工智能 安全
云计算与网络安全:技术融合与挑战
在数字化时代的浪潮中,云计算和网络安全已成为推动社会进步的两大关键技术。本文将探讨云计算服务的发展,网络安全的重要性,以及信息安全技术的演进。我们将通过实例分析,揭示云服务如何增强数据保护,网络安全措施如何应对新兴威胁,以及信息安全技术的创新如何为企业带来竞争优势。文章旨在为读者提供对云计算和网络安全领域的深入理解,并展示它们如何共同塑造我们的未来。
|
20天前
|
监控 安全 网络安全
云计算与网络安全:技术挑战与解决方案
随着云计算技术的飞速发展,其在各行各业的应用越来越广泛。然而,随之而来的网络安全问题也日益凸显。本文将从云服务、网络安全和信息安全等技术领域出发,探讨云计算面临的安全挑战及相应的解决方案。通过实例分析和代码示例,旨在帮助读者更好地理解云计算与网络安全的关系,提高网络安全防护意识。
|
22天前
|
存储 安全 网络安全
网络安全的盾与剑:漏洞防御与加密技术的实战应用
在数字化浪潮中,网络安全成为保护信息资产的重中之重。本文将深入探讨网络安全的两个关键领域——安全漏洞的防御策略和加密技术的应用,通过具体案例分析常见的安全威胁,并提供实用的防护措施。同时,我们将展示如何利用Python编程语言实现简单的加密算法,增强读者的安全意识和技术能力。文章旨在为非专业读者提供一扇了解网络安全复杂世界的窗口,以及为专业人士提供可立即投入使用的技术参考。
|
23天前
|
存储 监控 安全
云计算与网络安全:云服务、网络安全、信息安全等技术领域的融合与挑战
本文将探讨云计算与网络安全之间的关系,以及它们在云服务、网络安全和信息安全等技术领域中的融合与挑战。我们将分析云计算的优势和风险,以及如何通过网络安全措施来保护数据和应用程序。我们还将讨论如何确保云服务的可用性和可靠性,以及如何处理网络攻击和数据泄露等问题。最后,我们将提供一些关于如何在云计算环境中实现网络安全的建议和最佳实践。