化零为整WCF(8) - 消息处理(使用流数据传输文件)

[索引页]
[源码下载]


化零为整WCF(8) - 消息处理(使用流数据传输文件)


作者: webabcd


介绍
WCF(Windows Communication Foundation) - 消息处理:使用流数据传输文件,减少内存开销


示例
1、服务
IStreamed.cs
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.ServiceModel;
using  System.IO;

namespace  WCF.ServiceLib.Message
{
    
/// <summary>
    
/// 消息契约(定义与 SOAP 消息相对应的强类型类)
    
/// </summary>

    [MessageContract]
    
public class FileWrapper
    
{
        
/// <summary>
        
/// 指定数据成员为 SOAP 消息头
        
/// </summary>

        [MessageHeader]
        
public string FilePath;

        
/// <summary>
        
/// 指定将成员序列化为 SOAP 正文中的元素
        
/// </summary>

        [MessageBodyMember]
        
public Stream FileData;
    }


    
/// <summary>
    
/// IStreamed接口
    
/// </summary>

    [ServiceContract]
    
public interface IStreamed
    
{
        
/// <summary>
        
/// 上传文件
        
/// </summary>
        
/// <remarks>
        
/// 1、支持数据流传输的绑定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding
        
/// 2、流数据类型必须是可序列化的 Stream 或 MemoryStream

        // /3、传递时消息体(Message Body)中不能包含其他数据,即参数中只能有一个System.ServiceModel.MessageBodyMember
        /// </remarks>
        
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>

        [OperationContract]
        
void UploadFile(FileWrapper fileWrapper);
    }

}


Streamed.cs
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.ServiceModel;
using  System.IO;

namespace  WCF.ServiceLib.Message
{
    
/// <summary>
    
/// IStreamed类
    
/// </summary>

    public class Streamed : IStreamed
    
{
        
/// <summary>
        
/// 上传文件
        
/// </summary>
        
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>

        public void UploadFile(FileWrapper fileWrapper)
        
{
            var sourceStream 
= fileWrapper.FileData;

            var targetStream 
= new FileStream(fileWrapper.FilePath,
                FileMode.Create,
                FileAccess.Write,
                FileShare.None);

            var buffer 
= new byte[4096];
            var count 
= 0;

            
while ((count = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
            
{
                targetStream.Write(buffer, 
0, count);
            }


            targetStream.Close();
            sourceStream.Close();
        }

    }

}



2、宿主
Streamed.cs
using  (ServiceHost host  =   new  ServiceHost( typeof (WCF.ServiceLib.Message.Streamed)))
{
    host.Open();

    Console.WriteLine(
"服务已启动(WCF.ServiceLib.Message.Streamed)");
    Console.WriteLine(
"按<ENTER>停止服务");
    Console.ReadLine();

}

App.config
<? xml version="1.0" encoding="utf-8"  ?>
< configuration >
  
< system.serviceModel >
    
< services >
      
<!-- name - 提供服务的类名 -->
      
<!-- behaviorConfiguration - 指定相关的行为配置 -->
      
< service  name ="WCF.ServiceLib.Message.Streamed"  behaviorConfiguration ="MessageBehavior" >
        
<!-- address - 服务地址 -->
        
<!-- binding - 通信方式 -->
        
<!-- contract - 服务契约 -->
        
<!-- bindingConfiguration - 指定相关的绑定配置 -->
        
< endpoint  address ="Message/Streamed"  binding ="netTcpBinding"  contract ="WCF.ServiceLib.Message.IStreamed"  bindingConfiguration ="StreamedBindingConfiguration"   />
        
< endpoint  address ="mex"  binding ="mexHttpBinding"  contract ="IMetadataExchange"   />
        
< host >
          
< baseAddresses >
            
< add  baseAddress ="http://localhost:12345/Message/Streamed/" />
            
< add  baseAddress ="net.tcp://localhost:54321/" />
          
</ baseAddresses >
        
</ host >
      
</ service >
    
</ services >
    
< behaviors >
      
< serviceBehaviors >
        
< behavior  name ="MessageBehavior" >
          
<!-- httpGetEnabled - 使用get方式提供服务 -->
          
< serviceMetadata  httpGetEnabled ="true"   />
          
< serviceDebug  includeExceptionDetailInFaults ="true" />
        
</ behavior >
      
</ serviceBehaviors >
    
</ behaviors >
    
< bindings >
      
< netTcpBinding >
          
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
          
<!-- maxReceivedMessageSize - 在采用此绑定配置的通道上可接收的最大消息大小(单位:字节) -->
          
<!-- receiveTimeout - 在传输引发异常之前可用于完成读取操作的时间间隔 -->
          
< binding  name ="StreamedBindingConfiguration"  transferMode ="Streamed"  maxReceivedMessageSize ="1073741824"  receiveTimeout ="00:10:00"   />
      
</ netTcpBinding >
    
</ bindings >
  
</ system.serviceModel >
</ configuration >


3、客户端
Streamed.cs
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.Windows.Forms;
using  System.ServiceModel;
using  System.IO;

namespace  Client2.Message
{
    
/// <summary>
    
/// 演示Message.Streamed的类
    
/// </summary>

    public class Streamed
    
{
        
/// <summary>
        
/// 流数据上传文件
        
/// </summary>
        
/// <param name="source">源文件地址</param>
        
/// <param name="destination">目标路径</param>

        public void HelloStreamed(string source, string destination)
        
{
            
try
            
{
                var proxy 
= new MessageSvc.Streamed.StreamedClient();

                var sr 
= new System.IO.FileStream(
                    source, System.IO.FileMode.Open);

                proxy.UploadFile(destination 
+ Path.GetFileName(source), sr);

                sr.Close();
                proxy.Close();

                MessageBox.Show(
"上传成功");
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(ex.ToString());
            }

        }

    }

}


App.config
<? xml version="1.0" encoding="utf-8"  ?>
< configuration >
  
< system.serviceModel >
    
< client >
      
<!-- address - 服务地址 -->
      
<!-- binding - 通信方式 -->
      
<!-- contract - 服务契约 -->
      
< endpoint  address ="net.tcp://localhost:54321/Message/Streamed"  binding ="netTcpBinding"  contract ="MessageSvc.Streamed.IStreamed"  bindingConfiguration ="StreamedBindingConfiguration"   />
    
</ client >
    
< bindings >
      
< netTcpBinding >
          
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
          
<!-- sendTimeout - 在传输引发异常之前可用于完成写入操作的时间间隔 -->
          
< binding  name ="StreamedBindingConfiguration"  transferMode ="Streamed"  sendTimeout ="00:10:00"   />
      
</ netTcpBinding >
    
</ bindings >
  
</ system.serviceModel >
</ configuration >


运行结果:
上传文件后提示上传成功


OK
[源码下载]

你可能感兴趣的:(WCF)