3

I would like to create small protocol message diagrams as seen in IETF documents (e.g. as in CoAP). Nice would be auto aligning depending the amount of text (bigger texts appear like in CoAP HLS)

Example:

Client  Server
  |      |
  |      |
  +----->|     Header: GET (T=CON, Code=0.01, MID=0x7d34)
  | GET  |   Uri-Path: "temperature"
  |      |
  |      |
  |<-----+     Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d34)
  | 2.05 |    Payload: "22.3 C"
  |      |

Is there some package that would help? msc and pgf-umlsd or tikz-uml didn't look right....

Alternativly I could "hand-draw" that using TikZ. If there's no package to help here, how would a minimal TikZ example look?

3

I think it's easy to draw some diagram like that if you start placing comments and after that use them as references to draw message interchanges.

Next code shows a minimal example. I've used matrix to create all comments and server and client labels. Of course, you don't need to use a matrix and can place them using relative positions.

The tricky part is how to align message arrows with corresponding comment first line. May be there exist better solutions but I've used \subnode command from tikzmark library. It creates an internal reference inside every comment node.

Finally it's easy to draw message interchanges with the help of intersection coordinates (|- or -|).

This is a complete code for a minimal example:

    \documentclass[tikz,border=2mm]{standalone}

    \usetikzlibrary{matrix,positioning,tikzmark}

    \begin{document}
    \begin{tikzpicture}[remember picture, % --- Dont' forget it with tikzmark ---
        comment/.style={text width=10cm, align=left},   
        font=\small\ttfamily]

    %Place `Client`, `Server` and `comment` nodes   
    \matrix{%
        \node (client) {Client}; & 
        \node (server) {Server}; & \\
        & & 
        \node[comment] (1) {\subnode{A}{Header}: 
            GET (T=CON, Code=0.01, MID=0x7d34)\\ 
            Uri-Path: "temperature"}; \\ 
        & & 
        \node[comment] (2) {\subnode{B}{Header}: 
            2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\ 
            Payload: "22.3 C"}; \\};

    %Draw vertical lines
    \draw (client) -- (client|-2.south);
    \draw (server) -- (server|-2.south);

    %Draw message interchanges
    \draw[->] (A-|client)--node[below]{GET} (A-|server) ;
    \draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
    \end{tikzpicture}
    \end{document}

Compile previous code twice to get

enter image description here

Update

If you want to align comments around colons, you can use a tabular inside comments. In this case you have to use ampersand replacement option inside \matrix because it's necessary to have different & symbols inside tabular and matrix.

\begin{tikzpicture}[remember picture, 
    comment/.style={text width=10cm, align=left},   
    font=\small\ttfamily]

%Place `Client`, `Server` and `comment` nodes   
\matrix [ampersand replacement=\&]{%
    \node (client) {Client}; \& 
    \node (server) {Server}; \& \\
    \& \& 
    \node[comment] (1) {\begin{tabular}{r@{ }l}\subnode{A}{Header}:& 
        GET (T=CON, Code=0.01, MID=0x7d34)\\ 
        Uri-Path:& "temperature"\end{tabular}}; \\ 
    \& \& 
    \node[comment] (2) {\begin{tabular}{r@{ }l}\subnode{B}{Header}:& 
        2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\ 
        Payload:& "22.3 C"\end{tabular}}; \\};

%Draw vertical lines
\draw (client) -- (client|-2.south);
\draw (server) -- (server|-2.south);

%Draw message interchanges
\draw[->] (A-|client)--node[below]{GET} (A-|server) ;
\draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
\end{tikzpicture}

The result is now

enter image description here

But, if you want to align all comments, it's better to put all of them inside a tabular. You can avoid using \matrix and place server and client labels after it. In order to separate different comments you can use \\[vertical distance] inside tabular.

Solution looks like:

\begin{tikzpicture}[remember picture, 
    font=\small\ttfamily]

%Place a `comment` node with all text inside a tabular  
 \node(comments) {\begin{tabular}{r@{ }l}
        \subnode{A}{Header}:& 
        GET (T=CON, Code=0.01, MID=0x7d34)\\ 
        Uri-Path:& "temperature"\\[3mm] 
       \subnode{B}{Header}:& 
        2.05 Content (T=ACK, Code=2.05, MID=0x7d34)\\ 
        Payload:& "22.3 C"\end{tabular}};

% Place `server` and `client` nodes
\node[above left=1mm and 0mm of comments] (server) {Server}; 
\node[left=5mm of server] (client) {Client}; 

%Draw vertical lines
\draw (client) -- (client|-comments.south);
\draw (server) -- (server|-comments.south);

%Draw message interchanges
\draw[->] (A-|client)--node[below]{GET} (A-|server) ;
\draw[<-] (B-|client)-- node[below]{2.05} (B-|server) ;
\end{tikzpicture}

And the result is:

enter image description here

  • Thank you very much! The " symbol was conflicting with my babel package set to ngerman. But after using the solution from tex.stackexchange.com/questions/117732/tikz-and-babel-error it works. – Lincoln Jan 13 '14 at 20:24
  • One last thing: How would you align the comment entries to have the colons in a row underneath each other? – Lincoln Jan 13 '14 at 20:42
  • @Lincoln: I've updated the answer with two possible solutions – Ignasi Jan 14 '14 at 10:23
  • Amazing...exactly what I was looking for! Thanks – Lincoln Jan 14 '14 at 14:09
  • I tried the third piece of code ('But, if you want to align all comments...') and got an error: ! Package pgf Error: No shape named 2 is known. I changed client|-2.south to client|-B.south and server|-2.south to server|-B.south and that worked, sort of. The vertical lines stop just south of the the second, left-pointing, arrow. What am I missing? – sgmoye Jan 14 '14 at 15:06
0

the msc package (www.ctan.org/pkg/msc mirror.ctan.org:macros/latex/contrib/msc) seems to do what you want.

of course it's not pgf-sexy...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.