1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
---
version: tip
layout: manpage_v2
title: nng_ctx(5)
---
<h1>nng_ctx(5)</h1>
<div class="sect1">
<h2 id="_name">NAME</h2>
<div class="sectionbody">
<div class="paragraph">
<p>nng_ctx - protocol context</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_synopsis">SYNOPSIS</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c"><span></span><span class="tok-cp">#include</span><span class="tok-w"> </span><span class="tok-cpf"><nng/nng.h></span>
<span class="tok-k">typedef</span><span class="tok-w"> </span><span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">nng_ctx_s</span><span class="tok-w"> </span><span class="tok-n">nng_ctx</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_description">DESCRIPTION</h2>
<div class="sectionbody">
<div class="paragraph">
<p>An <code>nng_ctx</code> is a handle to an underlying context object,
which keeps the protocol state for some stateful protocols.
The purpose of a separate context object is to permit applications to
share a single socket, with its various underlying
<a href="nng_dialer.5.html">dialers</a>,
<a href="nng_listener.5.html">listeners</a>,
and <a href="nng_pipe.5.html">pipes</a>,
while still benefiting from separate state tracking.</p>
</div>
<div class="paragraph">
<p>For example, a <a href="nng_req.7.html"><em>req</em></a> context will contain the request ID
of any sent request, a timer to retry the request on failure, and so forth.
A separate context on the same socket can have similar data, but corresponding
to a completely different request.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
The <code>nng_ctx</code> structure is always passed by value (both
for input parameters and return values), and should be treated opaquely.
Passing structures this way gives the compiler a chance to perform
accurate type checks in functions passing values of this type.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>All contexts share the same socket, and so some options, as well as the
underlying transport details, will be common to all contexts on that socket.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Not every protocol supports separate contexts.
See the protocol-specific documentation for further details about whether
contexts are supported, and details about what options are supported for
contexts.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Protocols that make use of contexts will also have a default context
that is used when the socket global operations are used.
Operations using the global context will generally not interfere with
any other contexts, except that certain socket options may affect socket
global behavior.</p>
</div>
<div class="paragraph">
<p>
Historically, applications wanting to use a stateful protocol concurrently
would have to resort to <a href="nng.7.html#raw_mode">raw mode</a> sockets, which bypasses
much of the various protocol handling, leaving it to up to the application
to do so.
Contexts make it possible to still benefit from advanced protocol handling,
including timeouts, retries, and matching requests to responses, while doing so
concurrently.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<a href="nng.7.html#raw_mode">Raw mode</a> sockets do not support contexts, since
there is generally no state tracked for them, and thus contexts make no sense.
</td>
</tr>
</table>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
Contexts are an excellent mechanism to use when building concurrent
applications, and should be used in lieu of
<a href="nng.7.html#raw_mode">raw mode</a> sockets when possible.
</td>
</tr>
</table>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Use of file descriptor polling (with descriptors
obtained using the
<a href="nng_options.5.html#NNG_OPT_RECVFD"><code>NNG_OPT_RECVFD</code></a> or
<a href="nng_options.5.html#NNG_OPT_SENDFD"><code>NNG_OPT_SENDFD</code></a> options) while contexts
are in use on the same socket is not supported, and may lead to unpredictable
behavior.
These asynchronous methods should not be mixed on the same socket.
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="NNG_CTX_INITIALIZER">Initialization</h3>
<div class="paragraph">
<p>A context may be initialized using the macro <code>NNG_CTX_INITIALIZER</code>
before it is opened, to prevent confusion with valid open contexts.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_example">EXAMPLE</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following program fragment demonstrates the use of contexts to implement
a concurrent <a href="nng_rep.7.html"><em>rep</em></a> service that simply echos messages back
to the sender.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c"><span></span>
<span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">echo_context</span><span class="tok-w"> </span><span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-n">nng_ctx</span><span class="tok-w"> </span><span class="tok-n">ctx</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-n">nng_aio</span><span class="tok-w"> </span><span class="tok-o">*</span><span class="tok-n">aio</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-k">enum</span><span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"> </span><span class="tok-n">INIT</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">RECV</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">SEND</span><span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"> </span><span class="tok-n">state</span><span class="tok-p">;</span>
<span class="tok-p">};</span>
<span class="tok-kt">void</span>
<span class="tok-nf">echo</span><span class="tok-p">(</span><span class="tok-kt">void</span><span class="tok-w"> </span><span class="tok-o">*</span><span class="tok-n">arg</span><span class="tok-p">)</span>
<span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">echo_context</span><span class="tok-w"> </span><span class="tok-o">*</span><span class="tok-n">ec</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">arg</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-k">switch</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">state</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-k">case</span><span class="tok-w"> </span><span class="tok-no">INIT</span><span class="tok-p">:</span>
<span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">state</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">RECV</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-n">nng_ctx_recv</span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">ctx</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">aio</span><span class="tok-p">);</span>
<span class="tok-w"> </span><span class="tok-k">return</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-k">case</span><span class="tok-w"> </span><span class="tok-no">RECV</span><span class="tok-p">:</span>
<span class="tok-w"> </span><span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">nng_aio_result</span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">aio</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-mi">0</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-c1">// ... handle error</span>
<span class="tok-w"> </span><span class="tok-p">}</span>
<span class="tok-w"> </span><span class="tok-c1">// We reuse the message on the ec->aio</span>
<span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">state</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">SEND</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-n">nng_ctx_send</span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">ctx</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">aio</span><span class="tok-p">);</span>
<span class="tok-w"> </span><span class="tok-k">return</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-k">case</span><span class="tok-w"> </span><span class="tok-no">SEND</span><span class="tok-p">:</span>
<span class="tok-w"> </span><span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">nng_aio_result</span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">aio</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-mi">0</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-c1">// ... handle error</span>
<span class="tok-w"> </span><span class="tok-p">}</span>
<span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">state</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">RECV</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-n">nng_ctx_recv</span><span class="tok-p">(</span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">ctx</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">ec</span><span class="tok-o">-></span><span class="tok-n">aio</span><span class="tok-p">);</span>
<span class="tok-w"> </span><span class="tok-k">return</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-p">}</span>
<span class="tok-p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the above fragment, the following example shows setting up the
service. It assumes that the <a href="nng_socket.5.html">socket</a> has already been
created and any transports set up as well with functions such as
<a href="nng_dial.3.html"><code>nng_dial()</code></a>
or <a href="nng_listen.3.html"><code>nng_listen()</code></a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="c"><span></span><span class="tok-cp">#define CONCURRENCY 1024</span>
<span class="tok-k">static</span><span class="tok-w"> </span><span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">echo_context</span><span class="tok-w"> </span><span class="tok-n">ecs</span><span class="tok-p">[</span><span class="tok-n">CONCURRENCY</span><span class="tok-p">];</span>
<span class="tok-kt">void</span>
<span class="tok-nf">start_echo_service</span><span class="tok-p">(</span><span class="tok-n">nng_socket</span><span class="tok-w"> </span><span class="tok-n">rep_socket</span><span class="tok-p">)</span>
<span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-kt">int</span><span class="tok-w"> </span><span class="tok-n">i</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-mi">0</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">i</span><span class="tok-w"> </span><span class="tok-o"><</span><span class="tok-w"> </span><span class="tok-n">CONCURRENCY</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">i</span><span class="tok-o">++</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span>
<span class="tok-w"> </span><span class="tok-c1">// error checks elided for clarity</span>
<span class="tok-w"> </span><span class="tok-n">nng_ctx_open</span><span class="tok-p">(</span><span class="tok-o">&</span><span class="tok-n">ecs</span><span class="tok-p">[</span><span class="tok-n">i</span><span class="tok-p">].</span><span class="tok-n">ctx</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">rep_socket</span><span class="tok-p">);</span>
<span class="tok-w"> </span><span class="tok-n">nng_aio_alloc</span><span class="tok-p">(</span><span class="tok-o">&</span><span class="tok-n">ecs</span><span class="tok-p">[</span><span class="tok-n">i</span><span class="tok-p">].</span><span class="tok-n">aio</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">echo</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">ecs</span><span class="tok-o">+</span><span class="tok-n">i</span><span class="tok-p">);</span>
<span class="tok-w"> </span><span class="tok-n">ecs</span><span class="tok-p">[</span><span class="tok-n">i</span><span class="tok-p">].</span><span class="tok-n">state</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">INIT</span><span class="tok-p">;</span>
<span class="tok-w"> </span><span class="tok-n">echo</span><span class="tok-p">(</span><span class="tok-n">ecs</span><span class="tok-o">+</span><span class="tok-n">i</span><span class="tok-p">);</span><span class="tok-w"> </span><span class="tok-c1">// start it running</span>
<span class="tok-w"> </span><span class="tok-p">}</span>
<span class="tok-p">}</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_see_also">SEE ALSO</h2>
<div class="sectionbody">
<div class="paragraph text-left">
<p><a href="libnng.3.html">libnng(3)</a>,
<a href="nng_ctx_close.3.html">nng_ctx_close(3)</a>,
<a href="nng_ctx_open.3.html">nng_ctx_open(3)</a>,
<a href="nng_ctx_get.3.html">nng_ctx_get(3)</a>,
<a href="nng_ctx_id.3.html">nng_ctx_id(3)</a>,
<a href="nng_ctx_recv.3.html">nng_ctx_recv(3)</a>,
<a href="nng_ctx_recvmsg.3.html">nng_ctx_recvmsg(3)</a>,
<a href="nng_ctx_send.3.html">nng_ctx_send(3)</a>,
<a href="nng_ctx_sendmsg.3.html">nng_ctx_sendmsg(3)</a>,
<a href="nng_ctx_set.3.html">nng_ctx_set(3)</a>,
<a href="nng_dialer.5.html">nng_dialer(5)</a>,
<a href="nng_listener.5.html">nng_listener(5)</a>,
<a href="nng_socket.5.html">nng_socket(5)</a>,
<a href="nng_options.5.html">nng_options(5)</a>,
<a href="nng.7.html">nng(7)</a></p>
</div>
</div>
</div>
|