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.