Chapter 4. Exchanges

This chapter explains the different ways that messages are exchanged in BEEP.

In the section Channels in Chapter 2, we saw that the application protocol designer defines a profile that specifies the rules for exchanging messages. Experience shows that these fall into three categories, with each appropriate to a particular set of interaction requirements. It’s up to the application protocol designer to decide which one to use. The three exchange styles are:

  • Client/server

  • Server/client

  • Peer-to-peer

Client/Server

The client/server exchange consists of the client sending a message, and the server sending a reply. With the traditional client/server exchange, the peer that acted as the initiator always acts as a client. BEEP doesn’t require this, however—it’s perfectly fine for the peer that’s listening for incoming connections to act as a client once a connection is established.

Because the client/server exchange is so commonplace, we don’t have to look too hard to find a good example to use for the basis of a profile. Perhaps you’re familiar with XML-RPC, a technology that uses XML to encode remote procedure calls (RPCs) that are transmitted over HTTP. The idea is straightforward, and while XML-RPC won’t win any awards for elegance or performance, it gets the job done.[3] The client/server precept is shown in Figure 4-1.

The client/server precept

Figure 4-1. The client/server precept

Since no good deed goes unpunished, XML-RPC has evolved into a more generalized messaging protocol called the Simple Object Access Protocol (SOAP). Although a purist might quibble, there are only two architectural differences between XML-RPC and SOAP:

  • XML-RPC requires the use of HTTP as a transport, while SOAP isn’t HTTP-only.

  • XML-RPC provides only for request/response remote procedure calls, while SOAP doesn’t explicitly require any particular messaging model.

Oddly enough, SOAP doesn’t have an object model, and still spends a lot of time on marshaling (encoding low-level data structures to a network representation), so it still looks more like RPC than not.[4]

For example, here’s a SOAP message:

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV='ulink url="http://schemas.xmlsoap.org/soap/envelope/'
  SOAP-ENV:encodingStyle='ulink url="http://schemas.xmlsoap.org/soap/encoding/'>
    <SOAP-ENV:Body>
       <m:GetLastTradePrice xmlns:m='Some-URI'>
           <symbol>DIS</symbol>
       </m:GetLastTradePrice>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

If you’re an XML aficionado, this makes perfect sense, obviously! If not, the key take-away is the stuff nested in the SOAP-Env:Body element. The m:GetLastTradePrice element looks like a remote procedure call, with one argument, symbol, having the value DIS. Another take-away is that the envelope doesn’t contain any addressing information—it doesn’t explicitly identify the network service that will process the call.

The precept shown in Figure 4-2 concisely describes the three things you need to do to define a profile:

  • Assign a unique identifier for the profile.

  • Indicate what gets exchanged when a channel is bound to the profile.

  • Indicate what gets passed back and forth in a client/server exchange.

The SOAP over BEEP precept

Figure 4-2. The SOAP over BEEP precept

In BEEP, there’s actually a formal “registration template” that gets filled out when you define a profile. We’ll look at one in a bit, but for now, let’s avoid the formalities and concentrate on the concepts.

The URI part is easy enough; whoever is responsible for http://clipcode.org/ assigned it. (Anyone who can assign a URI can define a profile.) Note that if a URI starts with http://iana.org/, this indicates that the profile has had some review by the IETF. In some cases, this URI-prefix indicates that the profile has been approved for the Internet standards-track.

Similarly, the client/server exchange part is pretty easy too. The request sent by the client is a SOAP message, as is the server’s reply. That’s all BEEP really cares about. But what about the initialization exchange?

When a channel is created, it may require some additional parameters before it can begin normal processing. Many profiles don’t have initialization requirements, but the SOAP profile for BEEP does. In particular, it needs to know:

  • The identity of the network service that will be processing the SOAP messages

  • Optionally, whether any special SOAP “features” might be used

Each of these serves a different purpose.

When SOAP runs over HTTP, the network service that consumes the message is identified by two parameters, e.g.:

POST /StockQuote HTTP/1.1
Host: example.com

When SOAP runs over BEEP, you need to convey the same information, but it’s carried a little differently. Recall from Channel Creation in Chapter 3 that BEEP uses the serverName attribute to identify the virtual host, e.g.:

<start number='1' serverName='example.com'>
    <profile uri='http://clipcode.org/beep/SOAP' />
</start>

So, what about the part that got sent as HTTP’s Request-URI parameter?

That’s what the bootmsg used for channel initialization is for. As soon as the channel is started, the client sends a bootmsg, e.g.:

<bootmsg resource='/StockQuote' />

Actually, using BEEP’s piggybacking feature (see the section The piggyback in Chaspter 3), the bootmsg probably gets included in the request to start the channel.

If the server likes the resource, then a bootrpy is sent back; otherwise an error is sent. Once a bootrpy is received, the client is free to start using the channel to exchange SOAP messages. (Of course, after a bootrpy is received, if another bootmsg is sent, an error is returned.)

BEEP URIs

One of the reasons I like to use SOAP as an example is because it raises an interesting question: what does a BEEP URI look like?

The short answer is that since BEEP isn’t an application protocol, there’s no such thing. A better answer is that when you design a profile, you should ask yourself whether it makes sense to define a URL scheme for the resulting protocol. In the case of the SOAP over BEEP profile, this makes a lot of sense.

Here’s some examples, all of which should be self-explanatory:

