openkava

专注物流系统,企业信息化,进出口业务,会展,电子商务 目标:CIO 架构师
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

remoting 数据流压缩 实际例子

Posted on 2007-08-10 09:08  openkava  阅读(1518)  评论(2)    收藏  举报
分别使用nziplib 和zlib压缩数据流 ,参考其它的人所提供代码改写。
CompressHelper.cs
using System;
using System.IO;
using NZlib.Compression;
using NZlib.Streams;

namespace CompressionSink
{

    
public class CompressionHelper 
    {

        
/// <summary>
        
/// refactor  by zendy
        
/// </summary>
        
/// <param name="inStream"></param>
        
/// <returns></returns>
        public static Stream getCompressedStreamCopy(Stream inStream) 
        {
            MemoryStream outStream 
= new MemoryStream();
            Deflater mDeflater 
= new Deflater(Deflater.BEST_COMPRESSION);
            DeflaterOutputStream compressStream 
= new DeflaterOutputStream(outStream,mDeflater);

            
byte[] buf = new Byte[4096];
            
int cnt = inStream.Read(buf,0,4096);
            
while (cnt>0) {
                compressStream.Write(buf,
0,cnt);
                cnt 
= inStream.Read(buf,0,4096);
            }
            compressStream.Finish();
            
//modify by zendy //这个设置非常重要,否则会导致后续Sink在处理该stream时失败,在原来的源码中就是因为没有这个处理导致程序运行失败
            outStream.Seek(0,SeekOrigin.Begin);
            
return outStream;
        }

        
/// <summary>
        
/// refactor  by zendy
        
/// </summary>
        
/// <param name="inStream"></param>
        
/// <returns></returns>
        public static Stream getUncompressedStreamCopy(Stream inStream) 
        {
            InflaterInputStream unCompressStream 
= new InflaterInputStream(inStream); 
            MemoryStream outStream 
= new MemoryStream();
            
int mSize;
            Byte[] mWriteData 
= new Byte[4096];
            
while(true)
            {
                mSize 
= unCompressStream.Read(mWriteData, 0, mWriteData.Length);
                
if (mSize > 0)
                {
                    outStream.Write(mWriteData, 
0, mSize);
                }
                
else
                {
                    
break;
                }
            }
            unCompressStream.Close();
            
//modify by zendy//这个设置非常重要,否则会导致后续Sink在处理该stream时失败,,在原来的源码中就是因为没有这个处理导致程序运行失败
            outStream.Seek(0,SeekOrigin.Begin);
            
return outStream;
        }
    }
}
serversink.cs
using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Messaging;
using System.IO;

namespace CompressionSink
{

    
public class CompressionServerSink: BaseChannelSinkWithProperties,IServerChannelSink //,IChannelSinkBase
    {

        
private IServerChannelSink _nextSink;

        
public CompressionServerSink(IServerChannelSink next) 
        {
            _nextSink 
= next;
        }

        
public IServerChannelSink NextChannelSink 
        {
            
get 
            {
                
return _nextSink;
            }
        }
        
//异步方式    
        public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, 
            
object state, 
            IMessage msg, 
            ITransportHeaders headers, 
            Stream stream) 
        {
            
//如果客户端指定了压缩的标志,压缩数据流,默认为不压缩
            object compress = headers["Compress"];
            
if(compress != null && compress.ToString() == "True")
            {
                
// 压缩数据流
                stream=CompressionHelper.getCompressedStreamCopy(stream);
                
// forwarding to the stack for further processing
                sinkStack.AsyncProcessResponse(msg,headers,stream);
                
            }
            
else
            {
                _nextSink.AsyncProcessResponse(sinkStack,state,msg,headers,stream);
            }
            
            
        }

        
public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, 
            
object state, 
            IMessage msg, 
            ITransportHeaders headers)
        {
            
return null;
        }

        
public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, 
            IMessage requestMsg, 
            ITransportHeaders requestHeaders,
            Stream requestStream, 
            
out IMessage responseMsg, 
            
out ITransportHeaders responseHeaders, 
            
