How (WS-) Reliable Messaging Works

来源:互联网 发布:数据库decode函数 编辑:程序博客网 时间:2024/06/14 17:56


原文地址:http://msdn.microsoft.com/en-us/library/aa480191.aspx

Even though he Windows Communication Foundation does – as you will learn – conveniently hide all the intricate details of the WS-ReliableMessaging specification from the application developer and makes the implementation of reliable messaging a mere matter of picking the right binding configuration for a service and service client, it is certainly useful to have a bit of an idea of what's going on behind the scenes and on the wire.

After all, you can only really trust a mechanism that you fully understand, right?

Reliable messaging works generally like this: A client sends a sequence of messages (the sequence may be as short as one message) across a communication link and asks the receiver to acknowledge that it has received the message(s).

The acknowledgement(s) are sent back to the client either individually and for each message, or in a single acknowledgement for a series of messages. Once the client has received the acknowledgement, it knows that the message(s) has been successfully transferred.

The TCP (Transmission Control Protocol, as in TCP/IP) works with acknowledgement messages to make sure that all data packets of a sequence are reliably transferred between two endpoints. WS-ReliableMessaging works very much in the same way – just a bit higher up on the communication stack and independent of the underlying transport. More concretely: WS-RM is designed to control reliable delivery of single SOAP messages or sequences of SOAP messages between two endpoints, irrespective of how these endpoints are connected; for instance even if messages travel through message routers or other intermediaries using different transport protocols for each of hop.

To establish a reliable messaging link between two endpoints, we first need a notion of a connection or "session". Each message sent in the context of that session is assigned a unique number denoting its order in the sequence. The sender-side (or "initiator") establishes a temporary cache to keep track of the messages sent and matches them up with the incoming acknowledgements. If a message is not acknowledged after a certain time (the "retry-timeout"), the message is resent automatically from the cache. Once an acknowledgement is received, the message can be removed from the cache.

The receiver-side (or "acceptor") establishes a cache for holding messages it accepted in order to store them before delivering them to the application. That's done because the receiving infrastructure and the application may have a "pull-relationship".

Deep down in WCF's channel architecture where the WS-RM channel is stacked on top of the transport channel and possibly some additional channels such as the security channel, arriving messages are queued up in the transport channel as they arrive.

So – and this is indeed a bit of a simplified description of how it all works – whenever a worker thread becomes available to process a message, the service model pulls a message from that transport queue through the channel stack (each channel pulls from its underlying channel) and dispatches the message into the services you write. It may look as if every message is immediately and synchronously pushed to the services you write, but in fact there is always such a pull-push translation taking place.

Because there may be a delay between the arrival of the message and the message dispatch depending on how busy the service is and because the RM channel is concerned about acknowledging arrived messages rather quickly, the RM channel will not wait for messages to flow by as they bubble up from the transport to the service model. Instead, it proactively pulls them out of the underlying transport queue as they arrive, sends out the necessary acknowledgements (if it can; we get to that later) and keeps the messages available in its own queue for pickup by the service model layer.

This cache (or queue) also serves to temporarily hold any messages received out-of-order so that messages can be delivered to the application in the order they were sent. If messages 3 and 4 of a sequence arrive before message 2, these "later" messages are held in the cache until message 2 arrives and therefore only delivered to the application once the sequence is in proper order. This happens if the application requires ordered delivery and message order enforcement is turned on (which is the default behavior).

In addition for supporting ordered delivery, the message number allows the receiver-side to detect duplicate messages and discard them. Messages can be duplicated on the path from the sender to the receiver, or be sent twice by the sender-side if an acknowledgment is lost or delayed.

It's important to note that the terms "initiator" and "acceptor" are used instead of "client" and "server", because each end of the communication path can and often will play both roles. The "client" and "server" terminology becomes easily confusing once you start to think about bi-directional communication.

If we assume having a Request/Response communication pattern, the response needs to be delivered just as reliably as the request and therefore the responding party must implement an initiator mechanism that is very similar to what the requesting party implements for the original requests. The requesting party, in turn, is playing the acceptor role for the responses. If responses get lost, they must be resent by the responding party and therefore they must also be cached (and acknowledged). Both ends of a reliable messaging session therefore maintain separate caches for outbound and inbound messages.

Whenever the communicating parties have a bi-directional (dual) communication link, the responding party can simply retry sending messages just like the requesting party would retry sending if the request cannot be delivered.

However, if the communication link doesn't allow the responding party to deliver messages independent of a client request, things get a bit more complicated. That is specifically the case with HTTP where the responding party only has an opportunity to get anything back to the requesting party when the latter comes around with another request.

To force the requesting party to come around and pick up unacknowledged responses when using HTTP, the responding party uses a simple trick: The acknowledgement for the request message is always piggybacked on the response. With that and in case of the response getting lost, the requesting party will not receive an acknowledgement and will resend the request, even though the original request might indeed have arrived at the responding party and the request was already processed. The responding party will detect such a resend request by inspecting the message's sequence number and will serve the cached response resulting from the original request from its message cache instead of re-processing the message.

Any acknowledgements for received responses are piggybacked on subsequent requests made on the same reliable session, so that the responding party can clean up its response cache. The request that carries the response acknowledgement is thereby completely unrelated – its message simply serves as the next convenient ferryboat to come along and cross the river.

The scope for a WS-ReliableMessaging session is called "Sequence" and is established by a "CreateSequence" Web service request that is sent out-of-band between the communicating endpoints. Out-of-band means that this particular request is sent and handled by the infrastructure and not surfacing as a web service call anywhere on the service model level. Once the party initiating the sequence is done with its work and has collected all outstanding acknowledgements it sends a "TerminateSequence" request – also out-of-band and "behind the scenes" as the channel is closed.

If you really were to poke around down below in the channel architecture, you would see that receiving the "CreateSequence" request causes a new channel to become available, through which all messages for the respective sequence are delivered. The "TerminateSequence" message will cause that channel to indicate the end of the sequence by delivering a null message to the receiver.


原文地址:http://msdn.microsoft.com/en-us/library/aa480191.aspx




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 打雷了怎么办主题画 打雷了怎么办小班教案 费雪小火车不走怎么办 宝宝睡觉要开灯怎么办 门上有人做记号怎么办 颜料粘上衣服洗不掉怎么办 半夜有小偷开锁怎么办 幼儿园人数较多怎么办 附近幼儿园拖班招满了怎么办 6个月大宝宝拉肚子怎么办 婴儿容易吐奶怎么办 新生儿睡眠时间颠倒怎么办 婴儿睡觉黑白颠倒怎么办 婴儿黑白颠倒了怎么办 宝宝肠粘膜受损怎么办 dnf会卡换装怎么办? 孩子不讲理蛮横怎么办 孩子不爱上学了怎么办 幼儿园孩子不爱上学怎么办 额头撞肿了怎么办 两岁半宝宝说话晚怎么办 1岁宝宝拉肚子怎么办? 小孩嗓子老哑怎么办 小孩嗓子经常哑怎么办 小孩子一年级成绩差怎么办 小孩子一年级学习成绩差怎么办 楼上有孩子扰民怎么办 隔壁小孩太吵怎么办 楼上孩子太吵怎么办 泰国贴纸签小孩怎么办 六个月宝宝近视怎么办 孩子视力低应该怎么办 儿童视力低常怎么办 视力储备值低怎么办 六个月宝宝远视怎么办 婴儿喜欢舔衣服怎么办 一岁半宝宝抵抗力差怎么办 两个月宝宝打嗝怎么办 衣服买大一码怎么办 8岁儿童头汗多怎么办 新生儿肛门红了怎么办