soap.beep://example.com/StockQuote
soap.beep://example.com
soap.beep://example.com:1026
soap.beep://10.0.0.2:1026

Here are some fun facts about these four examples:

  • For the first three examples, http://example.com will be used as the serverName attribute.

  • For the last three examples, “\” will be used as the resource attribute in the bootmsg.

  • For the last two examples, the BEEP listener is on TCP port 1026.

But what TCP port is the BEEP listener using in the first two examples? There are two possible choices, depending on whether you prefer using a constant value or you want to let the DNS tell you.

However, the correct answer is always to start by asking the IANA to assign a port number. At this point, ask yourself whether it would be very helpful for the DNS to distribute the load among multiple servers. If not, you’re done! Otherwise, there’s a new DNS record called SRV (RFC 2782) that associates port numbers with services and provides a weighting mechanism for services available on multiple hosts.

For example, a DNS lookup of:

_soap-beep._tcp.example.com

will return zero or more SRV records. Each contains an IP address and TCP port number, along with some parameters that let you decide the order in which you should try to use the records.

For example, consider these resource records:

$ORIGIN example.com.

_soap-beep._tcp    SRV 0 1 10288 s1.example.com.
                   SRV 0 1 10288 s2.example.com.
                   SRV 1 0 10288 backup.example.com.

These records say to try to split the load between hosts s1 and s2; if both are unavailable, they specify the backup host.

The trick is in understanding the first two numbers after the SRV. The first number is the priority (the lower the number, the better the priority), and the second number is the weight relative to all other entries with the same priority. Since s1 and s2 have the same, lowest priority number, we look at those first. They each have equal weight, so they should have an equal chance of being selected first. If a connection can’t be made to either, we go to the next highest priority, of which there’s only one entry. So, in the worst case scenario, we’ll try to make three TCP connections.

Tip

Here’s a helpful hint if you decide to use SRV records: although you can use any port number you want, you can save yourself a lot of grief by always using the IANA-assigned port number. The reason is that dynamically assigned ports aren’t supported by a lot of infrastructural software, such as packet tracers, firewalls, and the like.

SOAP Extras

That’s about it for the client/server exchange, but there’s actually a little more to the SOAP over BEEP profile. Because SOAP isn’t tied to a particular messaging model, it actually allows two other exchange styles besides request/response:

  • One-way

  • 1-request/N-responses

Both of these are handled in BEEP by using a one-to-many exchange, as shown in Figure 4-3.

A SOAP over BEEP one-to-many exchange

Figure 4-3. A SOAP over BEEP one-to-many exchange

The one thing we didn’t discuss about SOAP is the relationship between SOAP and MIME. As we’ve seen, SOAP is about exchanging envelopes that are encoded using XML. If an envelope needs to contain non-XML information, then the envelope and extra information are sent as a SOAP package. This package is nothing more than a MIME multipart/related object (RFC 2387), e.g.:

Content-Type: multipart/related; boundary="MIME_boundary";
              type=application/xml;
              start="<claim061400a.xml@example.com>"

--MIME_boundary
Content-Type: application/xml
Content-ID: <claim061400a.xml@example.com>

<?xml version='1.0' ?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
<SOAP-ENV:Body>
..
<theSignedForm href='cid:claim061400a.tiff@example.com' />
..
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: <claim061400a.tiff@example.com>

...binary TIFF image...
--MIME_boundary--
END

The Content-ID: header (RFC 2111) is used to identify each component.

The SOAP over BEEP Registration

Earlier, Figure 4-2 showed an informal description of the SOAP over BEEP profile.

Here’s a copy of the registration for the SOAP over BEEP profile:

Profile identification

http://clipcode.org/beep/SOAP

Messages exchanged during channel creation

bootmsg, bootrpy

Messages starting one-to-one exchanges

bootmsg, SOAP-Env:Envelope

Messages in positive replies

bootrpy, SOAP-Env:Envelope

Messages in negative replies

error

Messages in one-to-many exchange

SOAP-Env:Envelope

Message syntax

SOAP-Env:Envelope as defined in Section 4 of Simple Object Access Protocol (SOAP) and SOAP Messages with Attachments

Message semantics

See Simple Object Access Protocol (SOAP)

Contact information

See the “Authors’ Addresses” section of Using SOAP in BEEP

Although not part of the “formal” template, profile designers often find it useful to include a concise summary, termed a designer doodle, as a comment, e.g.:

SOAP messages, exchanged as application/xml
                client                       server reply
     role       message              positive             negative
    ======      =======              ========             ========
      I         bootmsg              bootrpy              error

    I or L      SOAP-Env:Envelope    SOAP-Env:Envelope    error

The way to read this is pretty simple:

  • The initiator sends a bootmsg and, in reply, gets back either a bootrpy or an error.

  • Then either the initiator or listener sends an Envelope and in reply gets back either an Envelope or an error.

Although brief, this synopsis leaves out some important things, such as the necessity of a successful bootmsg before sending a SOAP message. Even so, it does a good job of getting across the ideas behind the exchange.



[3] If you’d like more information on XML-RPC, check out Programming Web Services with XML-RPC by Simon St.Laurent, Joe Johnston, and Edd Dumbill.

[4] If you’d like more information on SOAP, check out Programming Web Srvices with SOAP by Doug Tidwell, James Snell, and Pavel Kulchenko.

Get BEEP: The Definitive Guide now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.