利用DataSet實(shí)現(xiàn)WCF傳輸數(shù)據(jù)
在網(wǎng)上看了大量關(guān)于WCF相關(guān)的資料,WCF現(xiàn)在是一個(gè)強(qiáng)大的技術(shù),然后就產(chǎn)生一個(gè)想法.如何實(shí)現(xiàn)WCF傳輸數(shù)據(jù),這個(gè)服務(wù)的主要功能是客戶端調(diào)用服務(wù)端的一個(gè)函數(shù),這個(gè)函數(shù)接受一個(gè)DataSet的參數(shù),然后再返回一個(gè)DataSet,當(dāng)然這個(gè)功能很簡(jiǎn)單,幾行代碼就搞定了.
#T#可是當(dāng)如果DataSet內(nèi)的數(shù)據(jù)量非常大的時(shí)候, 那就麻煩了.(暫不討論傳輸大數(shù)據(jù)量的DataSet是否合理),WCF默認(rèn)最大傳輸數(shù)據(jù)量為64K,當(dāng)然可以實(shí)現(xiàn)修改配置文件來傳輸大數(shù)據(jù)量,可是不能解決本質(zhì)的問題,我目前解決這個(gè)問題的方式是,把一個(gè)DataSet序列化為一個(gè)字節(jié),然后把這些字節(jié)進(jìn)行壓縮,然后每次發(fā)送一小段字節(jié)回去,接受到這個(gè)些字節(jié)以后然后在解壓縮,再反序列化為為DataSet,這樣就實(shí)現(xiàn)了,傳入一個(gè)DataSet然后再返回一個(gè)DataSet,這樣的話,就需要用到 WCF的雙向通信,使用回調(diào)函數(shù),WCF傳輸數(shù)據(jù)代碼如下:
- DuplexChannelFactory<IHello> channelFactory = new DuplexChannelFactory<IHello>(new InstanceContext(new ClientCallBack()), "defaultEndpoint");
- IHello getHello = channelFactory.CreateChannel();
- //傳入DataSet到服務(wù)端
- getHello.SayHelloTo();
- //首先客戶端調(diào)用服務(wù)端的函數(shù)SayHelloTo(),
- public void SayHelloTo()
- {
- //讀取客戶端傳入的DataSet
- #region 服務(wù)端的數(shù)據(jù)
- ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
- int intNum = callback.getTimes() + 1; //獲取讀取字節(jié)流的次數(shù)
- MemoryStream Mstream = new MemoryStream();
- byte[] getbyte;
- for (int i = 1; i < intNum; i++)
- {
- getbyte = callback.getBytes(i);
- Mstream.Write(getbyte,0,getbyte.Length);//寫到內(nèi)存中
- }
- Mstream.Position = 0;
- getbyte = new byte[Mstream.Length];
- Mstream.Read(getbyte, 0, getbyte.Length);//從內(nèi)存中讀到getbyte中
- Mstream.Close();
- //反序列化
- ServiceData = KCDataFormatter.RetrieveDataSetDecompress(getbyte);
- //----------------------------
- //此處得到序列化以后的字節(jié),可以再反序列化為DataSet,得到DataSet就可以對(duì)個(gè)DataSet做處理,刪除,修改,
- //處理完成再把處理完成的DataSet賦值給ServiceData,就可以了
- //----------------------------
- #endregion
- }
- ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
- 此時(shí)就會(huì)調(diào)用客戶端的回調(diào)函數(shù)
- public class ClientCallBack : ICallback
- {
- #region ICallBack 成員
- //要上傳的數(shù)據(jù)
- public void getData()
- {
- DataSet ds = new DataSet("test");
- DataTable table = new DataTable("test");
- DataColumn column = new DataColumn("test");
- column.DataType = Type.GetType("System.String");
- table.Columns.Add(column);
- DataRow row;
- for (int i = 0; i < 200000; i++)
- {
- row = table.NewRow();
- row["test"] = "Hello";
- table.Rows.Add(row);
- }
- ds.Tables.Add(table);
- byte_All = KCDataFormatter.GetBinaryFormatDataCompress(ds);
- }
- private int i = 1000; //每次讀取字節(jié)的數(shù)量
- byte[] byte_All;//獲取要上傳的字節(jié)流
- MemoryStream Mstream;//流
- public byte[] getBytes(int intNum)
- {
- int j = 1000;
- byte[] buffer;
- if (intNum < iti)//判斷是否是最后一次循環(huán)
- {
- buffer = new byte[1000];
- }
- else
- {
- int nn = byte_All.Length - ((iti - 1) * 1000);
- buffer = new byte[nn];
- j = nn;
- }
- int iold = (i * (intNum - 1));//記錄上一次的字節(jié)位置
- Mstream = new MemoryStream();
- Mstream.Write(byte_All, iold, j);//從byte_All中的第iolld開始寫入j(最多不超過)個(gè)到內(nèi)存中
- buffer = Mstream.ToArray();
- Mstream.Close();
- Mstream.Dispose();
- return buffer;
- }
- private int iti = 0;//初始化循環(huán)次數(shù)
- public int getTimes()//將數(shù)據(jù)流分為多少部分
- {
- getData();
- int temp = byte_All.Length / 1000;
- int intNum = byte_All.Length % 1000 != 0 ? temp + 1 : temp;
- iti = intNum;
- return intNum;
- }
- #endregion
- }
以上就是我想出來的關(guān)于WCF傳輸數(shù)據(jù)一部分的代碼,希望大家看了會(huì)有幫助。