T B H P N

Message-Passing Communication with Queues

Introduction:

Message-Passing Communication (MPC) establishes a channel between processes to communciate by sending messages. A well known example is the communication between browsers and web servers sending request and reply messages using the HTTP protocol.

The simplest of these MPC systems is the client server model where a client sends a request message to a specified server, the server processes the message, and sends back an appropriate reply message. This request / reply sequence constitutes a talk protocol. The client initiates all message exchanges and the server simply responds. It has the benefit of a very simple message exchange sequence, but has the liability that the client must wait for a response.

Channels:

Another style is based on one-way message channels between a sender on one peer and a receiver on another, as shown in the diagram below. Each of these "peers" might be located on seperate machines or in seperate processes in the same machine.
Peer-To-Peer Communication
Note that Communication Peers may not be functionally identical.
Each peer contains a sender and receiver package. The sender communicates with one receiver at a time. The receivers each handle concurrent senders by accepting messages in a receive queue. Often those messages are processed sequentially by a single thread. This means that the receiver and consequential processing do not have to be thread safe, as long as the receiving queue is thread-safe.

End Points:

Each receiver has a listener assigned to a specific port, and we describe the ip-address and port number as an endpoint which we represent as an attribute pair ip : port. The endpoint is an address for a particular service provided by a peer. Note that the diagram emphasizes that the communication endpoints are identical, even though the processing that is provided at a particular endpoint may be quite different from that at another endpoint. The communication endpoints are peers, but the machines are not.

Talk Protocol:

The resulting talk protocol is very simple because messages only flow one way in each channel. A sender can send to an endpoint at any time, and a receiver can handle enqueued messages at any time. This makes a very flexible and fluid style of communication. The sender does not wait for a response. After sending a message it may send messages to other peers or do other processing. Eventually the receiver of the message may elect to send back a reply message to the sender, but is not required to do so. The exchange is very like threads of email that we all use.

Messages:

Messages contain a destination address so that the sender can connect to that endpoint. If the reciever will eventually reply, then, since there will be multiple senders, the message needs a return address. The message also needs to define the requested operation and provide any parameters needed to carry out the requested action. More details about messages and message-passing channels here: Communication Channel (pdf)

WCF Message-Passing Communication
The Receivers are wrappers around a WCF Service.
Senders are wrappers around a proxy for the WCF Service.

WCF Communication:

If we use a communcation framework like Windows Communication Foundation (WCF), then each message will consist of a Simple Object Access Protocol (SOAP) wrapper around a serialized instance of a data class that defines the request, the to and from addresses, and any parameters needed to execute the request.

The diagram at the right shows one possible design for peer-to-peer communication using WCF. Each Receiver instantiates a WCF service. The service objects simply enqueue incoming messages, for processing by the dequeueing thread. If a reply is appropriate the message processor builds a reply message, using the incoming message return address and passes it to its sender, usually with a PostMessage(msg) invocation.

Socket Communication:

If we craft our own communication infrastructure with sockets, we're likely to use HTTP style messages. The HTTP protocol uses messages that contain a header, consisting of text lines, where each line is an attribute pair. The message header is terminated with a blank line. If the message contains a content-length:483 attribute, that implies that the header is followed with a body containing 483 bytes of data, which need not be text.

Socket Message-Passing Communication
Receivers use Socket listeners that wait for connections.
Senders use a connection socket.
Receivers instantiate a socket listener, running on its own thread. When a connection is established, the listener passes a work-item to a thread pool thread that contains the connected socket and a reference to the blocking queue. When a thread pool thread is available, it begins framing messages by pulling bytes out of the socket, reading lines from the message header and pulling out the message body. It builds a message instance from the bytes it receives and enqueues for processing by the Message Processing Thread.

Message Queues:

Each receiver has a thread-safe blocking queue that is shared by all senders to that endpoint. If we are using WCF, we make the queue a static member of the service class so that every service instance shares the same queue, e.g., each sender to that endpoint gets a service instance and the service simply enqueues messages for the endpoint's processing thread to dequeue and process. This is the design we use for the last of the CSE681 - Software Modeling and Analysis projects.

If we are building a socket-based communication system, the listener socket, using threads from a threadpool, provides a dedicated client handler thread with the connected socket and a reference to the shared blocking queue. In CSE687 - Object Oriented Design, we will use this design for some projects.

File Transfer:

For sending a file between endpoints we could send blocks of bytes from the file in a sequence of messages, but it would be somewhat more efficient to send a beginning message that identifies the file name, length, and block size, and then a sequence of blocks of bytes, perhaps followed by a terminating message. Note that, while performing a file transfer, the service objects will simply write incoming blocks into a file, but not post them to the receive queue. When transfer is complete it posts a message to the queue so the message processor knows a file has arrived.