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
247
248
249
250
251
252
253
254
pub use ;
use ;
/// Sets up the IO layer functionality.
///
/// See [`Session`].
;
/// Represents an [`Entity`] which is establishing a connection to a peer, so
/// that it may open a [`Session`] in the future.
///
/// This is effectively a marker component for a [`Session`] which isn't
/// connected yet.
;
/// Represents an [`Entity`] which can be used to transfer [packets] over a
/// connection to a peer session, potentially over a network.
///
/// # Overview
///
/// A session can send data over to the other side of its connection - to its
/// peer. The peer may be located on a different machine, on the same machine as
/// this session, or even within the same app. This data is sent in the form of
/// [packets].
///
/// The session API is agnostic to the networking model used: it can be used to
/// represent a client-server, peer-to-peer, or any other kind of network
/// topology. The only constraint is that one session talks to one and only one
/// peer for its lifetime, however you can have multiple sessions within the
/// same world. These different sessions may even be communicating over
/// different protocols, such as raw UDP datagrams alongside Steam networking
/// sockets, so that you can e.g. support crossplay between different platforms.
///
/// The [`Session`] component is managed by your chosen IO layer implementation,
/// and you should not modify it yourself.
///
/// # Lifecycle
///
/// After creating a session entity using your chosen IO layer, the entity may
/// not start with the [`Session`] component - the session is *connecting* but
/// is not *connected* yet. This connecting state is marked with the
/// [`Endpoint`] component. Once the IO layer adds [`Session`], the entity is
/// considered *connected*, and you can send and receive data.
///
/// Note that [`Session`] is not a *guarantee* that you can send and receive
/// data - it is always possible that operations on OS sockets fail, the network
/// may be suddenly unreachable, etc.
///
/// If the session fails to connect, or loses connection after successfully
/// connecting (this may be a graceful disconnect or a connection error),
/// [`Disconnected`] is [triggered][trigger] on the session entity, and the
/// session is despawned immediately afterwards. You may also [trigger] your own
/// disconnection with a string reason by triggering [`Disconnect`].
///
/// # Packet buffers
///
/// [`Session`] holds the buffers of incoming and outgoing [packets] in
/// [`Session::recv`] and [`Session::send`] respectively. These buffers are
/// [`Vec`]s with unbounded capacity, but are cleared automatically on every
/// update:
/// - [`packet::clear_recv_buffers`] before [`IoSet::Poll`]
/// - [`packet::clear_send_buffers`] before [`IoSet::Flush`]
///
/// If there are any unconsumed packets in a buffer when it is cleared, a
/// warning is emitted - all packets should be consumed on every update.
///
/// # MTU
///
/// [`Session`]s are also responsible for tracking the current MTU value (see
/// [`packet`]). If the IO layer has a new value for known path MTU, it should
/// use [`Session::set_mtu`] to update it.
///
/// [trigger]: Trigger
/// [packets]: packet
/// [`Disconnected`]: connection::Disconnected
/// [`Disconnect`]: connection::Disconnect
// TODO: required component Endpoint
/// Set for scheduling IO layer systems.