out Stream responseStream) 
        {


            
object compress = requestHeaders["Compress"];
            
if(compress != null && compress.ToString() == "True")
            {
                
// 解压请求的数据流,using NZipLib
                Stream  localrequestStream = CompressionHelper.getUncompressedStreamCopy(requestStream);

                
// pushing onto stack and forwarding the call
                sinkStack.Push(this,null);

                Stream localresponseStream;
                ServerProcessing srvProc 
= _nextSink.ProcessMessage(sinkStack,
                    requestMsg,
                    requestHeaders,
                    localrequestStream,
                    
out responseMsg,
                    
out responseHeaders,
                    
out localresponseStream);

                
// compressing the response
                responseStream=
                    CompressionHelper.getCompressedStreamCopy(localresponseStream);

                
// returning status information
                return srvProc;



            }
            
else
            {
                
//System.Net.IPAddress ip = requestHeaders[CommonTransportKeys.IPAddress] as System.Net.IPAddress;
                return _nextSink.ProcessMessage(sinkStack,requestMsg,requestHeaders,requestStream,out responseMsg,out responseHeaders,out responseStream);
            }
            
        }
    }
}
serverprovider.cs
using System;
using System.Runtime.Remoting.Channels;
using System.Collections;

namespace CompressionSink
{
    
public class CompressionServerSinkProvider: IServerChannelSinkProvider
    {
        
private IServerChannelSinkProvider _nextProvider;

        
public CompressionServerSinkProvider(IDictionary properties, ICollection providerData) 
        {
            
// not yet needed
        }

        
public IServerChannelSinkProvider Next
        {
            
get {
                
return _nextProvider; 
            }
            
set {
                _nextProvider 
= value;
            }
        }

        
public IServerChannelSink CreateSink(IChannelReceiver channel)
        {
            
// create other sinks in the chain
            IServerChannelSink next = _nextProvider.CreateSink(channel);                
    
            
// put our sink on top of the chain and return it                
            return new CompressionServerSink(next);
        }

        
public void GetChannelData(IChannelDataStore channelData)
        {
            
// not yet needed
        }

    }
}
clientsink.cs
using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Messaging;
using System.IO;


namespace CompressionSink
{
    
public class CompressionClientSink: BaseChannelSinkWithProperties,IClientChannelSink
    {
        
private IClientChannelSink _nextSink;

        
public CompressionClientSink(IClientChannelSink next) 
        {
            _nextSink 
= next;
        }

        
public IClientChannelSink NextChannelSink 
        {
            
get {
                
return _nextSink;
            }
        }


        
public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, 
                                        IMessage msg, 
                                        ITransportHeaders headers, 
                                        Stream stream) 
        {

            headers[
"Compress"= "True";
            
// generate a compressed stream using NZipLib
            stream = CompressionHelper.getCompressedStreamCopy(stream);

            
// push onto stack and forward the request
            sinkStack.Push(this,null);
            _nextSink.AsyncProcessRequest(sinkStack,msg,headers,stream);
        }


        
public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, 
                                            
object state, 
                                            ITransportHeaders headers, 
                                            Stream stream) 
        {

            
// deflate the response
            stream = 
                CompressionHelper.getUncompressedStreamCopy(stream);

            
// forward the request
            sinkStack.AsyncProcessResponse(headers,stream);
        }


        
public Stream GetRequestStream(IMessage msg, 
                                       ITransportHeaders headers) 
        {
            
return _nextSink.GetRequestStream(msg, headers);
        }


        
public void ProcessMessage(IMessage msg, 
                                   ITransportHeaders requestHeaders, 
                                   Stream requestStream, 
                                   
out ITransportHeaders responseHeaders, 
                                   
out Stream responseStream) 
        {
            requestHeaders[
"Compress"= "True";
            
// generate a compressed stream using NZipLib

            Stream localrequestStream  
= 
                CompressionHelper.getCompressedStreamCopy(requestStream);

            Stream localresponseStream;
            
// forward the call to the next sink
            _nextSink.ProcessMessage(msg,
                                     requestHeaders,
                                     localrequestStream, 
                                     
out responseHeaders, 
                                     
out localresponseStream);

            
// deflate the response
            responseStream = CompressionHelper.getUncompressedStreamCopy(localresponseStream);

        }
    }
}
clientprovider.cs
using System;
using System.Runtime.Remoting.Channels;
using System.Collections;

namespace CompressionSink
{
    
public class CompressionClientSinkProvider: IClientChannelSinkProvider
    {
        
private IClientChannelSinkProvider _nextProvider;

        
public CompressionClientSinkProvider(IDictionary properties, ICollection providerData) 
        {
            
// not yet needed
        }

        
public IClientChannelSinkProvider Next
        {
            
get {
                
return _nextProvider;
            }
            
set {
                _nextProvider 
= value;
            }
        }

        
public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData) 
        {
            
// create other sinks in the chain
            IClientChannelSink next = _nextProvider.CreateSink(channel,
                url,
                remoteChannelData);    
    
            
// put our sink on top of the chain and return it                
            return new CompressionClientSink(next);
        }
    }
}
在这个基础上,分别建立俩个项目,一个是客户端项目,一个是服务端项目。
服务端:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Collections;

