• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Messages</title>
5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Beast">
8<link rel="up" href="../using_websocket.html" title="WebSocket">
9<link rel="prev" href="decorator.html" title="Decorator">
10<link rel="next" href="control_frames.html" title="Control Frames">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="decorator.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="control_frames.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h3 class="title">
27<a name="beast.using_websocket.messages"></a><a class="link" href="messages.html" title="Messages">Messages</a>
28</h3></div></div></div>
29<p>
30        Once a websocket session is established, messages can be sent unsolicited
31        by either peer at any time. A message is made up of one or more <span class="emphasis"><em>messages
32        frames</em></span>. Each frame is prefixed with the size of the payload in
33        bytes, followed by the data. A frame also contains a flag (called 'fin')
34        indicating whether or not it is the last frame of the message. When a message
35        is made up from only one frame, it is possible to know immediately what the
36        size of the message will be. Otherwise, the total size of the message can
37        only be determined once the last frame is received.
38      </p>
39<p>
40        The boundaries between frames of a multi-frame message are not not considered
41        part of the message. Intermediaries such as proxies which forward the websocket
42        traffic are free to "reframe" (split frames and combine them) the
43        message in arbitrary ways. These intermediaries include Beast, which can
44        reframe messages automatically in some cases depending on the options set
45        on the stream.
46      </p>
47<div class="caution"><table border="0" summary="Caution">
48<tr>
49<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../../doc/src/images/caution.png"></td>
50<th align="left">Caution</th>
51</tr>
52<tr><td align="left" valign="top"><p>
53          An algorithm should never depend on the way that incoming or outgoing messages
54          are split up into frames.
55        </p></td></tr>
56</table></div>
57<p>
58        Messages can be either text or binary. A message sent as text must contain
59        consist of valid utf8, while a message sent as binary may contain arbitrary
60        data. In addition to message frames, websocket provides <span class="emphasis"><em>control
61        frames</em></span> in the form of ping, pong, and close messages which have
62        a small upper limit on their payload size. Depending on how a message is
63        framed, control frames may have more opportunities to be sent in-between.
64      </p>
65<h5>
66<a name="beast.using_websocket.messages.h0"></a>
67        <span class="phrase"><a name="beast.using_websocket.messages.sending"></a></span><a class="link" href="messages.html#beast.using_websocket.messages.sending">Sending</a>
68      </h5>
69<p>
70        These stream members are used to write websocket messages:
71      </p>
72<div class="table">
73<a name="beast.using_websocket.messages.websocket_stream_write_operation"></a><p class="title"><b>Table 1.33. WebSocket Stream Write Operations</b></p>
74<div class="table-contents"><table class="table" summary="WebSocket Stream Write Operations">
75<colgroup>
76<col>
77<col>
78</colgroup>
79<thead><tr>
80<th>
81                <p>
82                  Function
83                </p>
84              </th>
85<th>
86                <p>
87                  Description
88                </p>
89              </th>
90</tr></thead>
91<tbody>
92<tr>
93<td>
94                <p>
95                  <a class="link" href="../ref/boost__beast__websocket__stream/write/overload2.html" title="websocket::stream::write (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">write</span></code></a>, <a class="link" href="../ref/boost__beast__websocket__stream/async_write.html" title="websocket::stream::async_write"><code class="computeroutput"><span class="identifier">async_write</span></code></a>
96                </p>
97              </td>
98<td>
99                <p>
100                  Send a buffer sequence as a complete message.
101                </p>
102              </td>
103</tr>
104<tr>
105<td>
106                <p>
107                  <a class="link" href="../ref/boost__beast__websocket__stream/write_some/overload2.html" title="websocket::stream::write_some (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">write_some</span></code></a>, <a class="link" href="../ref/boost__beast__websocket__stream/async_write_some.html" title="websocket::stream::async_write_some"><code class="computeroutput"><span class="identifier">async_write_some</span></code></a>
108                </p>
109              </td>
110<td>
111                <p>
112                  Send a buffer sequence as part of a message.
113                </p>
114              </td>
115</tr>
116</tbody>
117</table></div>
118</div>
119<br class="table-break"><p>
120        This example shows how to send a buffer sequence as a complete message.
121      </p>
122<pre class="programlisting"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">b</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span>
123
124<span class="comment">// This sets all outgoing messages to be sent as text.</span>
125<span class="comment">// Text messages must contain valid utf8, this is checked</span>
126<span class="comment">// when reading but not when writing.</span>
127
128<span class="identifier">ws</span><span class="special">.</span><span class="identifier">text</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
129
130<span class="comment">// Write the buffer as text</span>
131<span class="identifier">ws</span><span class="special">.</span><span class="identifier">write</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>
132</pre>
133<p>
134        The same message could be sent in two or more frames thusly.
135      </p>
136<h5>
137<a name="beast.using_websocket.messages.h1"></a>
138        <span class="phrase"><a name="beast.using_websocket.messages.receiving"></a></span><a class="link" href="messages.html#beast.using_websocket.messages.receiving">Receiving</a>
139      </h5>
140<div class="table">
141<a name="beast.using_websocket.messages.websocket_stream_read_operations"></a><p class="title"><b>Table 1.34. WebSocket Stream Read Operations</b></p>
142<div class="table-contents"><table class="table" summary="WebSocket Stream Read Operations">
143<colgroup>
144<col>
145<col>
146</colgroup>
147<thead><tr>
148<th>
149                <p>
150                  Function
151                </p>
152              </th>
153<th>
154                <p>
155                  Description
156                </p>
157              </th>
158</tr></thead>
159<tbody>
160<tr>
161<td>
162                <p>
163                  <a class="link" href="../ref/boost__beast__websocket__stream/read/overload2.html" title="websocket::stream::read (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">read</span></code></a>, <a class="link" href="../ref/boost__beast__websocket__stream/async_read.html" title="websocket::stream::async_read"><code class="computeroutput"><span class="identifier">async_read</span></code></a>
164                </p>
165              </td>
166<td>
167                <p>
168                  Read a complete message into a <a class="link" href="../concepts/DynamicBuffer.html" title="DynamicBuffer"><span class="emphasis"><em>DynamicBuffer</em></span></a>.
169                </p>
170              </td>
171</tr>
172<tr>
173<td>
174                <p>
175                  <a class="link" href="../ref/boost__beast__websocket__stream/read_some/overload2.html" title="websocket::stream::read_some (2 of 4 overloads)"><code class="computeroutput"><span class="identifier">read_some</span></code></a>, <a class="link" href="../ref/boost__beast__websocket__stream/async_read_some/overload1.html" title="websocket::stream::async_read_some (1 of 2 overloads)"><code class="computeroutput"><span class="identifier">async_read_some</span></code></a>
176                </p>
177              </td>
178<td>
179                <p>
180                  Read part of a message into a <a class="link" href="../concepts/DynamicBuffer.html" title="DynamicBuffer"><span class="emphasis"><em>DynamicBuffer</em></span></a>.
181                </p>
182              </td>
183</tr>
184<tr>
185<td>
186                <p>
187                  <a class="link" href="../ref/boost__beast__websocket__stream/read_some/overload4.html" title="websocket::stream::read_some (4 of 4 overloads)"><code class="computeroutput"><span class="identifier">read_some</span></code></a>, <a class="link" href="../ref/boost__beast__websocket__stream/async_read_some/overload2.html" title="websocket::stream::async_read_some (2 of 2 overloads)"><code class="computeroutput"><span class="identifier">async_read_some</span></code></a>
188                </p>
189              </td>
190<td>
191                <p>
192                  Read part of a message into a <a href="../../../../../../doc/html/boost_asio/reference/MutableBufferSequence.html" target="_top"><span class="emphasis"><em>MutableBufferSequence</em></span></a>.
193                </p>
194              </td>
195</tr>
196</tbody>
197</table></div>
198</div>
199<br class="table-break"><p>
200        After the WebSocket handshake is accomplished, callers may send and receive
201        messages using the message oriented interface. This interface requires that
202        all of the buffers representing the message are known ahead of time:
203      </p>
204<pre class="programlisting"><span class="comment">// This DynamicBuffer will hold the received message</span>
205<span class="identifier">flat_buffer</span> <span class="identifier">buffer</span><span class="special">;</span>
206
207<span class="comment">// Read a complete message into the buffer's input area</span>
208<span class="identifier">ws</span><span class="special">.</span><span class="identifier">read</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">);</span>
209
210<span class="comment">// Set text mode if the received message was also text,</span>
211<span class="comment">// otherwise binary mode will be set.</span>
212<span class="identifier">ws</span><span class="special">.</span><span class="identifier">text</span><span class="special">(</span><span class="identifier">ws</span><span class="special">.</span><span class="identifier">got_text</span><span class="special">());</span>
213
214<span class="comment">// Echo the received message back to the peer. If the received</span>
215<span class="comment">// message was in text mode, the echoed message will also be</span>
216<span class="comment">// in text mode, otherwise it will be in binary mode.</span>
217<span class="identifier">ws</span><span class="special">.</span><span class="identifier">write</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
218
219<span class="comment">// Discard all of the bytes stored in the dynamic buffer,</span>
220<span class="comment">// otherwise the next call to read will append to the existing</span>
221<span class="comment">// data instead of building a fresh message.</span>
222<span class="identifier">buffer</span><span class="special">.</span><span class="identifier">consume</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
223</pre>
224<div class="important"><table border="0" summary="Important">
225<tr>
226<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
227<th align="left">Important</th>
228</tr>
229<tr><td align="left" valign="top"><p>
230          <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">stream</span></code></a> is not thread-safe. Calls
231          to stream member functions must all be made from the same implicit or explicit
232          strand.
233        </p></td></tr>
234</table></div>
235<h5>
236<a name="beast.using_websocket.messages.h2"></a>
237        <span class="phrase"><a name="beast.using_websocket.messages.frames"></a></span><a class="link" href="messages.html#beast.using_websocket.messages.frames">Frames</a>
238      </h5>
239<p>
240        Some use-cases make it impractical or impossible to buffer the entire message
241        ahead of time:
242      </p>
243<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
244<li class="listitem">
245            Streaming multimedia to an endpoint.
246          </li>
247<li class="listitem">
248            Sending a message that does not fit in memory at once.
249          </li>
250<li class="listitem">
251            Providing incremental results as they become available.
252          </li>
253</ul></div>
254<p>
255        For these cases, the partial data oriented interface may be used. This example
256        reads and echoes a complete message using this interface:
257      </p>
258<pre class="programlisting"><span class="comment">// This DynamicBuffer will hold the received message</span>
259<span class="identifier">multi_buffer</span> <span class="identifier">buffer</span><span class="special">;</span>
260
261<span class="comment">// Read the next message in pieces</span>
262<span class="keyword">do</span>
263<span class="special">{</span>
264    <span class="comment">// Append up to 512 bytes of the message into the buffer</span>
265    <span class="identifier">ws</span><span class="special">.</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="number">512</span><span class="special">);</span>
266<span class="special">}</span>
267<span class="keyword">while</span><span class="special">(!</span> <span class="identifier">ws</span><span class="special">.</span><span class="identifier">is_message_done</span><span class="special">());</span>
268
269<span class="comment">// At this point we have a complete message in the buffer, now echo it</span>
270
271<span class="comment">// The echoed message will be sent in binary mode if the received</span>
272<span class="comment">// message was in binary mode, otherwise we will send in text mode.</span>
273<span class="identifier">ws</span><span class="special">.</span><span class="identifier">binary</span><span class="special">(</span><span class="identifier">ws</span><span class="special">.</span><span class="identifier">got_binary</span><span class="special">());</span>
274
275<span class="comment">// This buffer adaptor allows us to iterate through buffer in pieces</span>
276<span class="identifier">buffers_suffix</span><span class="special">&lt;</span><span class="identifier">multi_buffer</span><span class="special">::</span><span class="identifier">const_buffers_type</span><span class="special">&gt;</span> <span class="identifier">cb</span><span class="special">{</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">()};</span>
277
278<span class="comment">// Echo the received message in pieces.</span>
279<span class="comment">// This will cause the message to be broken up into multiple frames.</span>
280<span class="keyword">for</span><span class="special">(;;)</span>
281<span class="special">{</span>
282    <span class="keyword">if</span><span class="special">(</span><span class="identifier">buffer_bytes</span><span class="special">(</span><span class="identifier">cb</span><span class="special">)</span> <span class="special">&gt;</span> <span class="number">512</span><span class="special">)</span>
283    <span class="special">{</span>
284        <span class="comment">// There are more than 512 bytes left to send, just</span>
285        <span class="comment">// send the next 512 bytes. The value `false` informs</span>
286        <span class="comment">// the stream that the message is not complete.</span>
287        <span class="identifier">ws</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="keyword">false</span><span class="special">,</span> <span class="identifier">buffers_prefix</span><span class="special">(</span><span class="number">512</span><span class="special">,</span> <span class="identifier">cb</span><span class="special">));</span>
288
289        <span class="comment">// This efficiently discards data from the adaptor by</span>
290        <span class="comment">// simply ignoring it, but does not actually affect the</span>
291        <span class="comment">// underlying dynamic buffer.</span>
292        <span class="identifier">cb</span><span class="special">.</span><span class="identifier">consume</span><span class="special">(</span><span class="number">512</span><span class="special">);</span>
293    <span class="special">}</span>
294    <span class="keyword">else</span>
295    <span class="special">{</span>
296        <span class="comment">// Only 512 bytes or less remain, so write the whole</span>
297        <span class="comment">// thing and inform the stream that this piece represents</span>
298        <span class="comment">// the end of the message by passing `true`.</span>
299        <span class="identifier">ws</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="keyword">true</span><span class="special">,</span> <span class="identifier">cb</span><span class="special">);</span>
300        <span class="keyword">break</span><span class="special">;</span>
301    <span class="special">}</span>
302<span class="special">}</span>
303
304<span class="comment">// Discard all of the bytes stored in the dynamic buffer,</span>
305<span class="comment">// otherwise the next call to read will append to the existing</span>
306<span class="comment">// data instead of building a fresh message.</span>
307<span class="identifier">buffer</span><span class="special">.</span><span class="identifier">consume</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
308</pre>
309</div>
310<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
311<td align="left"></td>
312<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie
313      Falco<p>
314        Distributed under the Boost Software License, Version 1.0. (See accompanying
315        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
316      </p>
317</div></td>
318</tr></table>
319<hr>
320<div class="spirit-nav">
321<a accesskey="p" href="decorator.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="control_frames.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
322</div>
323</body>
324</html>
325