Participants want to engage in a two-way conversation.
How can participants engage in a two-way communication when each participant is limited to outbound requests?
- Many underlying communication protocols such as TCP are connection-oriented, meaning one participant has to initiate a connection to the other participant. Once established, the connections allows data exchange in both directions.
- Many networks restrict communication to outbound requests, meaning data can only be received as a response to a request but not unsolicited.
The participants make outbound requests to a Relay which makes messages from one participant available to the other.
The Relay conversation involves the following participants:
- The Initiator initiates the conversation by sending a message to the Relay. The Initiator may not be aware of the identity of the Partner.
- The Relay listens for messages and stores them until the Partner requests a message.
- The Partner requests messages from the Relay and processes them, sending responses back to the Relay.
A Relay is useful to enable inbound and outbound communication when both participants reside behind a firewall or a Proxy.
While only the transmission of a simple message from the Initiator to the Partner is shown in the solution sketch, a Relay can support any type of conversation; each message transmission that is part of the conversation is split into two parts: a message sent to the Relay and Polling by the recipient. For example, a Asynchronous Request-Response conversation can be implemented over a Relay by using one Relay for each direction:
A Relay can introduce significant overhead into a conversation because for each message Polling is used, which results in many messages (with empty results) being exchanged for a single message of the "higher level" conversation. This happens when basic HTTP connections are used by two participants which need to exchange data but each reside behind a firewall. Due to this inefficiency, most modern web-based systems either use Bidirectional-streams Over Synchronous HTTP (BOSH) or WebSockets to avoid excessive Polling. Instead of short-lived polling requests BOSH has the Partner make a long-running request that stays open until data is returned.
Because the Initiator and the Partner don't communicate directly with each other, an additional addressing scheme on top of the addressing scheme of the message transport is needed. For example, if the Initiator uses HTTP as the underlying protocol, it will connect to the URL of the Relay and transmit the message data. For the Partner to receive the right message it needs to have a way to specify which messages it is interested in. The same addressing scheme (URL's) can be used as extra data in the messages. Other setups use addressing schemes from related distributed system architectures such as tuple spaces, which stores tuples into a "blackboard", which can be retrieved by other participants, as it is implemented for example in Jini JavaSpaces. The purpose of such systems generally goes much beyond that of a Relay, though, to build a collaborative distributed computing environment. In contrast, a Relay is merely trying to overcome restrictions in the communication channels.
Unlike a ProxyA Relay needs to store content between the time the Initiator makes it available and the time when the Partner picks it up. This makes the Relay a stateful component. Such a storage intermediary can be likened to a Blackboard architecture. As messages have to be buffered by the Relay and are generally to be delivered in order, a one-way Relay can be built using a Messaging system and a Polling Consumer is used: the Initiator places messages into the Message Channel to be picked up by the Partner.
As a stateful component, a Relay must manage its resources, e.g. by using Resource Management patterns, such as a Lease. If Messaging is used to implement the Relay, Message Expiration is commonly used.
Same as with a Proxy, a Relay "sees" all messages exchanged between the participants. The participants must therefore trust the Relay or use additional encryption on the messages. Furthermore, participants may not know the identities of their conversation partners. This may be a design feature, but can also introduce security risks.
Example: Chat Server (XMPP)
Example: Amazon SQS (Simple Queue Service)
Amazon Web Services can serve as a one-way Relay by using their their Simple Queue Service. The addressing scheme used is a queue name which is specified on top of the "endpoint", which identifies the data center the queue is hosted in. When creating a queue you also specify the Message Expiration policy. You can add messages to the queue via HTTP GET or POST and retrieve messages via HTTP GET as in the following example:
http://sqs.us-east-1.amazonaws.com/123456789012/testQueue/?Action=ReceiveMessage&WaitTimeSeconds=10&MaxNumberOfMessages=5&AUTHPARAMSYou can use multiple queues to implement other conversations, e.g. a pair of queues to implement asynchronous Asynchronous Request-Response. To avoid excessive Polling, Amazon promotes using Long Polling, which delays sending a response instead of sending an empty response quickly
Related patterns: Lease, Message Channel, Message Expiration, Messaging, Polling, Polling Consumer, Proxy, Asynchronous Request-Response, Resource Management