日志 20071206 (WCF Architecture)
(1)可以迫使自己写日志的时候记录、思考得更认真一些
(2)这种日志比那种形成主题的随笔更加随意
(3)和大家分享
1.自己曾经到Artech的blog上询问过关于WCF处理大文件传输的问题,里面得到了两个非常好的提醒:
(1)Artech提到一片MSDN的文章,题目就叫 Large Data and Streaming ,自己接下来就要看
(2)idior提到用MTOM来解决,这也将作为俺的技术备选。我们传输邮件的时候,smtp协议对附件的发送采用的就是这种机制(MTOM messages are packaged as multipart/related MIME sequences with the root part being the actual SOAP message)。
2.在别人网页上看到一幅关于WCF结构的很好的图,摘录一下:
![](/images/cnblogs_com/xingyukun/wcfarchitecture.png)
图中不仅明确体现出ABC的各自分工,对WCF整个管道式的处理机制也体现的很形象。
接下来,自己又看到了另一篇很好的文章 Data Transfer Architectural Overview
3.整个WCF的运行时又可分为两大部分:信道栈(channel stack)和服务框架(service framework),将两部分联系在一起的就是Message。上图中,A+B应该大体属于信道栈的范畴,而C是服务框架。把一个Message实例转化为字节类的操作叫做encoding,反之叫做decoding,这些操作正是上图中Encoder(类似MessageEncoder这样的类)的工作内容。
所以,所有的Message一般都归入两种类型:outgoing(被服务框架创建,交给信道栈去发送)或者incoming(来自信道栈,交由服务框架去解释)。不管是信道栈还是服务框架都可以用缓存(Buffered)或者流化(Streamed)的方式来处理Message。其中缓冲的方式意味着,一个Message在被处理之前,已经被整个缓存在内存里了(想一想,如果这个Message包含了一个500MB的上传文件,会怎样?)。而流化的方式使得消息发送方以流的方式来产生要发送的内容,而消息框架会持续不断的把流里的数据发送给消息接收方。 下面是MSDN中给出的这两种编码方式所对应的WCF框架的操作方式:
Operation | Comment |
---|---|
Encoding, Buffered |
In buffered mode, the encoder normally creates a variable-size buffer and then creates an XML writer over it. It then calls WriteMessage on the message being encoded, which writes out the headers and then the body using WriteBodyContents as explained in the section about Message in this topic. The contents of the buffer (represented as an array of bytes) are then returned for the transport channel to use. |
Encoding, Streamed |
In streamed mode, the operation is similar to the above but simpler. There is no need for a buffer. An XML writer is normally created over the stream and WriteMessage is called on the Message to write it out to this writer. |
Decoding, Buffered |
When decoding in buffered mode, a special Message subclass that contains the buffered data is normally created. The headers of the message are read, and an XML reader positioned on the message body is created. This is the reader that will be returned with GetReaderAtBodyContents. |
Decoding, Streamed |
When decoding in streamed mode, a special Message subclass is normally created. The stream is advanced just enough to read all the headers and position it on the message body. An XML reader is then created over the stream. This is the reader that will be returned with GetReaderAtBodyContents. |
4.偶然看到了关于Base64编码的原理:
其实极其简单,挑出64个可见字符,每个字符代表一个6bit的bit序列,然后就可以把要编码的内存数据按6bit为单位进行编码了。这里要注意的是,由于每一个字符一般需要8个bit来保存,所以Base64编码有4:3的空间占用。
5.一般来说,我们会认为把数据编码成XML文本比将其编码为2进制格式要浪费空间。但在做这个结论前,有两点必须考虑:
(1)2进制数据不易读,所以一般会附带自己的格式信息(元数据),这部分格式信息也是有空间开销的。如果某个特定格式的节点在一段数据中反复多次出现,元数据在这方面的优势才能体现出来。
(2)对于一些数据信息(如阿拉伯数字),由于Base64编码造成的体积膨胀,2进制格式在空间上的占用要高于文本格式。
6.对MTOM的几个初步印象
(1)因为一个MTOM消息会被拆解成若干个MIME包,不管是MIME的元数据还是装包拆包的时间都是一种开销。所以只有当要传送的数据量足够大(msdn上说是1K)的时候,使用MTOM才合算。那么对于我要开发的文件传输组件,由于文件大小不一,所以可能要综合使用多种编码手段了。
下班了,明日继续 ^_^