開啓流模式,主要是設置一個叫TransferMode的屬性,所以,你看看哪些Binding的派生類有這個屬性就可以了。
TransferMode其實是一個舉枚,看看它的幾個有效值:
- Buffered:緩衝模式,說白了就是在內存中緩衝,一次調用就把整個消息讀/寫完,也就是我們最常用的方式,就是普通的操作協定的調用方式;
- StreamedRequest:只是在請求的時候使用流,說簡單一點就是在傳入方法的參數使用流,如 int MyMethod(System.IO.Stream stream);
- StreamedResponse:就是操作協定方法返回一個流,如 Stream MyMethod(string file_name);
一般而言,如果使用流作爲傳入參數,最好不要使用多個參數。
1、服務端
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.IO;
namespace Server
{
class Program
{
//設置服務並啓動
static void Main()
{
//服務基地址
Uri baseUri = new Uri("http://localhost:3000/Service");
//聲明服務器主機
using (ServiceHost host = new ServiceHost(typeof(MyService), baseUri))
{
//添加綁定和終結點
BasicHttpBinding binding = new BasicHttpBinding();
//啓用流模式
binding.TransferMode = TransferMode.StreamedRequest;
binding.MaxBufferSize = 1024;
//接收消息的最大範圍500M
binding.MaxReceivedMessageSize = 500*1024*1024;
host.AddServiceEndpoint(typeof(IService), binding, "test");
//添加服務描述
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
//啓動服務
try
{
host.Open();
Console.WriteLine("服務已啓動");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
//關閉服務
host.Close();
}
}
}
/// <summary>
/// 定義服務協定
/// </summary>
[ServiceContract]
public interface IService
{
[OperationContract]
ResponseMessage UpLoadFile(StreamFile stream);
}
/// <summary>
/// 實現服務協定
/// </summary>
public class MyService : IService
{
public ResponseMessage UpLoadFile(StreamFile stream)
{
ResponseMessage result=new ResponseMessage();
if (stream == null || stream.FileStream == null || string.IsNullOrEmpty(stream.FileName))
{
result.IsSuccessed = false;
result.ErrorMessage = "流文件爲空!";
return result;
}
try
{
using (FileStream fs = new FileStream(stream.FileName, FileMode.OpenOrCreate, FileAccess.Write))
{
// 我們不用對兩個流對象進行讀寫,只要複製流就OK
stream.FileStream.CopyTo(fs);
fs.Flush();
result.IsSuccessed = true;
Console.WriteLine("{0}接收到客戶端發送的流,已保存到{1}", DateTime.Now.ToLongTimeString(), stream.FileName);
}
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.IsSuccessed = false;
}
return result;
}
}
[MessageContract]
public class StreamFile
{
/// <summary>
/// 流文件名稱
/// </summary>
[MessageHeader]
public string FileName { get; set; }
/// <summary>
/// 流文件
/// </summary>
[MessageBodyMember]
public Stream FileStream { get; set; }
}
[MessageContract]
public class ResponseMessage
{
/// <summary>
/// 是否成功
/// </summary>
[MessageBodyMember]
public bool IsSuccessed { get; set; }
/// <summary>
/// 錯誤信息
/// </summary>
[MessageBodyMember]
public string ErrorMessage { get; set; }
}
}
2、客戶端
using System;
using System.Windows.Forms;
using System.IO;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "所有文件|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = ofd.FileName;
}
}
private async void btnUpLoad_Click(object sender, EventArgs e)
{
if (txtFileName.Text.Trim() == "")
{
MessageBox.Show("請選擇上傳的文件!");
btnOpen.Focus();
return;
}
btnUpLoad.Enabled = false;
FileStream fs = new FileStream(txtFileName.Text.Trim(), FileMode.Open, FileAccess.Read);
WS.ServiceClient sc = new WS.ServiceClient();
WS.StreamFile sf = new WS.StreamFile(Path.GetFileName(txtFileName.Text.Trim()), fs);
var response = await sc.UpLoadFileAsync(sf);
if (response.IsSuccessed)
{
MessageBox.Show("上傳成功");
}
else
{
MessageBox.Show(string.Format("上傳失敗!錯誤信息:{0}", response.ErrorMessage));
}
btnUpLoad.Enabled = true;
}
}
}