1.当遇到需要传输大量数据时,怎么样传输数据?
2.压缩数据有哪几种常见的方式?
问题1解答:通过压缩来传输数据
问题2解答:
(1)WCF自带的压缩方式
(2)自定义WCF binding进行压缩
(3)将对象序列化为JSON格式
今天来探讨一下WCF自带的压缩方式Gzip和Json序列化
我的其他WCF文章:
先上图:
1.WCF自带的压缩方式进行压缩数据及传输数据
参考资料:https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.compressionformat.aspx
总共有三种方式:
Deflate:The Deflate compression format.
GZip:The GZip compression format.
None: The none compression format.
注意,.NET framwork版本需要在4.0以上(包含4.0)。
1.1 Code的实现:
(1)Server端和Client的配置
<
binarymessageencoding
compressionformat="GZip">
<bindings>
<customBinding>
<binding name="BindingForTcp" receiveTimeout="00:05:00" sendTimeout="00:05:00">
<binaryMessageEncoding compressionFormat="GZip">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
</binaryMessageEncoding>
<httpTransport maxReceivedMessageSize="2147483647"> </httpTransport>
</binding>
</customBinding>
</bindings>
<services>
<service name="Jackson0714.WcfServices.Service.GetPersonDetailService"
behaviorConfiguration="metadataBehavior" >
<endpoint address="http://127.0.0.1:3725/GetPersonDetailService"
binding="customBinding"
bindingConfiguration ="BindingForTcp"
contract="Jackson0714.WcfServices.Service.Interface.IGetPersonDetailService" />
</service>
</services>
注意:Client和Server端必须使用相同的binding。
(2)Server端代码
打开端口,host服务
using System;
using System.ServiceModel;
using Jackson0714.WcfServices.Service;
namespace Jackson0714.WcfServices.Hosting
{
class Program
{
static void Main(string[] args)
{
ServiceHost getPersonDetailServiceHost = null;
try
{
getPersonDetailServiceHost = new ServiceHost(typeof(GetPersonDetailService));
getPersonDetailServiceHost.Open();
Console.WriteLine("GetPersonDetailService Started!");
Console.ReadKey();
}
catch(Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
finally
{
getPersonDetailServiceHost.Close();
}
}
}
}
(3)Client端代码
调用方法GetPersonDetail
using System;
using System.ServiceModel;
using Jackson0714.WcfServices.Service.Interface;
namespace Jackson0714.WcfServices.Client
{
class Program
{
static void Main(string[] args)
{
using (ChannelFactory<IGetPersonDetailService> channelFactory = new ChannelFactory<IGetPersonDetailService>("GetPersonDetailService"))
{
IGetPersonDetailService proxy = channelFactory.CreateChannel();
Console.WriteLine("Person Decription:{0}", proxy.GetPersonDetail("123").Description);
}
Console.Read();
}
}
}
(4)接口
GetPersonDetail
using Jackson0714.WcfServices.Common;
using System.ServiceModel;
namespace Jackson0714.WcfServices.Service.Interface
{
[ServiceContract(Name = "GetPersonDetailService", Namespace = "http://www.Jackson0714.com/")]
public interface IGetPersonDetailService
{
[OperationContract]
Person GetPersonDetail(string name);
}
}
(5)实现接口方法
GetPersonDetail
using Jackson0714.WcfServices.Common;
using Jackson0714.WcfServices.Service.Interface; namespace Jackson0714.WcfServices.Service
{
public class GetPersonDetailService : IGetPersonDetailService
{
public Person GetPersonDetail(string name)
{
Person person = DataAccess.MockQueryPersonDetail(name);
return person;
}
}
}
(6)Mock数据库访问层
MockQueryPersonDetail
模拟Person类的Description的数据量大小为100000字节
using Jackson0714.WcfServices.Common;
using System.Text; namespace Jackson0714.WcfServices.Service
{
class DataAccess
{
public static Person MockQueryPersonDetail(string name)
{
Person person = new Person();
person.Name = "Jackson0714";
string testString = "0123456789";
StringBuilder builder = new StringBuilder(); for(long i = 0;i<10000;i++)
{
builder.Append(testString);
}
person.Description = builder.ToString();
return person;
}
}
}
(6)Person类
Person
namespace Jackson0714.WcfServices.Common
{
public class Person
{
private string name;
public string Name
{
get
{
return this.name;
}
set
{
name = value;
}
}
private string description;
public string Description
{
get
{
return this.description;
}
set
{
description = value;
}
}
}
}
1.2 分析结果
通过WireShare抓包,可以得知Response的数据大小为Content-Length: 100352 bytes。
经过压缩后,Response的数据大小为Content-Length: 506 bytes。,远小于未压缩的数据量。
1.3 打印窗口
2.使用JSON格式的数据进行传输
Server端首先将数据序列化为Json格式的数据,String类型,Client端接收到Json格式的数据后,反序列化为Json格式的数据。
需要引入Newtonsoft.Json.dll
下载地址:http://www.newtonsoft.com/json
2.1 Code的实现:
(1)定义接口
GetPersonDetailWithJson
using Jackson0714.WcfServices.Common;
using System.ServiceModel;
namespace Jackson0714.WcfServices.Service.Interface
{
[ServiceContract(Name = "GetPersonDetailService", Namespace = "http://www.Jackson0714.com/")]
public interface IGetPersonDetailService
{
[OperationContract]
string GetPersonDetailWithJson(string name);
}
}
(2)实现接口
GetPersonDetailWithJson
使用JsonConvert.SerializeObject(person)将person序列化为Json格式的数据。
public string GetPersonDetailWithJson(string name)
{
Person person = DataAccess.MockQueryPersonDetail(name);
return JsonConvert.SerializeObject(person);
}
(3)客户端调用GetPersonDetailWithJson
使用JsonConvert.DeserializeObject<Person>(proxy.GetPersonDetailWithJson("123"))方法反序列化Json格式的数据,将Json格式的数据转换为Person对象。
using (ChannelFactory<IGetPersonDetailService> channelFactory = new ChannelFactory<IGetPersonDetailService>("GetPersonDetailService"))
{
IGetPersonDetailService proxy = channelFactory.CreateChannel();
Person person = JsonConvert.DeserializeObject<Person>(proxy.GetPersonDetailWithJson("123")); Console.WriteLine("GetPersonDetailWithJson->Person Decription:{0}", person.Description);
}
2.2 分析结果
通过WireShare抓包,可以得知Response的数据大小为Content-Length: 100263bytes。比未经过序列化的数据减少了89 bytes的数据。
这里有个问题,为什么Json格式的数据比原WCF基于XML传输的数据小???
原因是WCF的传输的数据是将对象序列化为xml格式,需要用很多标签来记录各个字段的内容。而用JSON格式的数据,已经将对象转化为键值对形式的数据,不包含标签,所以数据量减少了。
2.3 打印窗口
3.通过Json+压缩的方式传输
3.1 Code的实现
(1) 定义WCF压缩方式
<binaryMessageEncoding compressionFormat="GZip">
(2) 将对象序列化为Json格式的数据
JsonConvert.SerializeObject(person);
(3) 将Json格式的数据反序列化为对象
Person person = JsonConvert.DeserializeObject<Person>(proxy.GetPersonDetailWithJson("123"));
3.2 分析结果
从下图可以看出经过Json格式化然后压缩的数据为1004 bytes,未用Json格式化的数据为1071 bytes,减少了67个bytes。
4.通过压缩或Json格式化需要注意什么?
(1) 压缩或Json格式化需要消耗一定的资源,如果CPU和内存不足时,慎用压缩或Json格式化。
(2) 压缩或Json格式化需要消耗一定的时间,如果数据量很大,那么压缩或Json格式化的时间也很大,对于需要快速响应的系统,慎用压缩或Json格式化。
5.参考资料
https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.compressionformat.aspx
https://msdn.microsoft.com/en-us/library/ms751458(v=vs.110).aspx
我的其他WCF文章:
作 者:
Jackson0714
出 处:http://www.cnblogs.com/jackson0714/
关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!