namespace Server
{
    
class ServerStartup
    {    
private const string REMOTEAPPLICATIONNAME="";

        
public static void Main(String[] args) 
        {
            
//RemotingConfiguration.Configure("server.exe.config");
            Go();
            Console.WriteLine(
"Press <return> to exit");
            Console.ReadLine();
        }

        
static void Go()
        {
            IDictionary props 
= new Hashtable();
            props[
"name"= "server";
            props[
"port"= "5555";   
              
 
            CompressionSink.myClientSinkProvider  myclientSinkProvider 
=new CompressionSink.myClientSinkProvider (null,null);
            CompressionSink.myServerSinkProvider myServerSinkProvider 
= new CompressionSink.myServerSinkProvider(null,null);

            System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider soapclientSinkProvider 
= new System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider();
            System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider soapserverSinkProvider 
= new SoapServerFormatterSinkProvider();
 

            
//            serverSinkProvider.Next = new System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider();
//            myServerSinkProvider.Next = serverSinkProvider; 
 
            myServerSinkProvider.Next 
=  soapserverSinkProvider;
            soapclientSinkProvider.Next 
=myclientSinkProvider;

            ChannelServices.RegisterChannel(
new HttpChannel(props, myclientSinkProvider,myServerSinkProvider));

              
             

//            System.Runtime.Remoting.Channels.IChannel chanel1=new System.Runtime.Remoting.Channels.Tcp.TcpChannel(8888);
//            System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(chanel1);
//
//            System.Runtime.Remoting.Channels.IChannel chanel2=new System.Runtime.Remoting.Channels.Http.HttpChannel (5555);
//            System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(chanel2);
//            
            RegisterRemoteType(typeof(Service.SomeSAO ));
             
        }

        
static void RegisterRemoteType(Type type)
        {
            System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(type, type.Name
+ ".remote",System.Runtime.Remoting.WellKnownObjectMode.Singleton);
        }
    }
}
客户端:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Contexts ;
using System.Runtime.Remoting.Channels ;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Services  ;
using System.Threading;
using Service; // from service.dll
using System.Collections;
using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Drawing.Imaging ;
using System.IO ; 

namespace Client
{

    
class Client
    {
        
static void Main(string[] args)
        {
//            String filename = "client.exe.config";
//
//            RemotingConfiguration.Configure(filename);    
            
 
            
//试用压缩Sink
            CompressionSink.myClientSinkProvider  myclientSinkProvider =new CompressionSink.myClientSinkProvider (null,null);
            CompressionSink.myServerSinkProvider myServerSinkProvider 
= new CompressionSink.myServerSinkProvider(null,null); 

            System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider soapclientSinkProvider 
= new System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider();
            System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider soapserverSinkProvider 
= new SoapServerFormatterSinkProvider();
 
            

            myServerSinkProvider.Next 
=soapserverSinkProvider ;
           
// soapclientSinkProvider.Next = myclientSinkProvider;

            IDictionary props 
= new Hashtable();
            
// props["name"] = "HttpClientChannel";
            
//props["priority"] = 100;  
      
            ChannelServices.RegisterChannel(
new HttpChannel(props, soapclientSinkProvider,soapserverSinkProvider));
            
//ChannelServices.RegisterChannel(new SoapClientFormatterSink(clientSink));
            
            System.Text.StringBuilder str 
= new System.Text.StringBuilder();
            
for(int i=0;i<90000;i++) str.Append(i.ToString());
             
            
            SomeSAO obj 
= (SomeSAO) Activator.GetObject(typeof(SomeSAO),"http://localhost:5555/SomeSao.remote");
            String res 
= obj.doSomething(str.ToString());
//            System.Drawing.Bitmap bt = new System.Drawing.Bitmap("c:\\myjpeg.jpg");
//            System.IO.MemoryStream instream = new MemoryStream();
//            bt.Save(instream,ImageFormat.Jpeg);
//            instream.Seek(0,System.IO.SeekOrigin.Begin );
//
//            obj.ReceiveScreen(bt)         ;
                 
//            Form2 f = new Form2();
//            f.ShowDialog();
            Console.WriteLine("Got result: {0}",res);
            Console.ReadLine();
        }    
    }
}

也可以使用配置文件配置,在这里直接创建通道。
完整例子下载:
https://files.cnblogs.com/openkava/RemotingCompression.rar