文章内容列表:1. 场景:2. 解决方案3. WCF契约与服务实现设计静态图4. WCF契约与服务实现设计详细说明6. 服务端启动服务代码:7. 客户端代码8. WCF大数据量传输解决方案源码下载
1. 场景:WCF在网络传输中,大数据量传输造成网络阻塞,宽带无法承受;
2. 解决方案
解决WCF在网络传输中的大数据量问题:
A.需要把相关数据序列化成字节流,再对字节流进行压缩,再进行传输,到了客户端再做反向操作便可获得原始数据。
B.如果压缩后的数据仍然较大时,可以再压缩流后,再对流进行拆分即可。
(解决方案A图) (解决方案2)3. WCF契约与服务实现设计静态图
4. WCF契约与服务实现设计详细说明契约接口详细说明服务类详细说明5. WCF契约与服务代码实现: 契约代码 1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Runtime.Serialization; 5using System.ServiceModel; 6using System.Text; 7///日期:2008-04-16 8///作者:旋风 9///来自:http://cnblogs.com/xuanfeng10namespace WCFDataTransfers11{ 1213 [ServiceContract(Namespace = "http://DataTransfers/Demao")]14 public interface IDataTransfers15 { 16 /// <summary>17 /// 获取所用压缩后字节流18 /// </summary>19 /// <returns></returns>20 [OperationContract]21 byte[] GetAllBuffer();22 /// <summary>23 /// 设置压缩后字节流分块,每一块的大小24 /// </summary>25 /// <param name="length"></param>26 [OperationContract]27 void SetBufferLength(int length);28 /// <summary>29 /// 读取压缩后字节流一块,并提升字节流的位置30 /// </summary>31 /// <returns></returns>32 [OperationContract]33 bool ReadNextBuffer();34 /// <summary>35 /// 获取当前块的字节流36 /// </summary>37 /// <returns></returns>38 [OperationContract]39 byte[] GetCurrentBuffer(); 4041 42 }4344 45}46
实现契约服务代码
1using System; 2using System.Data; 3using System.Runtime.Serialization; 4using System.Runtime.Serialization.Formatters.Binary; 5using System.IO; 6using System.IO.Compression; 7using System.Collections.Generic; 8using System.Linq; 9using System.ServiceModel; 10using System.Text; 11///日期:2008-04-16 12///作者:旋风 13///来自:http://cnblogs.com/xuanfeng 14namespace WCFDataTransfers 15{ 16 17 public class DataTransfers :IDataTransfers 18 { 19 /// <summary> 20 /// 无参数构造函数 21 /// </summary> 22 public DataTransfers() 23 { 24 25 InitBuffers(InitTestDataSet()); 26 } 27 28 private byte[] buffer_all = null; 29 private byte[] buffer_currect = null; 30 private int get_buffer_length = 1000; 31 private long remain_length; 32 private MemoryStream stream; 33 /// <summary> 34 /// 生成一个测试的数据集 35 /// </summary> 36 /// <returns></returns> 37 private DataSet InitTestDataSet() 38 { 39 DataSet ds = new DataSet("test"); 40 DataTable table = new DataTable("test"); 41 DataColumn column = new DataColumn("test"); 42 column.DataType = Type.GetType("System.String"); 43 table.Columns.Add(column); 44 DataRow row; 45 for (int i = 0; i < 100000;i++ ) 46 { 47 row = table.NewRow(); 48 row["test"] = "测试数据 !"; 49 table.Rows.Add(row); 50 } 51 52 ds.Tables.Add(table); 53 54 return ds; 55 56 } 57 /// <summary> 58 /// 初始化压缩字节流 59 /// </summary> 60 /// <param name="ds"></param> 61 private void InitBuffers(DataSet ds) 62 { 63 64 IFormatter formatter = new BinaryFormatter(); 65 MemoryStream stream_ = new MemoryStream(); 66 formatter.Serialize(stream_, ds); 67 buffer_all = stream_.ToArray(); 68 stream_.Close(); 69 byte[] bytes_c = Compression(buffer_all, CompressionMode.Compress); 70 stream = new MemoryStream(bytes_c); 71 stream.Position = 0; 72 remain_length = stream.Length; 73 74 75 } 76 /// <summary> 77 /// 提供内部使用压缩字流的方法 78 /// </summary> 79 /// <param name="data"></param> 80 /// <param name="mode"></param> 81 /// <returns></returns> 82 private byte[] Compression(byte[] data, CompressionMode mode) 83 { 84 DeflateStream zip = null; 85 try 86 { 87 if (mode == CompressionMode.Compress) 88 { 89 MemoryStream ms = new MemoryStream(); 90 zip = new DeflateStream(ms, mode, true); 91 zip.Write(data, 0, data.Length); 92 zip.Close(); 93 return ms.ToArray(); 94 } 95 else 96 { 97 MemoryStream ms = new MemoryStream(); 98 ms.Write(data, 0, data.Length); 99 ms.Flush();100 ms.Position = 0;101 zip = new DeflateStream(ms, mode, true);102 MemoryStream os = new MemoryStream();103 int SIZE = 1024;104 byte[] buf = new byte[SIZE];105 int l = 0;106 do107 { 108 l = zip.Read(buf, 0, SIZE);109 if (l == 0) l = zip.Read(buf, 0, SIZE);110 os.Write(buf, 0, l);111 } while (l != 0);112 zip.Close();113 return os.ToArray();114 }115 }116 catch117 { 118 if (zip != null) zip.Close();119 return null;120 }121 finally122 { 123 if (zip != null) zip.Close();124 }125 }126127 #region IDataTransfers 成员128 /// <summary>129 /// 获取所有字节流130 /// </summary>131 /// <returns></returns>132 public byte[] GetAllBuffer()133 { 134 if (buffer_all != null)135 return buffer_all;136 else return null;137 }138 /// <summary>139 /// 设置压缩后字节流分块,每一块的大小140 /// </summary>141 /// <param name="length"></param>142 public void SetBufferLength(int length)143 { 144 this.get_buffer_length=length;145 }146 /// <summary>147 /// 读取压缩后字节流一块,并提升字节流的位置148 /// </summary>149 /// <returns></returns>150 public bool ReadNextBuffer()151 { 152 bool bo;153 if (remain_length > 0)154 { 155 if (remain_length> get_buffer_length)156 { 157 buffer_currect = new byte[get_buffer_length];158159 stream.Read(buffer_currect, 0, get_buffer_length);160 remain_length -= get_buffer_length;161 }162 else163 { 164 buffer_currect = new byte[remain_length];165 stream.Read(buffer_currect, 0, (int)remain_length);166 remain_length = 0;167 }168169 bo = true;170 }171 else172 bo = false;173 return bo;174 175 }176 /// <summary>177 /// 获取当前块的字节流178 /// </summary>179 /// <returns></returns>180 public byte[] GetCurrentBuffer()181 { 182 if (buffer_currect != null)183 return buffer_currect;184 else185 return null;186187 }188189 #endregion190 }191}192
6. 服务端启动服务代码:
static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(DataTransfers)); Console.Write("服务中"); Console.Read(); Console.Read(); }
7. 客户端代码
1 //实例化WCF客户端 2 DataTransfersClient client = new DataTransfersClient(); 3 MemoryStream stream = new MemoryStream(); 4 byte[] buffer; 5 //获取所用块压缩流,并组装 6 while(client.ReadNextBuffer()) 7 { 8 buffer = client.GetCurrentBuffer(); 9 stream.Write(buffer,0,buffer.Length);10 }11 stream.Position = 0;12 buffer= new byte[stream.Length] ;13 stream.Read(buffer,0,buffer.Length);14 stream.Close();15 //解压压缩流16 byte[] bytes = Compression(buffer,CompressionMode.Decompress);17 stream = new MemoryStream(bytes);18 IFormatter formatter = new BinaryFormatter();19 //反序列化20 DataSet ds=(DataSet) formatter.Deserialize(stream);21 stream.Close();22 this.dataGridView1.DataSource = ds;23 this.dataGridView1.DataMember="test";24 this.label1.Text = ds.Tables[0].Rows.Count.ToString();25 client.Close();
8.