Offset 1, 9 lines modified | Offset 1, 9 lines modified | ||
1 | -rw-r--r--···0·root·········(0)·root·········(0)····10751·2023-12-16·15:01:40.000000·.BUILDINFO | 1 | -rw-r--r--···0·root·········(0)·root·········(0)····10751·2023-12-16·15:01:40.000000·.BUILDINFO |
2 | -rw-r--r--···0·root·········(0)·root·········(0)····19 | 2 | -rw-r--r--···0·root·········(0)·root·········(0)····19502·2023-12-16·15:01:40.000000·.MTREE |
3 | -rw-r--r--···0·root·········(0)·root·········(0)······690·2023-12-16·15:01:40.000000·.PKGINFO | 3 | -rw-r--r--···0·root·········(0)·root·········(0)······690·2023-12-16·15:01:40.000000·.PKGINFO |
4 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/ | 4 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/ |
5 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/ | 5 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/ |
6 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/ | 6 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/ |
7 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/ | 7 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/ |
8 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/ | 8 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/ |
9 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets-12.0-py3.11.egg-info/ | 9 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets-12.0-py3.11.egg-info/ |
Offset 137, 15 lines modified | Offset 137, 15 lines modified | ||
137 | -rw-r--r--···0·root·········(0)·root·········(0)·····1150·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/utils.py | 137 | -rw-r--r--···0·root·········(0)·root·········(0)·····1150·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/utils.py |
138 | -rw-r--r--···0·root·········(0)·root·········(0)·····2747·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/version.py | 138 | -rw-r--r--···0·root·········(0)·root·········(0)·····2747·2023-12-16·15:01:40.000000·usr/lib/python3.11/site-packages/websockets/version.py |
139 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/ | 139 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/ |
140 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/ | 140 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/ |
141 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/ | 141 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/ |
142 | -rw-r--r--···0·root·········(0)·root·········(0)······230·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.buildinfo | 142 | -rw-r--r--···0·root·········(0)·root·········(0)······230·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.buildinfo |
143 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/ | 143 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/ |
144 | -rw-r--r--···0·root·········(0)·root·········(0)·· | 144 | -rw-r--r--···0·root·········(0)·root·········(0)··4372408·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/environment.pickle |
145 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/ | 145 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/ |
146 | -rw-r--r--···0·root·········(0)·root·········(0)····15823·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/asyncio.doctree | 146 | -rw-r--r--···0·root·········(0)·root·········(0)····15823·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/asyncio.doctree |
147 | -rw-r--r--···0·root·········(0)·root·········(0)····19528·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/client.doctree | 147 | -rw-r--r--···0·root·········(0)·root·········(0)····19528·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/client.doctree |
148 | -rw-r--r--···0·root·········(0)·root·········(0)····23148·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/common.doctree | 148 | -rw-r--r--···0·root·········(0)·root·········(0)····23148·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/common.doctree |
149 | -rw-r--r--···0·root·········(0)·root·········(0)·····4613·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/index.doctree | 149 | -rw-r--r--···0·root·········(0)·root·········(0)·····4613·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/index.doctree |
150 | -rw-r--r--···0·root·········(0)·root·········(0)····11013·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/misc.doctree | 150 | -rw-r--r--···0·root·········(0)·root·········(0)····11013·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/misc.doctree |
151 | -rw-r--r--···0·root·········(0)·root·········(0)····51328·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/server.doctree | 151 | -rw-r--r--···0·root·········(0)·root·········(0)····51328·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/.doctrees/faq/server.doctree |
Offset 255, 135 lines modified | Offset 255, 135 lines modified | ||
255 | -rw-r--r--···0·root·········(0)·root·········(0)····72791·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/styles/furo.css.map | 255 | -rw-r--r--···0·root·········(0)·root·········(0)····72791·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/styles/furo.css.map |
256 | -rw-r--r--···0·root·········(0)·root·········(0)·····2589·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tabs.css | 256 | -rw-r--r--···0·root·········(0)·root·········(0)·····2589·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tabs.css |
257 | -rw-r--r--···0·root·········(0)·root·········(0)······782·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tabs.js | 257 | -rw-r--r--···0·root·········(0)·root·········(0)······782·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tabs.js |
258 | -rw-r--r--···0·root·········(0)·root·········(0)·····4069·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tidelift.png | 258 | -rw-r--r--···0·root·········(0)·root·········(0)·····4069·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/tidelift.png |
259 | -rw-r--r--···0·root·········(0)·root·········(0)····14786·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/websockets.svg | 259 | -rw-r--r--···0·root·········(0)·root·········(0)····14786·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/_static/websockets.svg |
260 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/ | 260 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/ |
261 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/asyncio/ | 261 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/asyncio/ |
262 | -rw-r--r--···0·root·········(0)·root·········(0)····2 | 262 | -rw-r--r--···0·root·········(0)·root·········(0)····26425·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/asyncio/index.html |
263 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/client/ | 263 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/client/ |
264 | -rw-r--r--···0·root·········(0)·root·········(0)····3 | 264 | -rw-r--r--···0·root·········(0)·root·········(0)····33331·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/client/index.html |
265 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/common/ | 265 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/common/ |
266 | -rw-r--r--···0·root·········(0)·root·········(0)····34 | 266 | -rw-r--r--···0·root·········(0)·root·········(0)····34032·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/common/index.html |
267 | -rw-r--r--···0·root·········(0)·root·········(0)····29 | 267 | -rw-r--r--···0·root·········(0)·root·········(0)····29047·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/index.html |
268 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/misc/ | 268 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/misc/ |
269 | -rw-r--r--···0·root·········(0)·root·········(0)····25 | 269 | -rw-r--r--···0·root·········(0)·root·········(0)····25066·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/misc/index.html |
270 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/server/ | 270 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/server/ |
271 | -rw-r--r--···0·root·········(0)·root·········(0)····5 | 271 | -rw-r--r--···0·root·········(0)·root·········(0)····58609·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/faq/server/index.html |
272 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/genindex/ | 272 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/genindex/ |
273 | -rw-r--r--···0·root·········(0)·root·········(0)····80222·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/genindex/index.html | 273 | -rw-r--r--···0·root·········(0)·root·········(0)····80222·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/genindex/index.html |
274 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/ | 274 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/ |
275 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/autoreload/ | 275 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/autoreload/ |
276 | -rw-r--r--···0·root·········(0)·root·········(0)····21290·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/autoreload/index.html | 276 | -rw-r--r--···0·root·········(0)·root·········(0)····21290·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/autoreload/index.html |
277 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/cheatsheet/ | 277 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/cheatsheet/ |
278 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 278 | -rw-r--r--···0·root·········(0)·root·········(0)····29628·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/cheatsheet/index.html |
279 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/django/ | 279 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/django/ |
280 | -rw-r--r--···0·root·········(0)·root·········(0)····5 | 280 | -rw-r--r--···0·root·········(0)·root·········(0)····54782·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/django/index.html |
281 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/extensions/ | 281 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/extensions/ |
282 | -rw-r--r--···0·root·········(0)·root·········(0)····21319·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/extensions/index.html | 282 | -rw-r--r--···0·root·········(0)·root·········(0)····21319·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/extensions/index.html |
283 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/fly/ | 283 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/fly/ |
284 | -rw-r--r--···0·root·········(0)·root·········(0)····34048·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/fly/index.html | 284 | -rw-r--r--···0·root·········(0)·root·········(0)····34048·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/fly/index.html |
285 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/haproxy/ | 285 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/haproxy/ |
286 | -rw-r--r--···0·root·········(0)·root·········(0)····28726·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/haproxy/index.html | 286 | -rw-r--r--···0·root·········(0)·root·········(0)····28726·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/haproxy/index.html |
287 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/heroku/ | 287 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/heroku/ |
288 | -rw-r--r--···0·root·········(0)·root·········(0)····32895·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/heroku/index.html | 288 | -rw-r--r--···0·root·········(0)·root·········(0)····32895·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/heroku/index.html |
289 | -rw-r--r--···0·root·········(0)·root·········(0)····22625·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/index.html | 289 | -rw-r--r--···0·root·········(0)·root·········(0)····22625·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/index.html |
290 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/kubernetes/ | 290 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/kubernetes/ |
291 | -rw-r--r--···0·root·········(0)·root·········(0)····45750·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/kubernetes/index.html | 291 | -rw-r--r--···0·root·········(0)·root·········(0)····45750·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/kubernetes/index.html |
292 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/nginx/ | 292 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/nginx/ |
293 | -rw-r--r--···0·root·········(0)·root·········(0)····29253·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/nginx/index.html | 293 | -rw-r--r--···0·root·········(0)·root·········(0)····29253·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/nginx/index.html |
294 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/patterns/ | 294 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/patterns/ |
295 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 295 | -rw-r--r--···0·root·········(0)·root·········(0)····29965·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/patterns/index.html |
296 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/quickstart/ | 296 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/quickstart/ |
297 | -rw-r--r--···0·root·········(0)·root·········(0)····80 | 297 | -rw-r--r--···0·root·········(0)·root·········(0)····80235·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/quickstart/index.html |
298 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/render/ | 298 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/render/ |
299 | -rw-r--r--···0·root·········(0)·root·········(0)····32444·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/render/index.html | 299 | -rw-r--r--···0·root·········(0)·root·········(0)····32444·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/render/index.html |
300 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/sansio/ | 300 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/sansio/ |
301 | -rw-r--r--···0·root·········(0)·root·········(0)····51 | 301 | -rw-r--r--···0·root·········(0)·root·········(0)····51256·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/sansio/index.html |
302 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/supervisor/ | 302 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/supervisor/ |
303 | -rw-r--r--···0·root·········(0)·root·········(0)····30 | 303 | -rw-r--r--···0·root·········(0)·root·········(0)····30594·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/howto/supervisor/index.html |
304 | -rw-r--r--···0·root·········(0)·root·········(0)····25 | 304 | -rw-r--r--···0·root·········(0)·root·········(0)····25104·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/index.html |
305 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/ | 305 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/ |
306 | -rw-r--r--···0·root·········(0)·root·········(0)····26379·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/index.html | 306 | -rw-r--r--···0·root·········(0)·root·········(0)····26379·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/index.html |
307 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial1/ | 307 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial1/ |
308 | -rw-r--r--···0·root·········(0)·root·········(0)···106 | 308 | -rw-r--r--···0·root·········(0)·root·········(0)···106301·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial1/index.html |
309 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial2/ | 309 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial2/ |
310 | -rw-r--r--···0·root·········(0)·root·········(0)···118 | 310 | -rw-r--r--···0·root·········(0)·root·········(0)···118529·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial2/index.html |
311 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial3/ | 311 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial3/ |
312 | -rw-r--r--···0·root·········(0)·root·········(0)····94 | 312 | -rw-r--r--···0·root·········(0)·root·········(0)····94306·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/intro/tutorial3/index.html |
313 | -rw-r--r--···0·root·········(0)·root·········(0)·····4136·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/objects.inv | 313 | -rw-r--r--···0·root·········(0)·root·········(0)·····4136·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/objects.inv |
314 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/ | 314 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/ |
315 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/changelog/ | 315 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/changelog/ |
316 | -rw-r--r--···0·root·········(0)·root·········(0)···1 | 316 | -rw-r--r--···0·root·········(0)·root·········(0)···118659·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/changelog/index.html |
317 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/contributing/ | 317 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/contributing/ |
318 | -rw-r--r--···0·root·········(0)·root·········(0)····23 | 318 | -rw-r--r--···0·root·········(0)·root·········(0)····23430·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/contributing/index.html |
319 | -rw-r--r--···0·root·········(0)·root·········(0)····19641·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/index.html | 319 | -rw-r--r--···0·root·········(0)·root·········(0)····19641·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/index.html |
320 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/license/ | 320 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/license/ |
321 | -rw-r--r--···0·root·········(0)·root·········(0)····21112·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/license/index.html | 321 | -rw-r--r--···0·root·········(0)·root·········(0)····21112·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/license/index.html |
322 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/tidelift/ | 322 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/tidelift/ |
323 | -rw-r--r--···0·root·········(0)·root·········(0)····24651·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/tidelift/index.html | 323 | -rw-r--r--···0·root·········(0)·root·········(0)····24651·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/project/tidelift/index.html |
324 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/py-modindex/ | 324 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/py-modindex/ |
325 | -rw-r--r--···0·root·········(0)·root·········(0)····21987·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/py-modindex/index.html | 325 | -rw-r--r--···0·root·········(0)·root·········(0)····21987·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/py-modindex/index.html |
326 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/ | 326 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/ |
327 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/ | 327 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/ |
328 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/client/ | 328 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/client/ |
329 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 329 | -rw-r--r--···0·root·········(0)·root·········(0)····86570·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/client/index.html |
330 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/common/ | 330 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/common/ |
331 | -rw-r--r--···0·root·········(0)·root·········(0)····7 | 331 | -rw-r--r--···0·root·········(0)·root·········(0)····71523·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/common/index.html |
332 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/server/ | 332 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/server/ |
333 | -rw-r--r--···0·root·········(0)·root·········(0)···1 | 333 | -rw-r--r--···0·root·········(0)·root·········(0)···130815·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/asyncio/server/index.html |
334 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/datastructures/ | 334 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/datastructures/ |
335 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 335 | -rw-r--r--···0·root·········(0)·root·········(0)····67934·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/datastructures/index.html |
336 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/exceptions/ | 336 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/exceptions/ |
337 | -rw-r--r--···0·root·········(0)·root·········(0)····56 | 337 | -rw-r--r--···0·root·········(0)·root·········(0)····56408·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/exceptions/index.html |
338 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/extensions/ | 338 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/extensions/ |
339 | -rw-r--r--···0·root·········(0)·root·········(0)····4 | 339 | -rw-r--r--···0·root·········(0)·root·········(0)····43340·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/extensions/index.html |
340 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/features/ | 340 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/features/ |
341 | -rw-r--r--···0·root·········(0)·root·········(0)····3 | 341 | -rw-r--r--···0·root·········(0)·root·········(0)····31576·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/features/index.html |
342 | -rw-r--r--···0·root·········(0)·root·········(0)····24 | 342 | -rw-r--r--···0·root·········(0)·root·········(0)····24460·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/index.html |
343 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/ | 343 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/ |
344 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/client/ | 344 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/client/ |
345 | -rw-r--r--···0·root·········(0)·root·········(0)····5 | 345 | -rw-r--r--···0·root·········(0)·root·········(0)····54223·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/client/index.html |
346 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/common/ | 346 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/common/ |
347 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 347 | -rw-r--r--···0·root·········(0)·root·········(0)····56154·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/common/index.html |
348 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/server/ | 348 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/server/ |
349 | -rw-r--r--···0·root·········(0)·root·········(0)····6 | 349 | -rw-r--r--···0·root·········(0)·root·········(0)····61327·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sansio/server/index.html |
350 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/ | 350 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/ |
351 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/client/ | 351 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/client/ |
352 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 352 | -rw-r--r--···0·root·········(0)·root·········(0)····68455·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/client/index.html |
353 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/common/ | 353 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/common/ |
354 | -rw-r--r--···0·root·········(0)·root·········(0)···· | 354 | -rw-r--r--···0·root·········(0)·root·········(0)····48847·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/common/index.html |
355 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/server/ | 355 | drwxr-xr-x···0·root·········(0)·root·········(0)········0·2023-12-16·15:01:40.000000·usr/share/doc/python-websockets/reference/sync/server/ |
Max diff block lines reached; 5763/28104 bytes (20.51%) of diff not shown. |
Offset 1, 11 lines modified | Offset 1, 11 lines modified | ||
1 | #mtree | 1 | #mtree |
2 | /set·type=file·uid=0·gid=0·mode=644 | 2 | /set·type=file·uid=0·gid=0·mode=644 |
3 | ./.BUILDINFO·time=1702738900.0·size=10751·md5digest=39dcc26b59809707ecff9f6aa0425274·sha256digest=396ec26164b5d11ef6ec62d1431149e6b38ecaa57f8bbcd6122c2a835e80a1d8 | 3 | ./.BUILDINFO·time=1702738900.0·size=10751·md5digest=39dcc26b59809707ecff9f6aa0425274·sha256digest=396ec26164b5d11ef6ec62d1431149e6b38ecaa57f8bbcd6122c2a835e80a1d8 |
4 | ./.PKGINFO·time=1702738900.0·size=690·md5digest= | 4 | ./.PKGINFO·time=1702738900.0·size=690·md5digest=7072d2ce3d8b06d466b5dde0df4378bf·sha256digest=ca4bdcb799165e329850c6d44134f9c022319727f3d6643dccfbbf41595b8fd4 |
5 | /set·mode=755 | 5 | /set·mode=755 |
6 | ./usr·time=1702738900.0·type=dir | 6 | ./usr·time=1702738900.0·type=dir |
7 | ./usr/lib·time=1702738900.0·type=dir | 7 | ./usr/lib·time=1702738900.0·type=dir |
8 | ./usr/lib/python3.11·time=1702738900.0·type=dir | 8 | ./usr/lib/python3.11·time=1702738900.0·type=dir |
9 | ./usr/lib/python3.11/site-packages·time=1702738900.0·type=dir | 9 | ./usr/lib/python3.11/site-packages·time=1702738900.0·type=dir |
10 | /set·mode=644 | 10 | /set·mode=644 |
11 | ./usr/lib/python3.11/site-packages/websockets·time=1702738900.0·mode=755·type=dir | 11 | ./usr/lib/python3.11/site-packages/websockets·time=1702738900.0·mode=755·type=dir |
Offset 141, 19 lines modified | Offset 141, 19 lines modified | ||
141 | ./usr/lib/python3.11/site-packages/websockets-12.0-py3.11.egg-info/top_level.txt·time=1702738900.0·size=11·md5digest=f36b810914d17b7d95a034db8477fece·sha256digest=08ca5d2a49712acbd980283296dc5458e1e26d95d9d6e60856971af71b10f079 | 141 | ./usr/lib/python3.11/site-packages/websockets-12.0-py3.11.egg-info/top_level.txt·time=1702738900.0·size=11·md5digest=f36b810914d17b7d95a034db8477fece·sha256digest=08ca5d2a49712acbd980283296dc5458e1e26d95d9d6e60856971af71b10f079 |
142 | /set·mode=755 | 142 | /set·mode=755 |
143 | ./usr/share·time=1702738900.0·type=dir | 143 | ./usr/share·time=1702738900.0·type=dir |
144 | ./usr/share/doc·time=1702738900.0·type=dir | 144 | ./usr/share/doc·time=1702738900.0·type=dir |
145 | ./usr/share/doc/python-websockets·time=1702738900.0·type=dir | 145 | ./usr/share/doc/python-websockets·time=1702738900.0·type=dir |
146 | ./usr/share/doc/python-websockets/.buildinfo·time=1702738900.0·mode=644·size=230·md5digest=ea0d0dec6edc2d71e9b5804544c4832f·sha256digest=a66140bbdd31d59e67bb4ae096afcedd212feaaa125d531074fbbc784ee22dfb | 146 | ./usr/share/doc/python-websockets/.buildinfo·time=1702738900.0·mode=644·size=230·md5digest=ea0d0dec6edc2d71e9b5804544c4832f·sha256digest=a66140bbdd31d59e67bb4ae096afcedd212feaaa125d531074fbbc784ee22dfb |
147 | ./usr/share/doc/python-websockets/README.rst·time=1702738900.0·mode=644·size=6340·md5digest=af2c087b794495dcc376f0ab1b88988d·sha256digest=a40cd5e8e1c11ed2189c7d806d0f5ec602579a9bbd7885a23a376decbaf73ff0 | 147 | ./usr/share/doc/python-websockets/README.rst·time=1702738900.0·mode=644·size=6340·md5digest=af2c087b794495dcc376f0ab1b88988d·sha256digest=a40cd5e8e1c11ed2189c7d806d0f5ec602579a9bbd7885a23a376decbaf73ff0 |
148 | ./usr/share/doc/python-websockets/index.html·time=1702738900.0·mode=644·size=25 | 148 | ./usr/share/doc/python-websockets/index.html·time=1702738900.0·mode=644·size=25104·md5digest=a966ae5f9ef6be48903a5ef57f18800e·sha256digest=48a1d3bac2bc4a4043535f6095bbe5809cfe2869d00545ae2993127737e11483 |
149 | ./usr/share/doc/python-websockets/objects.inv·time=1702738900.0·mode=644·size=4136·md5digest=d3f9b0ce1fa53632084fa296c24c81d8·sha256digest=f810afae4366e1d5ab5054aae9bcef4434491df3c65dbced3689f54dc718ce7c | 149 | ./usr/share/doc/python-websockets/objects.inv·time=1702738900.0·mode=644·size=4136·md5digest=d3f9b0ce1fa53632084fa296c24c81d8·sha256digest=f810afae4366e1d5ab5054aae9bcef4434491df3c65dbced3689f54dc718ce7c |
150 | ./usr/share/doc/python-websockets/searchindex.js·time=1702738900.0·mode=644·size=162736·md5digest=ffafa2ba5c7cfe385026d92ad120755e·sha256digest=d9fb619e64f21d40a40fcafaf897faaf644a6943d71ab1be1d1200ce2e3e5ca9 | 150 | ./usr/share/doc/python-websockets/searchindex.js·time=1702738900.0·mode=644·size=162736·md5digest=ffafa2ba5c7cfe385026d92ad120755e·sha256digest=d9fb619e64f21d40a40fcafaf897faaf644a6943d71ab1be1d1200ce2e3e5ca9 |
151 | ./usr/share/doc/python-websockets/.doctrees·time=1702738900.0·type=dir | 151 | ./usr/share/doc/python-websockets/.doctrees·time=1702738900.0·type=dir |
152 | ./usr/share/doc/python-websockets/.doctrees/environment.pickle·time=1702738900.0·mode=644·size= | 152 | ./usr/share/doc/python-websockets/.doctrees/environment.pickle·time=1702738900.0·mode=644·size=4372408·md5digest=c165ef2cf4843ee8aa603116f15800a0·sha256digest=b9e93be3d43276bdbfd62094d046aa2daadf000186ce12d7b2ea637f888d9a4d |
153 | ./usr/share/doc/python-websockets/.doctrees/index.doctree·time=1702738900.0·mode=644·size=17259·md5digest=ceb3bfac163144d8e91e304e4c559368·sha256digest=51230b2ecad6342654e8de6784c4c970a7cd39b1a6ef8a504cc6e230d2ed9bc4 | 153 | ./usr/share/doc/python-websockets/.doctrees/index.doctree·time=1702738900.0·mode=644·size=17259·md5digest=ceb3bfac163144d8e91e304e4c559368·sha256digest=51230b2ecad6342654e8de6784c4c970a7cd39b1a6ef8a504cc6e230d2ed9bc4 |
154 | /set·mode=644 | 154 | /set·mode=644 |
155 | ./usr/share/doc/python-websockets/.doctrees/faq·time=1702738900.0·mode=755·type=dir | 155 | ./usr/share/doc/python-websockets/.doctrees/faq·time=1702738900.0·mode=755·type=dir |
156 | ./usr/share/doc/python-websockets/.doctrees/faq/asyncio.doctree·time=1702738900.0·size=15823·md5digest=bf6e4e47db078775031d7d01b7d322c8·sha256digest=c0a193a7c4c02018a7c5f1b0d657e3e3a76d927355ee07662611a9568144ad6c | 156 | ./usr/share/doc/python-websockets/.doctrees/faq/asyncio.doctree·time=1702738900.0·size=15823·md5digest=bf6e4e47db078775031d7d01b7d322c8·sha256digest=c0a193a7c4c02018a7c5f1b0d657e3e3a76d927355ee07662611a9568144ad6c |
157 | ./usr/share/doc/python-websockets/.doctrees/faq/client.doctree·time=1702738900.0·size=19528·md5digest=c3ca616e8aaf2bf8fd4ae6e3c7aff899·sha256digest=dd10cb4192ab725145e664bff78e03ed9a75c49f5e1e43ecfd68b1ca2f38e7b1 | 157 | ./usr/share/doc/python-websockets/.doctrees/faq/client.doctree·time=1702738900.0·size=19528·md5digest=c3ca616e8aaf2bf8fd4ae6e3c7aff899·sha256digest=dd10cb4192ab725145e664bff78e03ed9a75c49f5e1e43ecfd68b1ca2f38e7b1 |
158 | ./usr/share/doc/python-websockets/.doctrees/faq/common.doctree·time=1702738900.0·size=23148·md5digest=832102fb2ea2da755d5375afc2630f12·sha256digest=c4e74f8abac4199ac05672dc52fa9267464c2c9578c5e72c0a01d018a9840b39 | 158 | ./usr/share/doc/python-websockets/.doctrees/faq/common.doctree·time=1702738900.0·size=23148·md5digest=832102fb2ea2da755d5375afc2630f12·sha256digest=c4e74f8abac4199ac05672dc52fa9267464c2c9578c5e72c0a01d018a9840b39 |
159 | ./usr/share/doc/python-websockets/.doctrees/faq/index.doctree·time=1702738900.0·size=4613·md5digest=146aa0edf636600a1a33a04fd2916309·sha256digest=0697eea210f6293b54c6069f7dffad38b29f5191a229fbc1a790dcb26bbbd9c2 | 159 | ./usr/share/doc/python-websockets/.doctrees/faq/index.doctree·time=1702738900.0·size=4613·md5digest=146aa0edf636600a1a33a04fd2916309·sha256digest=0697eea210f6293b54c6069f7dffad38b29f5191a229fbc1a790dcb26bbbd9c2 |
Offset 265, 133 lines modified | Offset 265, 133 lines modified | ||
265 | ./usr/share/doc/python-websockets/_static/styles·time=1702738900.0·mode=755·type=dir | 265 | ./usr/share/doc/python-websockets/_static/styles·time=1702738900.0·mode=755·type=dir |
266 | ./usr/share/doc/python-websockets/_static/styles/furo-extensions.css·time=1702738900.0·size=5529·md5digest=878a8e8b856203beceb619668204178f·sha256digest=41553344c82007533539f36817807f543042d69f01915d5be4da31291f35c262 | 266 | ./usr/share/doc/python-websockets/_static/styles/furo-extensions.css·time=1702738900.0·size=5529·md5digest=878a8e8b856203beceb619668204178f·sha256digest=41553344c82007533539f36817807f543042d69f01915d5be4da31291f35c262 |
267 | ./usr/share/doc/python-websockets/_static/styles/furo-extensions.css.map·time=1702738900.0·size=7809·md5digest=0c930ac5db2b2ba99712238698c5c879·sha256digest=6b6b1e32eaca3165c98b443bd0b5c9897aab53b0e6d4be3e2067807b231aa407 | 267 | ./usr/share/doc/python-websockets/_static/styles/furo-extensions.css.map·time=1702738900.0·size=7809·md5digest=0c930ac5db2b2ba99712238698c5c879·sha256digest=6b6b1e32eaca3165c98b443bd0b5c9897aab53b0e6d4be3e2067807b231aa407 |
268 | ./usr/share/doc/python-websockets/_static/styles/furo.css·time=1702738900.0·size=48265·md5digest=86ddd020eaa644c83a734502bb55ed06·sha256digest=141fe0f93b28e36637c7be857b8b21de27f88e58e9094a0407640451f65687f7 | 268 | ./usr/share/doc/python-websockets/_static/styles/furo.css·time=1702738900.0·size=48265·md5digest=86ddd020eaa644c83a734502bb55ed06·sha256digest=141fe0f93b28e36637c7be857b8b21de27f88e58e9094a0407640451f65687f7 |
269 | ./usr/share/doc/python-websockets/_static/styles/furo.css.map·time=1702738900.0·size=72791·md5digest=b6f6ea7497d70b79aef4237ddf6126b7·sha256digest=bcbc1590273b22a7b3acc8f72bd77eed9c0de23f50d69aff5040bd6b0976c7cd | 269 | ./usr/share/doc/python-websockets/_static/styles/furo.css.map·time=1702738900.0·size=72791·md5digest=b6f6ea7497d70b79aef4237ddf6126b7·sha256digest=bcbc1590273b22a7b3acc8f72bd77eed9c0de23f50d69aff5040bd6b0976c7cd |
270 | /set·mode=755 | 270 | /set·mode=755 |
271 | ./usr/share/doc/python-websockets/faq·time=1702738900.0·type=dir | 271 | ./usr/share/doc/python-websockets/faq·time=1702738900.0·type=dir |
272 | ./usr/share/doc/python-websockets/faq/index.html·time=1702738900.0·mode=644·size=29 | 272 | ./usr/share/doc/python-websockets/faq/index.html·time=1702738900.0·mode=644·size=29047·md5digest=c3e39d8be787a1cf33592bd8d325e9a3·sha256digest=58c4bae46b9e6daed2653b0e6d12ef42949f88d06c1df52f868112a33d19ce6f |
273 | ./usr/share/doc/python-websockets/faq/asyncio·time=1702738900.0·type=dir | 273 | ./usr/share/doc/python-websockets/faq/asyncio·time=1702738900.0·type=dir |
274 | ./usr/share/doc/python-websockets/faq/asyncio/index.html·time=1702738900.0·mode=644·size=2 | 274 | ./usr/share/doc/python-websockets/faq/asyncio/index.html·time=1702738900.0·mode=644·size=26425·md5digest=b21ceede20dbbdd59333c07a891549a7·sha256digest=58cc18dd465859f583fa1138da288b3345b640f6ededa7f8a038f2cca003a45b |
275 | ./usr/share/doc/python-websockets/faq/client·time=1702738900.0·type=dir | 275 | ./usr/share/doc/python-websockets/faq/client·time=1702738900.0·type=dir |
276 | ./usr/share/doc/python-websockets/faq/client/index.html·time=1702738900.0·mode=644·size=3 | 276 | ./usr/share/doc/python-websockets/faq/client/index.html·time=1702738900.0·mode=644·size=33331·md5digest=65f931385c56688b11336d3a3cddc5a3·sha256digest=5c2aae08d72665997acad1c62ebf2324786222b93b124c0d47e093a6a58250a8 |
277 | ./usr/share/doc/python-websockets/faq/common·time=1702738900.0·type=dir | 277 | ./usr/share/doc/python-websockets/faq/common·time=1702738900.0·type=dir |
278 | ./usr/share/doc/python-websockets/faq/common/index.html·time=1702738900.0·mode=644·size=34 | 278 | ./usr/share/doc/python-websockets/faq/common/index.html·time=1702738900.0·mode=644·size=34032·md5digest=052831acc4af468dc5c0f321bb50bd13·sha256digest=b9c82e71f428a5ba728c8b5ae8989b7f505774e23d4f0f1367feef54b46ba78e |
279 | ./usr/share/doc/python-websockets/faq/misc·time=1702738900.0·type=dir | 279 | ./usr/share/doc/python-websockets/faq/misc·time=1702738900.0·type=dir |
280 | ./usr/share/doc/python-websockets/faq/misc/index.html·time=1702738900.0·mode=644·size=25 | 280 | ./usr/share/doc/python-websockets/faq/misc/index.html·time=1702738900.0·mode=644·size=25066·md5digest=f6e1f3360d5abd214d437b07aa86f9d7·sha256digest=80c5cec8ada988249d9fdad4aa1a30e73926db81cbc8a3f17c94c52053620da8 |
281 | ./usr/share/doc/python-websockets/faq/server·time=1702738900.0·type=dir | 281 | ./usr/share/doc/python-websockets/faq/server·time=1702738900.0·type=dir |
282 | ./usr/share/doc/python-websockets/faq/server/index.html·time=1702738900.0·mode=644·size=5 | 282 | ./usr/share/doc/python-websockets/faq/server/index.html·time=1702738900.0·mode=644·size=58609·md5digest=4201f74262eef58f0c681d2de6729b10·sha256digest=6a8290c6f7edf185318e92de80eb5df39401af9c055e01b51d8e2fad3fc9887d |
283 | ./usr/share/doc/python-websockets/genindex·time=1702738900.0·type=dir | 283 | ./usr/share/doc/python-websockets/genindex·time=1702738900.0·type=dir |
284 | ./usr/share/doc/python-websockets/genindex/index.html·time=1702738900.0·mode=644·size=80222·md5digest=1fcafaa51201bffc10601391345fe648·sha256digest=8ced854342da2d2c986775e7cfb55110212603c518822bc93e6dbe4470176c9b | 284 | ./usr/share/doc/python-websockets/genindex/index.html·time=1702738900.0·mode=644·size=80222·md5digest=1fcafaa51201bffc10601391345fe648·sha256digest=8ced854342da2d2c986775e7cfb55110212603c518822bc93e6dbe4470176c9b |
285 | ./usr/share/doc/python-websockets/howto·time=1702738900.0·type=dir | 285 | ./usr/share/doc/python-websockets/howto·time=1702738900.0·type=dir |
286 | ./usr/share/doc/python-websockets/howto/index.html·time=1702738900.0·mode=644·size=22625·md5digest=20f860e390f352db2099a6edf1f5cc7c·sha256digest=095ae6862bfef0768dcf561731c4508b1da8a0e71417905a094ea6498e79f083 | 286 | ./usr/share/doc/python-websockets/howto/index.html·time=1702738900.0·mode=644·size=22625·md5digest=20f860e390f352db2099a6edf1f5cc7c·sha256digest=095ae6862bfef0768dcf561731c4508b1da8a0e71417905a094ea6498e79f083 |
287 | ./usr/share/doc/python-websockets/howto/autoreload·time=1702738900.0·type=dir | 287 | ./usr/share/doc/python-websockets/howto/autoreload·time=1702738900.0·type=dir |
288 | ./usr/share/doc/python-websockets/howto/autoreload/index.html·time=1702738900.0·mode=644·size=21290·md5digest=8e4773f044c3d4eb8861887c3b66e3af·sha256digest=c0a7ebfb0e9ae81ab380e8fcbf9bf5048b2e0e291fba4510f3d1985fa7ecd2f5 | 288 | ./usr/share/doc/python-websockets/howto/autoreload/index.html·time=1702738900.0·mode=644·size=21290·md5digest=8e4773f044c3d4eb8861887c3b66e3af·sha256digest=c0a7ebfb0e9ae81ab380e8fcbf9bf5048b2e0e291fba4510f3d1985fa7ecd2f5 |
289 | ./usr/share/doc/python-websockets/howto/cheatsheet·time=1702738900.0·type=dir | 289 | ./usr/share/doc/python-websockets/howto/cheatsheet·time=1702738900.0·type=dir |
290 | ./usr/share/doc/python-websockets/howto/cheatsheet/index.html·time=1702738900.0·mode=644·size= | 290 | ./usr/share/doc/python-websockets/howto/cheatsheet/index.html·time=1702738900.0·mode=644·size=29628·md5digest=257b48ca248122d51d0a0cb0b4f46b6a·sha256digest=084d76b1fe30b4a44406b49d84c5beb1f86c627143ca64365a008c098d49be9b |
291 | ./usr/share/doc/python-websockets/howto/django·time=1702738900.0·type=dir | 291 | ./usr/share/doc/python-websockets/howto/django·time=1702738900.0·type=dir |
292 | ./usr/share/doc/python-websockets/howto/django/index.html·time=1702738900.0·mode=644·size=5 | 292 | ./usr/share/doc/python-websockets/howto/django/index.html·time=1702738900.0·mode=644·size=54782·md5digest=297d8e271933c3a6031e59b71ac0ca18·sha256digest=dbe262262c641528162e29704555ca7a7734a456b841c60b98337e24e4233650 |
293 | ./usr/share/doc/python-websockets/howto/extensions·time=1702738900.0·type=dir | 293 | ./usr/share/doc/python-websockets/howto/extensions·time=1702738900.0·type=dir |
294 | ./usr/share/doc/python-websockets/howto/extensions/index.html·time=1702738900.0·mode=644·size=21319·md5digest=5290cdba0110f8cfedb25bd735cfabd1·sha256digest=92896f29609bfacb084917b6f0ba6034bedfe3f2da797dc23237cbb8221b0447 | 294 | ./usr/share/doc/python-websockets/howto/extensions/index.html·time=1702738900.0·mode=644·size=21319·md5digest=5290cdba0110f8cfedb25bd735cfabd1·sha256digest=92896f29609bfacb084917b6f0ba6034bedfe3f2da797dc23237cbb8221b0447 |
295 | ./usr/share/doc/python-websockets/howto/fly·time=1702738900.0·type=dir | 295 | ./usr/share/doc/python-websockets/howto/fly·time=1702738900.0·type=dir |
296 | ./usr/share/doc/python-websockets/howto/fly/index.html·time=1702738900.0·mode=644·size=34048·md5digest=aa1a7e15d16410bf7df110d2a59c8f00·sha256digest=9f5796430cec2ec64bf3844e7e817559421a691ff85dc26af31e2ec401d47052 | 296 | ./usr/share/doc/python-websockets/howto/fly/index.html·time=1702738900.0·mode=644·size=34048·md5digest=aa1a7e15d16410bf7df110d2a59c8f00·sha256digest=9f5796430cec2ec64bf3844e7e817559421a691ff85dc26af31e2ec401d47052 |
297 | ./usr/share/doc/python-websockets/howto/haproxy·time=1702738900.0·type=dir | 297 | ./usr/share/doc/python-websockets/howto/haproxy·time=1702738900.0·type=dir |
298 | ./usr/share/doc/python-websockets/howto/haproxy/index.html·time=1702738900.0·mode=644·size=28726·md5digest=27892918e4242ddfb7baf699ebfed311·sha256digest=9cb03b612d98938642a1eccd9d5399c4301b9c96cfc8190dc8004d8db760f02f | 298 | ./usr/share/doc/python-websockets/howto/haproxy/index.html·time=1702738900.0·mode=644·size=28726·md5digest=27892918e4242ddfb7baf699ebfed311·sha256digest=9cb03b612d98938642a1eccd9d5399c4301b9c96cfc8190dc8004d8db760f02f |
299 | ./usr/share/doc/python-websockets/howto/heroku·time=1702738900.0·type=dir | 299 | ./usr/share/doc/python-websockets/howto/heroku·time=1702738900.0·type=dir |
300 | ./usr/share/doc/python-websockets/howto/heroku/index.html·time=1702738900.0·mode=644·size=32895·md5digest=59cdcdaca54a2efaf1da854997be4384·sha256digest=ad2af525f21e858f8513ae4d18959bf17f6c109ec457608be0c8f7740009f8d1 | 300 | ./usr/share/doc/python-websockets/howto/heroku/index.html·time=1702738900.0·mode=644·size=32895·md5digest=59cdcdaca54a2efaf1da854997be4384·sha256digest=ad2af525f21e858f8513ae4d18959bf17f6c109ec457608be0c8f7740009f8d1 |
301 | ./usr/share/doc/python-websockets/howto/kubernetes·time=1702738900.0·type=dir | 301 | ./usr/share/doc/python-websockets/howto/kubernetes·time=1702738900.0·type=dir |
302 | ./usr/share/doc/python-websockets/howto/kubernetes/index.html·time=1702738900.0·mode=644·size=45750·md5digest=4535138190b97b3184246ba57f2be5c1·sha256digest=90b5ba77bbc5b57d8edded23a0ee0ebd7ec133644b83f529417c24f751839a20 | 302 | ./usr/share/doc/python-websockets/howto/kubernetes/index.html·time=1702738900.0·mode=644·size=45750·md5digest=4535138190b97b3184246ba57f2be5c1·sha256digest=90b5ba77bbc5b57d8edded23a0ee0ebd7ec133644b83f529417c24f751839a20 |
303 | ./usr/share/doc/python-websockets/howto/nginx·time=1702738900.0·type=dir | 303 | ./usr/share/doc/python-websockets/howto/nginx·time=1702738900.0·type=dir |
304 | ./usr/share/doc/python-websockets/howto/nginx/index.html·time=1702738900.0·mode=644·size=29253·md5digest=67cf183b9cb0161923d27cf57db93e68·sha256digest=e2d67b7a83e8e5fb56d535312b5895906709f25d3e9a0eab70f8a5f1c05ef7c6 | 304 | ./usr/share/doc/python-websockets/howto/nginx/index.html·time=1702738900.0·mode=644·size=29253·md5digest=67cf183b9cb0161923d27cf57db93e68·sha256digest=e2d67b7a83e8e5fb56d535312b5895906709f25d3e9a0eab70f8a5f1c05ef7c6 |
305 | ./usr/share/doc/python-websockets/howto/patterns·time=1702738900.0·type=dir | 305 | ./usr/share/doc/python-websockets/howto/patterns·time=1702738900.0·type=dir |
306 | ./usr/share/doc/python-websockets/howto/patterns/index.html·time=1702738900.0·mode=644·size= | 306 | ./usr/share/doc/python-websockets/howto/patterns/index.html·time=1702738900.0·mode=644·size=29965·md5digest=c3d5a130d45bd60b63b4a58d360f8d13·sha256digest=0e1ce18b53f3325675cb66d00935ee5a4330d66356a7418e787211bb2a0c6501 |
307 | ./usr/share/doc/python-websockets/howto/quickstart·time=1702738900.0·type=dir | 307 | ./usr/share/doc/python-websockets/howto/quickstart·time=1702738900.0·type=dir |
308 | ./usr/share/doc/python-websockets/howto/quickstart/index.html·time=1702738900.0·mode=644·size=80 | 308 | ./usr/share/doc/python-websockets/howto/quickstart/index.html·time=1702738900.0·mode=644·size=80235·md5digest=2c01fe5a2ae4822c2a5bd3b5ecc27b65·sha256digest=dd8c8d680159efa514d682addf4fda22aebfb489c9bcb0411f5f4d2fe531d376 |
309 | ./usr/share/doc/python-websockets/howto/render·time=1702738900.0·type=dir | 309 | ./usr/share/doc/python-websockets/howto/render·time=1702738900.0·type=dir |
310 | ./usr/share/doc/python-websockets/howto/render/index.html·time=1702738900.0·mode=644·size=32444·md5digest=84a200fd3e0137b6fbd637427cbb1501·sha256digest=87b1461cdd96934176477538ee8ccbd16b8d735e9c3d0ad877330976e92555b4 | 310 | ./usr/share/doc/python-websockets/howto/render/index.html·time=1702738900.0·mode=644·size=32444·md5digest=84a200fd3e0137b6fbd637427cbb1501·sha256digest=87b1461cdd96934176477538ee8ccbd16b8d735e9c3d0ad877330976e92555b4 |
311 | ./usr/share/doc/python-websockets/howto/sansio·time=1702738900.0·type=dir | 311 | ./usr/share/doc/python-websockets/howto/sansio·time=1702738900.0·type=dir |
312 | ./usr/share/doc/python-websockets/howto/sansio/index.html·time=1702738900.0·mode=644·size=51 | 312 | ./usr/share/doc/python-websockets/howto/sansio/index.html·time=1702738900.0·mode=644·size=51256·md5digest=cddaf05a764415afe275bfaf5bc78ce8·sha256digest=fd1c4d7e363b5132b3f1d0700b09e9b09a9a6dcc76c051a7d3f3cf1daf12b910 |
313 | ./usr/share/doc/python-websockets/howto/supervisor·time=1702738900.0·type=dir | 313 | ./usr/share/doc/python-websockets/howto/supervisor·time=1702738900.0·type=dir |
314 | ./usr/share/doc/python-websockets/howto/supervisor/index.html·time=1702738900.0·mode=644·size=30 | 314 | ./usr/share/doc/python-websockets/howto/supervisor/index.html·time=1702738900.0·mode=644·size=30594·md5digest=bf9f5fba091381a870b3d5dda7043a9c·sha256digest=b04f68874bc791ba10e9685a3e0a141b40621f717befe38eb038a48777d62a6f |
315 | ./usr/share/doc/python-websockets/intro·time=1702738900.0·type=dir | 315 | ./usr/share/doc/python-websockets/intro·time=1702738900.0·type=dir |
316 | ./usr/share/doc/python-websockets/intro/index.html·time=1702738900.0·mode=644·size=26379·md5digest=fb4b841c0827c9c14497041fde90c54c·sha256digest=7d7571d6f1a845b70350c922a94e572a7a94e64848cce48faad85b31b4da78de | 316 | ./usr/share/doc/python-websockets/intro/index.html·time=1702738900.0·mode=644·size=26379·md5digest=fb4b841c0827c9c14497041fde90c54c·sha256digest=7d7571d6f1a845b70350c922a94e572a7a94e64848cce48faad85b31b4da78de |
317 | ./usr/share/doc/python-websockets/intro/tutorial1·time=1702738900.0·type=dir | 317 | ./usr/share/doc/python-websockets/intro/tutorial1·time=1702738900.0·type=dir |
318 | ./usr/share/doc/python-websockets/intro/tutorial1/index.html·time=1702738900.0·mode=644·size=106 | 318 | ./usr/share/doc/python-websockets/intro/tutorial1/index.html·time=1702738900.0·mode=644·size=106301·md5digest=3bb8430bdd21756aefd0717e0411d4e1·sha256digest=46f78e7c07e7f8a2892cf581438751d80d0b883197376858036138da0489f5a7 |
319 | ./usr/share/doc/python-websockets/intro/tutorial2·time=1702738900.0·type=dir | 319 | ./usr/share/doc/python-websockets/intro/tutorial2·time=1702738900.0·type=dir |
320 | ./usr/share/doc/python-websockets/intro/tutorial2/index.html·time=1702738900.0·mode=644·size=118 | 320 | ./usr/share/doc/python-websockets/intro/tutorial2/index.html·time=1702738900.0·mode=644·size=118529·md5digest=7f602549fec060a28915f770bc2901ff·sha256digest=aace431c9906204902a92899040ab6beb8f340b3b93673fa173a81e12b63db1b |
321 | ./usr/share/doc/python-websockets/intro/tutorial3·time=1702738900.0·type=dir | 321 | ./usr/share/doc/python-websockets/intro/tutorial3·time=1702738900.0·type=dir |
322 | ./usr/share/doc/python-websockets/intro/tutorial3/index.html·time=1702738900.0·mode=644·size=94 | 322 | ./usr/share/doc/python-websockets/intro/tutorial3/index.html·time=1702738900.0·mode=644·size=94306·md5digest=90a2db5ec6e2963a1e293fc8971d2a9c·sha256digest=679991edf671e8ffbf08487d8e66808112a815ccd5e81e3da23e5869a029e985 |
323 | ./usr/share/doc/python-websockets/project·time=1702738900.0·type=dir | 323 | ./usr/share/doc/python-websockets/project·time=1702738900.0·type=dir |
324 | ./usr/share/doc/python-websockets/project/index.html·time=1702738900.0·mode=644·size=19641·md5digest=f0a9d208ed53175540d6f0309742f8bd·sha256digest=34db0bb7c3b90caffa82b7ab35abcb279445a7a8029fe4338ccc9a66ebfd88fe | 324 | ./usr/share/doc/python-websockets/project/index.html·time=1702738900.0·mode=644·size=19641·md5digest=f0a9d208ed53175540d6f0309742f8bd·sha256digest=34db0bb7c3b90caffa82b7ab35abcb279445a7a8029fe4338ccc9a66ebfd88fe |
325 | ./usr/share/doc/python-websockets/project/changelog·time=1702738900.0·type=dir | 325 | ./usr/share/doc/python-websockets/project/changelog·time=1702738900.0·type=dir |
326 | ./usr/share/doc/python-websockets/project/changelog/index.html·time=1702738900.0·mode=644·size=1 | 326 | ./usr/share/doc/python-websockets/project/changelog/index.html·time=1702738900.0·mode=644·size=118659·md5digest=2e4598f3e8d6cb305db4b8b9c2341295·sha256digest=aa9d751ba9c0b41c4cdcb35f0389af1be6a7a35ca026e81682aef667f6b5d535 |
327 | ./usr/share/doc/python-websockets/project/contributing·time=1702738900.0·type=dir | 327 | ./usr/share/doc/python-websockets/project/contributing·time=1702738900.0·type=dir |
328 | ./usr/share/doc/python-websockets/project/contributing/index.html·time=1702738900.0·mode=644·size=23 | 328 | ./usr/share/doc/python-websockets/project/contributing/index.html·time=1702738900.0·mode=644·size=23430·md5digest=b8126e8cb1b902de5b5d637a42124d95·sha256digest=e4083ede3f3aaa06a43924a731c48ffb5baffee3e9139ac51c8746b7a21971cf |
329 | ./usr/share/doc/python-websockets/project/license·time=1702738900.0·type=dir | 329 | ./usr/share/doc/python-websockets/project/license·time=1702738900.0·type=dir |
330 | ./usr/share/doc/python-websockets/project/license/index.html·time=1702738900.0·mode=644·size=21112·md5digest=e2f75cd07c41ee930735c4d81094e6e6·sha256digest=c7ac3f1fb2af4ea6a20988e576a9ab0217f25edc2d9e628dc8ba2f142c58a8d6 | 330 | ./usr/share/doc/python-websockets/project/license/index.html·time=1702738900.0·mode=644·size=21112·md5digest=e2f75cd07c41ee930735c4d81094e6e6·sha256digest=c7ac3f1fb2af4ea6a20988e576a9ab0217f25edc2d9e628dc8ba2f142c58a8d6 |
331 | ./usr/share/doc/python-websockets/project/tidelift·time=1702738900.0·type=dir | 331 | ./usr/share/doc/python-websockets/project/tidelift·time=1702738900.0·type=dir |
332 | ./usr/share/doc/python-websockets/project/tidelift/index.html·time=1702738900.0·mode=644·size=24651·md5digest=33f979123e5ac405376bec7ad2841ab5·sha256digest=58e08d2f622357940ea00bf62b7cd57c4654388c4aa81d98a38f8975b50ee65d | 332 | ./usr/share/doc/python-websockets/project/tidelift/index.html·time=1702738900.0·mode=644·size=24651·md5digest=33f979123e5ac405376bec7ad2841ab5·sha256digest=58e08d2f622357940ea00bf62b7cd57c4654388c4aa81d98a38f8975b50ee65d |
333 | ./usr/share/doc/python-websockets/py-modindex·time=1702738900.0·type=dir | 333 | ./usr/share/doc/python-websockets/py-modindex·time=1702738900.0·type=dir |
334 | ./usr/share/doc/python-websockets/py-modindex/index.html·time=1702738900.0·mode=644·size=21987·md5digest=1406f578126dcf0f903c2967a789f2d1·sha256digest=4381a1f62db84cf797180b981515ecd3474fc555f02aea1743b8ab465f441dde | 334 | ./usr/share/doc/python-websockets/py-modindex/index.html·time=1702738900.0·mode=644·size=21987·md5digest=1406f578126dcf0f903c2967a789f2d1·sha256digest=4381a1f62db84cf797180b981515ecd3474fc555f02aea1743b8ab465f441dde |
335 | ./usr/share/doc/python-websockets/reference·time=1702738900.0·type=dir | 335 | ./usr/share/doc/python-websockets/reference·time=1702738900.0·type=dir |
336 | ./usr/share/doc/python-websockets/reference/index.html·time=1702738900.0·mode=644·size=24 | 336 | ./usr/share/doc/python-websockets/reference/index.html·time=1702738900.0·mode=644·size=24460·md5digest=0ed2fe4ffe1be18942913f7df04b6a30·sha256digest=4b51c3f8d6f112446e9c7f4ab244d667235668bbe05e2e90044e00b9dd8f5b34 |
337 | ./usr/share/doc/python-websockets/reference/asyncio·time=1702738900.0·type=dir | 337 | ./usr/share/doc/python-websockets/reference/asyncio·time=1702738900.0·type=dir |
338 | ./usr/share/doc/python-websockets/reference/asyncio/client·time=1702738900.0·type=dir | 338 | ./usr/share/doc/python-websockets/reference/asyncio/client·time=1702738900.0·type=dir |
339 | ./usr/share/doc/python-websockets/reference/asyncio/client/index.html·time=1702738900.0·mode=644·size= | 339 | ./usr/share/doc/python-websockets/reference/asyncio/client/index.html·time=1702738900.0·mode=644·size=86570·md5digest=dea0056296390c695eea48729d55adf6·sha256digest=22f89d38730acc813b6d4da86c809e9026575be88554d195b411efdc9d2b2f47 |
340 | ./usr/share/doc/python-websockets/reference/asyncio/common·time=1702738900.0·type=dir | 340 | ./usr/share/doc/python-websockets/reference/asyncio/common·time=1702738900.0·type=dir |
341 | ./usr/share/doc/python-websockets/reference/asyncio/common/index.html·time=1702738900.0·mode=644·size=7 | 341 | ./usr/share/doc/python-websockets/reference/asyncio/common/index.html·time=1702738900.0·mode=644·size=71523·md5digest=9bb3378d2a78ae2aaf039ef0bd34efe7·sha256digest=ebcbae09303b9896f04d7d6617032f085ee68bd9ea954e4b199ca8016b50bc04 |
342 | ./usr/share/doc/python-websockets/reference/asyncio/server·time=1702738900.0·type=dir | 342 | ./usr/share/doc/python-websockets/reference/asyncio/server·time=1702738900.0·type=dir |
343 | ./usr/share/doc/python-websockets/reference/asyncio/server/index.html·time=1702738900.0·mode=644·size=1 | 343 | ./usr/share/doc/python-websockets/reference/asyncio/server/index.html·time=1702738900.0·mode=644·size=130815·md5digest=4c3a9afb36ed54d9f9b32caba15634f9·sha256digest=0cd73196e4e049a1953ce196f35a5c63b90b2cc1a4880be456c9f93c555f6565 |
344 | ./usr/share/doc/python-websockets/reference/datastructures·time=1702738900.0·type=dir | 344 | ./usr/share/doc/python-websockets/reference/datastructures·time=1702738900.0·type=dir |
345 | ./usr/share/doc/python-websockets/reference/datastructures/index.html·time=1702738900.0·mode=644·size= | 345 | ./usr/share/doc/python-websockets/reference/datastructures/index.html·time=1702738900.0·mode=644·size=67934·md5digest=7b7cafc1fffa522778611c147ee6a527·sha256digest=ad4838c8131861b9cbf850d7888efc31e65fa4be919d5a855bed69b3ed81512f |
346 | ./usr/share/doc/python-websockets/reference/exceptions·time=1702738900.0·type=dir | 346 | ./usr/share/doc/python-websockets/reference/exceptions·time=1702738900.0·type=dir |
347 | ./usr/share/doc/python-websockets/reference/exceptions/index.html·time=1702738900.0·mode=644·size=56 | 347 | ./usr/share/doc/python-websockets/reference/exceptions/index.html·time=1702738900.0·mode=644·size=56408·md5digest=675fc9e47b3861f05e4ad25f6c25d7fe·sha256digest=288fa4d404888743d691af78bede0b5b4cd89ba3ecfbdd423dfbb6510719dbbf |
348 | ./usr/share/doc/python-websockets/reference/extensions·time=1702738900.0·type=dir | 348 | ./usr/share/doc/python-websockets/reference/extensions·time=1702738900.0·type=dir |
349 | ./usr/share/doc/python-websockets/reference/extensions/index.html·time=1702738900.0·mode=644·size=4 | 349 | ./usr/share/doc/python-websockets/reference/extensions/index.html·time=1702738900.0·mode=644·size=43340·md5digest=6af98c2128b1d73139733f020e32e3dd·sha256digest=163d6346e82972bcb0fb3cf0cfd8abbc6d318cf94d2f59780c55497614f2ace4 |
350 | ./usr/share/doc/python-websockets/reference/features·time=1702738900.0·type=dir | 350 | ./usr/share/doc/python-websockets/reference/features·time=1702738900.0·type=dir |
351 | ./usr/share/doc/python-websockets/reference/features/index.html·time=1702738900.0·mode=644·size=3 | 351 | ./usr/share/doc/python-websockets/reference/features/index.html·time=1702738900.0·mode=644·size=31576·md5digest=4280096c4592f518c037266f53ecde86·sha256digest=c6cb1c97795e60b5030bce2b57adc7ce338e40ae31b2f3adf1cd467a9e5651c3 |
352 | ./usr/share/doc/python-websockets/reference/sansio·time=1702738900.0·type=dir | 352 | ./usr/share/doc/python-websockets/reference/sansio·time=1702738900.0·type=dir |
353 | ./usr/share/doc/python-websockets/reference/sansio/client·time=1702738900.0·type=dir | 353 | ./usr/share/doc/python-websockets/reference/sansio/client·time=1702738900.0·type=dir |
354 | ./usr/share/doc/python-websockets/reference/sansio/client/index.html·time=1702738900.0·mode=644·size=5 | 354 | ./usr/share/doc/python-websockets/reference/sansio/client/index.html·time=1702738900.0·mode=644·size=54223·md5digest=232b7da933b475ec3213509c0188098b·sha256digest=1bc83c7504497c1c187566d2e0a20899d4ed676e92d0e38768c7e12327471c22 |
355 | ./usr/share/doc/python-websockets/reference/sansio/common·time=1702738900.0·type=dir | 355 | ./usr/share/doc/python-websockets/reference/sansio/common·time=1702738900.0·type=dir |
356 | ./usr/share/doc/python-websockets/reference/sansio/common/index.html·time=1702738900.0·mode=644·size= | 356 | ./usr/share/doc/python-websockets/reference/sansio/common/index.html·time=1702738900.0·mode=644·size=56154·md5digest=1b1b4b3ebcee9401509ed93aca4a653f·sha256digest=86b5f40cb5a662c5e4c7688fcc440dc644e849f006dcb1c54cbbb6d603700edd |
357 | ./usr/share/doc/python-websockets/reference/sansio/server·time=1702738900.0·type=dir | 357 | ./usr/share/doc/python-websockets/reference/sansio/server·time=1702738900.0·type=dir |
358 | ./usr/share/doc/python-websockets/reference/sansio/server/index.html·time=1702738900.0·mode=644·size=6 | 358 | ./usr/share/doc/python-websockets/reference/sansio/server/index.html·time=1702738900.0·mode=644·size=61327·md5digest=9e984a7b2b5deeeb1d7c5c0f36496884·sha256digest=b9b2a82fb2129d005e682e7af5bf50c4ab49f28cd7fa4998fe402ff52edc2fac |
359 | ./usr/share/doc/python-websockets/reference/sync·time=1702738900.0·type=dir | 359 | ./usr/share/doc/python-websockets/reference/sync·time=1702738900.0·type=dir |
Max diff block lines reached; 8225/32760 bytes (25.11%) of diff not shown. |
Offset 3, 15 lines modified | Offset 3, 15 lines modified | ||
3 | pkgname·=·python-websockets | 3 | pkgname·=·python-websockets |
4 | pkgbase·=·python-websockets | 4 | pkgbase·=·python-websockets |
5 | pkgver·=·12.0-1 | 5 | pkgver·=·12.0-1 |
6 | pkgdesc·=·Python·implementation·of·the·WebSocket·Protocol·(RFC·6455) | 6 | pkgdesc·=·Python·implementation·of·the·WebSocket·Protocol·(RFC·6455) |
7 | url·=·https://github.com/aaugustin/websockets | 7 | url·=·https://github.com/aaugustin/websockets |
8 | builddate·=·1702738900 | 8 | builddate·=·1702738900 |
9 | packager·=·Reproducible·Arch·Linux·tests·<reproducible@archlinux.org> | 9 | packager·=·Reproducible·Arch·Linux·tests·<reproducible@archlinux.org> |
10 | size·=·1 | 10 | size·=·12290785 |
11 | arch·=·x86_64 | 11 | arch·=·x86_64 |
12 | license·=·BSD | 12 | license·=·BSD |
13 | depend·=·python | 13 | depend·=·python |
14 | makedepend·=·python-setuptools | 14 | makedepend·=·python-setuptools |
15 | makedepend·=·python-sphinx | 15 | makedepend·=·python-sphinx |
16 | makedepend·=·python-sphinx-copybutton | 16 | makedepend·=·python-sphinx-copybutton |
17 | makedepend·=·python-sphinx-furo | 17 | makedepend·=·python-sphinx-furo |
Offset 1169, 65 lines modified | Offset 1169, 65 lines modified | ||
00004900:·6c74·5f6c·6576·656c·944b·058c·1666·696c··lt_level.K...fil | 00004900:·6c74·5f6c·6576·656c·944b·058c·1666·696c··lt_level.K...fil | ||
00004910:·655f·696e·7365·7274·696f·6e5f·656e·6162··e_insertion_enab | 00004910:·655f·696e·7365·7274·696f·6e5f·656e·6162··e_insertion_enab | ||
00004920:·6c65·6494·888c·1373·6d61·7274·7175·6f74··led....smartquot | 00004920:·6c65·6494·888c·1373·6d61·7274·7175·6f74··led....smartquot | ||
00004930:·6573·5f6c·6f63·616c·6573·945d·9468·a168··es_locales.].h.h | 00004930:·6573·5f6c·6f63·616c·6573·945d·9468·a168··es_locales.].h.h | ||
00004940:·0368·da89·8c0d·6c61·6e67·7561·6765·5f63··.h....language_c | 00004940:·0368·da89·8c0d·6c61·6e67·7561·6765·5f63··.h....language_c | ||
00004950:·6f64·6594·68af·8c0c·736d·6172·745f·7175··ode.h...smart_qu | 00004950:·6f64·6594·68af·8c0c·736d·6172·745f·7175··ode.h...smart_qu | ||
00004960:·6f74·6573·9488·758c·0861·6c6c·5f64·6f63··otes..u..all_doc | 00004960:·6f74·6573·9488·758c·0861·6c6c·5f64·6f63··otes..u..all_doc | ||
00004970:·7394·7d94·286a·7f03·0000·8a07· | 00004970:·7394·7d94·286a·7f03·0000·8a07·41a7·c492··s.}.(j......A... | ||
00004980:· | 00004980:·ed2b·066a·8d03·0000·8a07·7021·c592·ed2b··.+.j......p!...+ | ||
00004990:·066a·9503·0000·8a07· | 00004990:·066a·9503·0000·8a07·49b1·c592·ed2b·066a··.j......I....+.j | ||
000049a0:·9203·0000·8a07· | 000049a0:·9203·0000·8a07·7ed6·c592·ed2b·066a·7d03··......~....+.j}. | ||
000049b0:·0000·8a07· | 000049b0:·0000·8a07·e522·c692·ed2b·066a·a203·0000··....."...+.j.... | ||
000049c0:·8a07· | 000049c0:·8a07·a44b·c792·ed2b·066a·8803·0000·8a07··...K...+.j...... | ||
000049d0:· | 000049d0:·c479·c792·ed2b·066a·9803·0000·8a07·4f11··.y...+.j......O. | ||
000049e0:·c | 000049e0:·c892·ed2b·066a·b303·0000·8a07·811d·c992··...+.j.......... | ||
000049f0:· | 000049f0:·ed2b·066a·7e03·0000·8a07·c854·c992·ed2b··.+.j~......T...+ | ||
00004a00:·066a·8f03·0000·8a07· | 00004a00:·066a·8f03·0000·8a07·ad0e·ca92·ed2b·066a··.j...........+.j | ||
00004a10:·a803·0000·8a07· | 00004a10:·a803·0000·8a07·015f·ca92·ed2b·066a·b103··......._...+.j.. | ||
00004a20:·0000·8a07· | 00004a20:·0000·8a07·27fc·ca92·ed2b·066a·9e03·0000··....'....+.j.... | ||
00004a30:·8a07· | 00004a30:·8a07·8042·cb92·ed2b·066a·9703·0000·8a07··...B...+.j...... | ||
00004a40:· | 00004a40:·62f2·cb92·ed2b·066a·ad03·0000·8a07·4218··b....+.j......B. | ||
00004a50:· | 00004a50:·cd92·ed2b·066a·8603·0000·8a07·2a4b·cd92··...+.j......*K.. | ||
00004a60:· | 00004a60:·ed2b·066a·9303·0000·8a07·dee2·cd92·ed2b··.+.j...........+ | ||
00004a70:·066a·9403·0000·8a07· | 00004a70:·066a·9403·0000·8a07·4b49·ce92·ed2b·066a··.j......KI...+.j | ||
00004a80:·9003·0000·8a07· | 00004a80:·9003·0000·8a07·490f·cf92·ed2b·066a·ab03··......I....+.j.. | ||
00004a90:·0000·8a07· | 00004a90:·0000·8a07·6857·cf92·ed2b·066a·a303·0000··....hW...+.j.... | ||
00004aa0:·8a07· | 00004aa0:·8a07·3fb7·cf92·ed2b·066a·8703·0000·8a07··..?....+.j...... | ||
00004ab0:· | 00004ab0:·48da·cf92·ed2b·066a·9603·0000·8a07·e776··H....+.j.......v | ||
00004ac0:·d | 00004ac0:·d192·ed2b·066a·9c03·0000·8a07·d68c·d292··...+.j.......... | ||
00004ad0:· | 00004ad0:·ed2b·066a·9903·0000·8a07·5a7a·d392·ed2b··.+.j......Zz...+ | ||
00004ae0:·066a·a903·0000·8a07· | 00004ae0:·066a·a903·0000·8a07·2132·d992·ed2b·066a··.j......!2...+.j | ||
00004af0:·8903·0000·8a07· | 00004af0:·8903·0000·8a07·f584·d992·ed2b·066a·8e03··...........+.j.. | ||
00004b00:·0000·8a07· | 00004b00:·0000·8a07·7b94·d992·ed2b·066a·b203·0000··....{....+.j.... | ||
00004b10:·8a07· | 00004b10:·8a07·a0ae·d992·ed2b·066a·b003·0000·8a07··.......+.j...... | ||
00004b20:·e429·eace·a10c·066a·9f03·0000·8a07·c288··.).....j........ | |||
00004b30:·f9ce·a10c·066a·9a03·0000·8a07·607f·01cf··.....j......`... | |||
00004b | 00004b20:·26ea·d992·ed2b·066a·9f03·0000·8a07·6743··&....+.j......gC | ||
00004b30:·e292·ed2b·066a·9a03·0000·8a07·3a53·e692··...+.j......:S.. | |||
00004b40:·ed2b·066a·a703·0000·8a07·4c57·f092·ed2b··.+.j......LW...+ | |||
00004b50:·066a·8503·0000·8a07· | 00004b50:·066a·8503·0000·8a07·99f4·fd92·ed2b·066a··.j...........+.j | ||
00004b60:·a403·0000·8a07· | 00004b60:·a403·0000·8a07·3b38·0393·ed2b·066a·aa03··......;8...+.j.. | ||
00004b70:·0000·8a07· | 00004b70:·0000·8a07·b7fe·0593·ed2b·066a·ae03·0000··.........+.j.... | ||
00004b80:·8a07· | 00004b80:·8a07·873d·0793·ed2b·066a·af03·0000·8a07··...=...+.j...... | ||
00004b90:·39c1·3bcf·a10c·066a·ac03·0000·8a07·4a0d··9.;....j......J. | |||
00004ba0:·45cf·a10c·066a·a003·0000·8a07·5c26·4ccf··E....j......\&L. | |||
00004b | 00004b90:·7581·0793·ed2b·066a·ac03·0000·8a07·8231··u....+.j.......1 | ||
00004ba0:·0b93·ed2b·066a·a003·0000·8a07·7b46·1093··...+.j......{F.. | |||
00004bb0:·ed2b·066a·8303·0000·8a07·6aef·1493·ed2b··.+.j......j....+ | |||
00004bc0:·066a·9103·0000·8a07· | 00004bc0:·066a·9103·0000·8a07·8cbb·1993·ed2b·066a··.j...........+.j | ||
00004bd0:·9d03·0000·8a07· | 00004bd0:·9d03·0000·8a07·fa50·1c93·ed2b·066a·8203··.......P...+.j.. | ||
00004be0:·0000·8a07· | 00004be0:·0000·8a07·80a8·2093·ed2b·066a·8003·0000··......·..+.j.... | ||
00004bf0:·8a07· | 00004bf0:·8a07·b352·2393·ed2b·066a·8a03·0000·8a07··...R#..+.j...... | ||
00004c00:·a687·6fcf·a10c·066a·a503·0000·8a07·07a6··..o....j........ | |||
00004c10:·70cf·a10c·066a·8b03·0000·8a07·5de6·71cf··p....j......].q. | |||
00004c | 00004c00:·54f5·2393·ed2b·066a·a503·0000·8a07·a889··T.#..+.j........ | ||
00004c10:·2493·ed2b·066a·8b03·0000·8a07·bd2f·2593··$..+.j......./%. | |||
00004c20:·ed2b·066a·8403·0000·8a07·e5b1·2593·ed2b··.+.j........%..+ | |||
00004c30:·066a·a103·0000·8a07·e | 00004c30:·066a·a103·0000·8a07·9e62·2793·ed2b·066a··.j.......b'..+.j | ||
00004c40:·9b03·0000·8a07· | 00004c40:·9b03·0000·8a07·f07f·2793·ed2b·066a·7c03··........'..+.j|. | ||
00004c50:·0000·8a07· | 00004c50:·0000·8a07·8e05·2893·ed2b·066a·7b03·0000··......(..+.j{... | ||
00004c60:·8a07· | 00004c60:·8a07·1032·2893·ed2b·066a·8103·0000·8a07··...2(..+.j...... | ||
00004c70:· | 00004c70:·7047·2893·ed2b·066a·a603·0000·8a07·2868··pG(..+.j......(h | ||
00004c80:· | 00004c80:·2893·ed2b·066a·8c03·0000·8a07·89b9·2893··(..+.j........(. | ||
00004c90:· | 00004c90:·ed2b·0675·8c0c·6465·7065·6e64·656e·6369··.+.u..dependenci | ||
00004ca0:·6573·948c·0b63·6f6c·6c65·6374·696f·6e73··es...collections | 00004ca0:·6573·948c·0b63·6f6c·6c65·6374·696f·6e73··es...collections | ||
00004cb0:·948c·0b64·6566·6175·6c74·6469·6374·9493··...defaultdict.. | 00004cb0:·948c·0b64·6566·6175·6c74·6469·6374·9493··...defaultdict.. | ||
00004cc0:·948c·0862·7569·6c74·696e·7394·8c03·7365··...builtins...se | 00004cc0:·948c·0862·7569·6c74·696e·7394·8c03·7365··...builtins...se | ||
00004cd0:·7494·9394·8594·5294·286a·8d03·0000·8f94··t.....R.(j...... | 00004cd0:·7494·9394·8594·5294·286a·8d03·0000·8f94··t.....R.(j...... | ||
00004ce0:·288c·212e·2e2f·6578·616d·706c·652f·6661··(.!../example/fa | 00004ce0:·288c·212e·2e2f·6578·616d·706c·652f·6661··(.!../example/fa | ||
00004cf0:·712f·7368·7574·646f·776e·5f63·6c69·656e··q/shutdown_clien | 00004cf0:·712f·7368·7574·646f·776e·5f63·6c69·656e··q/shutdown_clien | ||
00004d00:·742e·7079·9490·6aa2·0300·008f·9428·8c25··t.py..j......(.% | 00004d00:·742e·7079·9490·6aa2·0300·008f·9428·8c25··t.py..j......(.% | ||
Offset 270499, 15 lines modified | Offset 270499, 15 lines modified | ||
00420a20:·0000·5d94·6ad3·0400·005d·946a·d504·0000··..].j....].j.... | 00420a20:·0000·5d94·6ad3·0400·005d·946a·d504·0000··..].j....].j.... | ||
00420a30:·5d94·6ad7·0400·005d·9475·6ad9·0400·006a··].j....].uj....j | 00420a30:·5d94·6ad7·0400·005d·9475·6ad9·0400·006a··].j....].uj....j | ||
00420a40:·330f·0000·6ac9·0400·006a·7d1b·0400·7562··3...j....j}...ub | 00420a40:·330f·0000·6ac9·0400·006a·7d1b·0400·7562··3...j....j}...ub | ||
00420a50:·6a34·0f00·0029·8194·7d94·286a·b504·0000··j4...)..}.(j.... | 00420a50:·6a34·0f00·0029·8194·7d94·286a·b504·0000··j4...)..}.(j.... | ||
00420a60:·68a5·6ab6·0400·005d·946a·13a9·0300·2981··h.j....].j....). | 00420a60:·68a5·6ab6·0400·005d·946a·13a9·0300·2981··h.j....].j....). | ||
00420a70:·947d·9428·6ab5·0400·0068·a56a·b604·0000··.}.(j....h.j.... | 00420a70:·947d·9428·6ab5·0400·0068·a56a·b604·0000··.}.(j....h.j.... | ||
00420a80:·5d94·6a97·0600·0029·8194·7d94·286a·b504··].j....)..}.(j.. | 00420a80:·5d94·6a97·0600·0029·8194·7d94·286a·b504··].j....)..}.(j.. | ||
00420a90:·0000·95 | 00420a90:·0000·951d·ad00·0000·0000·0068·a56a·b604··...........h.j.. | ||
00420aa0:·0000·5d94·6ac4·0400·008c·0c42·6163·6b70··..].j......Backp | 00420aa0:·0000·5d94·6ac4·0400·008c·0c42·6163·6b70··..].j......Backp | ||
00420ab0:·7265·7373·7572·6594·8594·8194·7d94·6ac9··ressure.....}.j. | 00420ab0:·7265·7373·7572·6594·8594·8194·7d94·6ac9··ressure.....}.j. | ||
00420ac0:·0400·006a·d11d·0400·7362·616a·cd04·0000··...j....sbaj.... | 00420ac0:·0400·006a·d11d·0400·7362·616a·cd04·0000··...j....sbaj.... | ||
00420ad0:·7d94·286a·cf04·0000·5d94·6ad1·0400·005d··}.(j....].j....] | 00420ad0:·7d94·286a·cf04·0000·5d94·6ad1·0400·005d··}.(j....].j....] | ||
00420ae0:·946a·d304·0000·5d94·6ad5·0400·005d·946a··.j....].j....].j | 00420ae0:·946a·d304·0000·5d94·6ad5·0400·005d·946a··.j....].j....].j | ||
00420af0:·d704·0000·5d94·8c08·696e·7465·726e·616c··....]...internal | 00420af0:·d704·0000·5d94·8c08·696e·7465·726e·616c··....]...internal | ||
00420b00:·9488·8c06·7265·6675·7269·946a·a103·0000··....refuri.j.... | 00420b00:·9488·8c06·7265·6675·7269·946a·a103·0000··....refuri.j.... | ||
Offset 273265, 129363 lines modified | Offset 273265, 12 lines modified | ||
0042b700:·785f·616c·6c5f·7469·746c·6573·947d·948c··x_all_titles.}.. | 0042b700:·785f·616c·6c5f·7469·746c·6573·947d·948c··x_all_titles.}.. | ||
0042b710:·1b5f·7365·6172·6368·5f69·6e64·6578·5f69··._search_index_i | 0042b710:·1b5f·7365·6172·6368·5f69·6e64·6578·5f69··._search_index_i | ||
0042b720:·6e64·6578·5f65·6e74·7269·6573·947d·948c··ndex_entries.}.. | 0042b720:·6e64·6578·5f65·6e74·7269·6573·947d·948c··ndex_entries.}.. | ||
0042b730:·165f·7365·6172·6368·5f69·6e64·6578·5f6f··._search_index_o | 0042b730:·165f·7365·6172·6368·5f69·6e64·6578·5f6f··._search_index_o | ||
0042b740:·626a·7479·7065·7394·7d94·8c16·5f73·6561··bjtypes.}..._sea | 0042b740:·626a·7479·7065·7394·7d94·8c16·5f73·6561··bjtypes.}..._sea | ||
0042b750:·7263·685f·696e·6465·785f·6f62·6a6e·616d··rch_index_objnam | 0042b750:·7263·685f·696e·6465·785f·6f62·6a6e·616d··rch_index_objnam | Diff chunk too large, falling back to line-by-line diff (5 lines added, 129356 lines removed) | |
0042b760:·6573·947d·948c·1169·6e74·6572·7370·6869··es.}...intersphi | 0042b760:·6573·947d·948c·1169·6e74·6572·7370·6869··es.}...intersphi | ||
0042b770:·6e78·5f63·6163·6865·947d·94 | 0042b770:·6e78·5f63·6163·6865·947d·948c·1569·6e74··nx_cache.}...int | ||
0042b780:· | 0042b780:·6572·7370·6869·6e78·5f69·6e76·656e·746f··ersphinx_invento | ||
0042b790:·72 | 0042b790:·7279·947d·948c·1b69·6e74·6572·7370·6869··ry.}...intersphi | ||
0042b7a0:· | 0042b7a0:·6e78·5f6e·616d·6564·5f69·6e76·656e·746f··nx_named_invento | ||
0042b7b0:· | 0042b7b0:·7279·947d·9475·622e······················ry.}.ub. | ||
0042b7c0:·7073·3a2f·2f64·6f63·732e·7079·7468·6f6e··ps://docs.python | |||
0042b7d0:·2e6f·7267·2f33·2f63·2d61·7069·2f76·6572··.org/3/c-api/ver | |||
0042b7e0:·7968·6967·682e·6874·6d6c·2363·2e43·4f5f··yhigh.html#c.CO_ | |||
0042b7f0:·4655·5455·5245·5f44·4956·4953·494f·4e94··FUTURE_DIVISION. | |||
0042b800:·6aa1·9500·0074·948c·1750·7941·7379·6e63··j....t...PyAsync | |||
0042b810:·4d65·7468·6f64·732e·616d·5f61·6974·6572··Methods.am_aiter | |||
0042b820:·9428·6a06·2804·006a·0728·0400·8c46·6874··.(j.(..j.(...Fht | |||
0042b830:·7470·733a·2f2f·646f·6373·2e70·7974·686f··tps://docs.pytho | |||
0042b840:·6e2e·6f72·672f·332f·632d·6170·692f·7479··n.org/3/c-api/ty | |||
0042b850:·7065·6f62·6a2e·6874·6d6c·2363·2e50·7941··peobj.html#c.PyA | |||
0042b860:·7379·6e63·4d65·7468·6f64·732e·616d·5f61··syncMethods.am_a | |||
0042b870:·6974·6572·946a·a195·0000·7494·8c17·5079··iter.j....t...Py | |||
0042b880:·4173·796e·634d·6574·686f·6473·2e61·6d5f··AsyncMethods.am_ | |||
0042b890:·616e·6578·7494·286a·0628·0400·6a07·2804··anext.(j.(..j.(. | |||
0042b8a0:·008c·4668·7474·7073·3a2f·2f64·6f63·732e··..Fhttps://docs. | |||
0042b8b0:·7079·7468·6f6e·2e6f·7267·2f33·2f63·2d61··python.org/3/c-a | |||
0042b8c0:·7069·2f74·7970·656f·626a·2e68·746d·6c23··pi/typeobj.html# | |||
0042b8d0:·632e·5079·4173·796e·634d·6574·686f·6473··c.PyAsyncMethods | |||
0042b8e0:·2e61·6d5f·616e·6578·7494·6aa1·9500·0074··.am_anext.j....t | |||
0042b8f0:·948c·1750·7941·7379·6e63·4d65·7468·6f64··...PyAsyncMethod | |||
0042b900:·732e·616d·5f61·7761·6974·9428·6a06·2804··s.am_await.(j.(. | |||
0042b910:·006a·0728·0400·8c46·6874·7470·733a·2f2f··.j.(...Fhttps:// | |||
0042b920:·646f·6373·2e70·7974·686f·6e2e·6f72·672f··docs.python.org/ | |||
0042b930:·332f·632d·6170·692f·7479·7065·6f62·6a2e··3/c-api/typeobj. | |||
0042b940:·6874·6d6c·2363·2e50·7941·7379·6e63·4d65··html#c.PyAsyncMe | |||
0042b950:·7468·6f64·732e·616d·5f61·7761·6974·946a··thods.am_await.j | |||
Max diff block lines reached; -1/8935572 bytes (-0.00%) of diff not shown. |
Offset 271, 15 lines modified | Offset 271, 15 lines modified | ||
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="using-asyncio"> | 273 | ··········<section·id="using-asyncio"> |
274 | <h1>Using·asyncio<a·class="headerlink"·href="#using-asyncio"·title="Link·to·this·heading">#</a></h1> | 274 | <h1>Using·asyncio<a·class="headerlink"·href="#using-asyncio"·title="Link·to·this·heading">#</a></h1> |
275 | <section·id="how-do-i-run-two-coroutines-in-parallel"> | 275 | <section·id="how-do-i-run-two-coroutines-in-parallel"> |
276 | <h2>How·do·I·run·two·coroutines·in·parallel?<a·class="headerlink"·href="#how-do-i-run-two-coroutines-in-parallel"·title="Link·to·this·heading">#</a></h2> | 276 | <h2>How·do·I·run·two·coroutines·in·parallel?<a·class="headerlink"·href="#how-do-i-run-two-coroutines-in-parallel"·title="Link·to·this·heading">#</a></h2> |
277 | <p>You·must·start·two·tasks,·which·the·event·loop·will·run·concurrently.·You·can | 277 | <p>You·must·start·two·tasks,·which·the·event·loop·will·run·concurrently.·You·can |
278 | achieve·this·with·< | 278 | achieve·this·with·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.gather()</span></code>·or·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.create_task()</span></code>.</p> |
279 | <p>Keep·track·of·the·tasks·and·make·sure·they·terminate·or·you·cancel·them·when | 279 | <p>Keep·track·of·the·tasks·and·make·sure·they·terminate·or·you·cancel·them·when |
280 | the·connection·terminates.</p> | 280 | the·connection·terminates.</p> |
281 | </section> | 281 | </section> |
282 | <section·id="why-does-my-program-never-receive-any-messages"> | 282 | <section·id="why-does-my-program-never-receive-any-messages"> |
283 | <h2>Why·does·my·program·never·receive·any·messages?<a·class="headerlink"·href="#why-does-my-program-never-receive-any-messages"·title="Link·to·this·heading">#</a></h2> | 283 | <h2>Why·does·my·program·never·receive·any·messages?<a·class="headerlink"·href="#why-does-my-program-never-receive-any-messages"·title="Link·to·this·heading">#</a></h2> |
284 | <p>Your·program·runs·a·coroutine·that·never·yields·control·to·the·event·loop.·The | 284 | <p>Your·program·runs·a·coroutine·that·never·yields·control·to·the·event·loop.·The |
285 | coroutine·that·receives·messages·never·gets·a·chance·to·run.</p> | 285 | coroutine·that·receives·messages·never·gets·a·chance·to·run.</p> |
Offset 287, 40 lines modified | Offset 287, 40 lines modified | ||
287 | to·yield·control.·Awaiting·a·coroutine·may·yield·control,·but·there’s·no | 287 | to·yield·control.·Awaiting·a·coroutine·may·yield·control,·but·there’s·no |
288 | guarantee·that·it·will.</p> | 288 | guarantee·that·it·will.</p> |
289 | <p>For·example,·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·only·yields | 289 | <p>For·example,·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·only·yields |
290 | control·when·send·buffers·are·full,·which·never·happens·in·most·practical | 290 | control·when·send·buffers·are·full,·which·never·happens·in·most·practical |
291 | cases.</p> | 291 | cases.</p> |
292 | <p>If·you·run·a·loop·that·contains·only·synchronous·operations·and | 292 | <p>If·you·run·a·loop·that·contains·only·synchronous·operations·and |
293 | a·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·call,·you·must·yield | 293 | a·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·call,·you·must·yield |
294 | control·explicitly·with·< | 294 | control·explicitly·with·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.sleep()</span></code>:</p> |
295 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">producer</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 295 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">producer</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
296 | ····<span·class="n">message</span>·<span·class="o">=</span>·<span·class="n">generate_next_message</span><span·class="p">()</span> | 296 | ····<span·class="n">message</span>·<span·class="o">=</span>·<span·class="n">generate_next_message</span><span·class="p">()</span> |
297 | ····<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> | 297 | ····<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> |
298 | ····<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">sleep</span><span·class="p">(</span><span·class="mi">0</span><span·class="p">)</span>··<span·class="c1">#·yield·control·to·the·event·loop</span> | 298 | ····<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">sleep</span><span·class="p">(</span><span·class="mi">0</span><span·class="p">)</span>··<span·class="c1">#·yield·control·to·the·event·loop</span> |
299 | </pre></div> | 299 | </pre></div> |
300 | </div> | 300 | </div> |
301 | <p>< | 301 | <p><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.sleep()</span></code>·always·suspends·the·current·task,·allowing·other·tasks |
302 | to·run.·This·behavior·is·documented·precisely·because·it·isn’t·expected·from | 302 | to·run.·This·behavior·is·documented·precisely·because·it·isn’t·expected·from |
303 | every·coroutine.</p> | 303 | every·coroutine.</p> |
304 | <p>See·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/issues/867">issue·867</a>.</p> | 304 | <p>See·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/issues/867">issue·867</a>.</p> |
305 | </section> | 305 | </section> |
306 | <section·id="why-am-i-having-problems-with-threads"> | 306 | <section·id="why-am-i-having-problems-with-threads"> |
307 | <h2>Why·am·I·having·problems·with·threads?<a·class="headerlink"·href="#why-am-i-having-problems-with-threads"·title="Link·to·this·heading">#</a></h2> | 307 | <h2>Why·am·I·having·problems·with·threads?<a·class="headerlink"·href="#why-am-i-having-problems-with-threads"·title="Link·to·this·heading">#</a></h2> |
308 | <p>If·you·choose·websockets’·default·implementation·based·on·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a>,·then | ||
309 | you·shouldn’t·use·threads.·Indeed,·choosing·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a>·to·handle·concurrency | ||
310 | 308 | <p>If·you·choose·websockets’·default·implementation·based·on·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>,·then | |
309 | you·shouldn’t·use·threads.·Indeed,·choosing·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·to·handle·concurrency | ||
310 | is·mutually·exclusive·with·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>.</p> | ||
311 | <p>If·you·believe·that·you·need·to·run·websockets·in·a·thread·and·some·logic·in | 311 | <p>If·you·believe·that·you·need·to·run·websockets·in·a·thread·and·some·logic·in |
312 | another·thread,·you·should·run·that·logic·in·a·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-task.html#asyncio.Task"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Task</span></code></a>·instead. | ||
313 | If·it·blocks·the·event·loop,·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor"·title="(in·Python·v3.12)"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">run_in_executor()</span></code></a>·will·help.</p> | ||
314 | <p>This·question·is·really·about·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a>.·Please·review·the·advice·about | ||
315 | 312 | another·thread,·you·should·run·that·logic·in·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Task</span></code>·instead. | |
313 | If·it·blocks·the·event·loop,·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">run_in_executor()</span></code>·will·help.</p> | ||
314 | <p>This·question·is·really·about·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.·Please·review·the·advice·about | ||
315 | <span·class="xref·std·std-ref">asyncio-multithreading</span>·in·the·Python·documentation.</p> | ||
316 | </section> | 316 | </section> |
317 | <section·id="why-does-my-simple-program-misbehave-mysteriously"> | 317 | <section·id="why-does-my-simple-program-misbehave-mysteriously"> |
318 | <h2>Why·does·my·simple·program·misbehave·mysteriously?<a·class="headerlink"·href="#why-does-my-simple-program-misbehave-mysteriously"·title="Link·to·this·heading">#</a></h2> | 318 | <h2>Why·does·my·simple·program·misbehave·mysteriously?<a·class="headerlink"·href="#why-does-my-simple-program-misbehave-mysteriously"·title="Link·to·this·heading">#</a></h2> |
319 | <p>You·are·using·< | 319 | <p>You·are·using·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">time.sleep()</span></code>·instead·of·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.sleep()</span></code>,·which |
320 | blocks·the·event·loop·and·prevents·asyncio·from·operating·normally.</p> | 320 | blocks·the·event·loop·and·prevents·asyncio·from·operating·normally.</p> |
321 | <p>This·may·lead·to·messages·getting·send·but·not·received,·to·connection | 321 | <p>This·may·lead·to·messages·getting·send·but·not·received,·to·connection |
322 | timeouts,·and·to·unexpected·results·of·shotgun·debugging·e.g.·adding·an | 322 | timeouts,·and·to·unexpected·results·of·shotgun·debugging·e.g.·adding·an |
323 | unnecessary·call·to·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a> | 323 | unnecessary·call·to·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a> |
324 | makes·the·program·functional.</p> | 324 | makes·the·program·functional.</p> |
325 | </section> | 325 | </section> |
326 | </section> | 326 | </section> |
Offset 126, 16 lines modified | Offset 126, 16 lines modified | ||
126 | *****·Why·am·I·having·problems·with·threads?#·***** | 126 | *****·Why·am·I·having·problems·with·threads?#·***** |
127 | If·you·choose·websocketsâ·default·implementation·based·on·asyncio,·then·you | 127 | If·you·choose·websocketsâ·default·implementation·based·on·asyncio,·then·you |
128 | shouldnât·use·threads.·Indeed,·choosing·asyncio·to·handle·concurrency·is | 128 | shouldnât·use·threads.·Indeed,·choosing·asyncio·to·handle·concurrency·is |
129 | mutually·exclusive·with·threading. | 129 | mutually·exclusive·with·threading. |
130 | If·you·believe·that·you·need·to·run·websockets·in·a·thread·and·some·logic·in | 130 | If·you·believe·that·you·need·to·run·websockets·in·a·thread·and·some·logic·in |
131 | another·thread,·you·should·run·that·logic·in·a·Task·instead.·If·it·blocks·the | 131 | another·thread,·you·should·run·that·logic·in·a·Task·instead.·If·it·blocks·the |
132 | event·loop,·run_in_executor()·will·help. | 132 | event·loop,·run_in_executor()·will·help. |
133 | This·question·is·really·about·asyncio.·Please·review·the·advice·about | 133 | This·question·is·really·about·asyncio.·Please·review·the·advice·about·asyncio- |
134 | 134 | multithreading·in·the·Python·documentation. | |
135 | *****·Why·does·my·simple·program·misbehave·mysteriously?#·***** | 135 | *****·Why·does·my·simple·program·misbehave·mysteriously?#·***** |
136 | You·are·using·time.sleep()·instead·of·asyncio.sleep(),·which·blocks·the·event | 136 | You·are·using·time.sleep()·instead·of·asyncio.sleep(),·which·blocks·the·event |
137 | loop·and·prevents·asyncio·from·operating·normally. | 137 | loop·and·prevents·asyncio·from·operating·normally. |
138 | This·may·lead·to·messages·getting·send·but·not·received,·to·connection | 138 | This·may·lead·to·messages·getting·send·but·not·received,·to·connection |
139 | timeouts,·and·to·unexpected·results·of·shotgun·debugging·e.g.·adding·an | 139 | timeouts,·and·to·unexpected·results·of·shotgun·debugging·e.g.·adding·an |
140 | unnecessary·call·to·send()·makes·the·program·functional. | 140 | unnecessary·call·to·send()·makes·the·program·functional. |
Offset 296, 35 lines modified | Offset 296, 35 lines modified | ||
296 | <section·id="how-do-i-set-http-headers"> | 296 | <section·id="how-do-i-set-http-headers"> |
297 | <h2>How·do·I·set·HTTP·headers?<a·class="headerlink"·href="#how-do-i-set-http-headers"·title="Link·to·this·heading">#</a></h2> | 297 | <h2>How·do·I·set·HTTP·headers?<a·class="headerlink"·href="#how-do-i-set-http-headers"·title="Link·to·this·heading">#</a></h2> |
298 | <p>To·set·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Extensions</span></code>,·or | 298 | <p>To·set·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Extensions</span></code>,·or |
299 | <code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Protocol</span></code>·headers·in·the·WebSocket·handshake·request,·use·the | 299 | <code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Protocol</span></code>·headers·in·the·WebSocket·handshake·request,·use·the |
300 | <code·class="docutils·literal·notranslate"><span·class="pre">origin</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">extensions</span></code>,·or·<code·class="docutils·literal·notranslate"><span·class="pre">subprotocols</span></code>·arguments·of | 300 | <code·class="docutils·literal·notranslate"><span·class="pre">origin</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">extensions</span></code>,·or·<code·class="docutils·literal·notranslate"><span·class="pre">subprotocols</span></code>·arguments·of |
301 | <a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>.</p> | 301 | <a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>.</p> |
302 | <p>To·override·the·<code·class="docutils·literal·notranslate"><span·class="pre">User-Agent</span></code>·header,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">user_agent_header</span></code>·argument. | 302 | <p>To·override·the·<code·class="docutils·literal·notranslate"><span·class="pre">User-Agent</span></code>·header,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">user_agent_header</span></code>·argument. |
303 | Set·it·to·< | 303 | Set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·remove·the·header.</p> |
304 | <p>To·set·other·HTTP·headers,·for·example·the·<code·class="docutils·literal·notranslate"><span·class="pre">Authorization</span></code>·header,·use·the | 304 | <p>To·set·other·HTTP·headers,·for·example·the·<code·class="docutils·literal·notranslate"><span·class="pre">Authorization</span></code>·header,·use·the |
305 | <code·class="docutils·literal·notranslate"><span·class="pre">extra_headers</span></code>·argument:</p> | 305 | <code·class="docutils·literal·notranslate"><span·class="pre">extra_headers</span></code>·argument:</p> |
306 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">,</span>·<span·class="n">extra_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="o">...</span><span·class="p">})</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 306 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">,</span>·<span·class="n">extra_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="o">...</span><span·class="p">})</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
307 | ····<span·class="o">...</span> | 307 | ····<span·class="o">...</span> |
308 | </pre></div> | 308 | </pre></div> |
309 | </div> | 309 | </div> |
310 | <p>In·the·< | 310 | <p>In·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·API,·this·argument·is·named·<code·class="docutils·literal·notranslate"><span·class="pre">additional_headers</span></code>:</p> |
311 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">,</span>·<span·class="n">additional_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="o">...</span><span·class="p">})</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 311 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">,</span>·<span·class="n">additional_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="o">...</span><span·class="p">})</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
312 | ····<span·class="o">...</span> | 312 | ····<span·class="o">...</span> |
313 | </pre></div> | 313 | </pre></div> |
314 | </div> | 314 | </div> |
315 | </section> | 315 | </section> |
316 | <section·id="how-do-i-force-the-ip-address-that-the-client-connects-to"> | 316 | <section·id="how-do-i-force-the-ip-address-that-the-client-connects-to"> |
317 | <h2>How·do·I·force·the·IP·address·that·the·client·connects·to?<a·class="headerlink"·href="#how-do-i-force-the-ip-address-that-the-client-connects-to"·title="Link·to·this·heading">#</a></h2> | 317 | <h2>How·do·I·force·the·IP·address·that·the·client·connects·to?<a·class="headerlink"·href="#how-do-i-force-the-ip-address-that-the-client-connects-to"·title="Link·to·this·heading">#</a></h2> |
318 | <p>Use·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·of·< | 318 | <p>Use·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·of·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>:</p> |
319 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">await</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span><span·class="s2">"ws://example.com"</span><span·class="p">,</span>·<span·class="n">host</span><span·class="o">=</span><span·class="s2">"192.168.0.1"</span><span·class="p">)</span> | 319 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">await</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span><span·class="s2">"ws://example.com"</span><span·class="p">,</span>·<span·class="n">host</span><span·class="o">=</span><span·class="s2">"192.168.0.1"</span><span·class="p">)</span> |
320 | </pre></div> | 320 | </pre></div> |
321 | </div> | 321 | </div> |
322 | <p><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·accepts·the·same·arguments·as | 322 | <p><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·accepts·the·same·arguments·as |
323 | < | 323 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>.</p> |
324 | </section> | 324 | </section> |
325 | <section·id="how-do-i-close-a-connection"> | 325 | <section·id="how-do-i-close-a-connection"> |
326 | <h2>How·do·I·close·a·connection?<a·class="headerlink"·href="#how-do-i-close-a-connection"·title="Link·to·this·heading">#</a></h2> | 326 | <h2>How·do·I·close·a·connection?<a·class="headerlink"·href="#how-do-i-close-a-connection"·title="Link·to·this·heading">#</a></h2> |
327 | <p>The·easiest·is·to·use·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·as·a·context·manager:</p> | 327 | <p>The·easiest·is·to·use·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·as·a·context·manager:</p> |
328 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 328 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="o">...</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
329 | ····<span·class="o">...</span> | 329 | ····<span·class="o">...</span> |
330 | </pre></div> | 330 | </pre></div> |
Offset 368, 17 lines modified | Offset 368, 17 lines modified | ||
368 | <span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">client</span><span·class="p">())</span> | 368 | <span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">client</span><span·class="p">())</span> |
369 | </pre></div> | 369 | </pre></div> |
370 | </div> | 370 | </div> |
371 | </section> | 371 | </section> |
372 | <section·id="how-do-i-disable-tls-ssl-certificate-verification"> | 372 | <section·id="how-do-i-disable-tls-ssl-certificate-verification"> |
373 | <h2>How·do·I·disable·TLS/SSL·certificate·verification?<a·class="headerlink"·href="#how-do-i-disable-tls-ssl-certificate-verification"·title="Link·to·this·heading">#</a></h2> | 373 | <h2>How·do·I·disable·TLS/SSL·certificate·verification?<a·class="headerlink"·href="#how-do-i-disable-tls-ssl-certificate-verification"·title="Link·to·this·heading">#</a></h2> |
374 | <p>Look·at·the·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·argument·of·< | 374 | <p>Look·at·the·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·argument·of·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>.</p> |
375 | <p><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·accepts·the·same·arguments·as | 375 | <p><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·accepts·the·same·arguments·as |
376 | < | 376 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>.</p> |
377 | </section> | 377 | </section> |
378 | </section> | 378 | </section> |
379 | ········</article> | 379 | ········</article> |
380 | ······</div> | 380 | ······</div> |
381 | ······<footer> | 381 | ······<footer> |
382 | ········ | 382 | ········ |
Offset 354, 30 lines modified | Offset 354, 30 lines modified | ||
354 | </ul> | 354 | </ul> |
355 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../topics/timeouts/"><span·class="doc">timeouts</span></a>·for·details.</p> | 355 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../topics/timeouts/"><span·class="doc">timeouts</span></a>·for·details.</p> |
356 | <p>If·websockets’·default·timeout·of·20·seconds·is·too·short·for·your·use·case, | 356 | <p>If·websockets’·default·timeout·of·20·seconds·is·too·short·for·your·use·case, |
357 | you·can·adjust·it·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·argument.</p> | 357 | you·can·adjust·it·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·argument.</p> |
358 | </section> | 358 | </section> |
359 | <section·id="how-do-i-set-a-timeout-on-recv"> | 359 | <section·id="how-do-i-set-a-timeout-on-recv"> |
360 | <h2>How·do·I·set·a·timeout·on·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>?<a·class="headerlink"·href="#how-do-i-set-a-timeout-on-recv"·title="Link·to·this·heading">#</a></h2> | 360 | <h2>How·do·I·set·a·timeout·on·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>?<a·class="headerlink"·href="#how-do-i-set-a-timeout-on-recv"·title="Link·to·this·heading">#</a></h2> |
361 | <p>On·Python·≥·3.11,·use·< | 361 | <p>On·Python·≥·3.11,·use·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.timeout()</span></code>:</p> |
362 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">timeout</span><span·class="p">(</span><span·class="n">timeout</span><span·class="o">=</span><span·class="mi">10</span><span·class="p">):</span> | 362 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">timeout</span><span·class="p">(</span><span·class="n">timeout</span><span·class="o">=</span><span·class="mi">10</span><span·class="p">):</span> |
363 | ····<span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">()</span> | 363 | ····<span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">()</span> |
364 | </pre></div> | 364 | </pre></div> |
365 | </div> | 365 | </div> |
366 | <p>On·older·versions·of·Python,·use·< | 366 | <p>On·older·versions·of·Python,·use·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.wait_for()</span></code>:</p> |
367 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">wait_for</span><span·class="p">(</span><span·class="n">websocket</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">(),</span>·<span·class="n">timeout</span><span·class="o">=</span><span·class="mi">10</span><span·class="p">)</span> | 367 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">wait_for</span><span·class="p">(</span><span·class="n">websocket</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">(),</span>·<span·class="n">timeout</span><span·class="o">=</span><span·class="mi">10</span><span·class="p">)</span> |
368 | </pre></div> | 368 | </pre></div> |
369 | </div> | 369 | </div> |
370 | <p>This·technique·works·for·most·APIs.·When·it·doesn’t,·for·example·with | 370 | <p>This·technique·works·for·most·APIs.·When·it·doesn’t,·for·example·with |
371 | asynchronous·context·managers,·websockets·provides·an·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·argument.</p> | 371 | asynchronous·context·managers,·websockets·provides·an·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·argument.</p> |
372 | </section> | 372 | </section> |
373 | <section·id="how-can-i-pass-arguments-to-a-custom-protocol-subclass"> | 373 | <section·id="how-can-i-pass-arguments-to-a-custom-protocol-subclass"> |
374 | <h2>How·can·I·pass·arguments·to·a·custom·protocol·subclass?<a·class="headerlink"·href="#how-can-i-pass-arguments-to-a-custom-protocol-subclass"·title="Link·to·this·heading">#</a></h2> | 374 | <h2>How·can·I·pass·arguments·to·a·custom·protocol·subclass?<a·class="headerlink"·href="#how-can-i-pass-arguments-to-a-custom-protocol-subclass"·title="Link·to·this·heading">#</a></h2> |
375 | <p>You·can·bind·additional·arguments·to·the·protocol·factory·with | 375 | <p>You·can·bind·additional·arguments·to·the·protocol·factory·with |
376 | < | 376 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">functools.partial()</span></code>:</p> |
377 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">asyncio</span> | 377 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">asyncio</span> |
378 | <span·class="kn">import</span>·<span·class="nn">functools</span> | 378 | <span·class="kn">import</span>·<span·class="nn">functools</span> |
379 | <span·class="kn">import</span>·<span·class="nn">websockets</span> | 379 | <span·class="kn">import</span>·<span·class="nn">websockets</span> |
380 | <span·class="k">class</span>·<span·class="nc">MyServerProtocol</span><span·class="p">(</span><span·class="n">websockets</span><span·class="o">.</span><span·class="n">WebSocketServerProtocol</span><span·class="p">):</span> | 380 | <span·class="k">class</span>·<span·class="nc">MyServerProtocol</span><span·class="p">(</span><span·class="n">websockets</span><span·class="o">.</span><span·class="n">WebSocketServerProtocol</span><span·class="p">):</span> |
381 | ····<span·class="k">def</span>·<span·class="fm">__init__</span><span·class="p">(</span><span·class="bp">self</span><span·class="p">,</span>·<span·class="o">*</span><span·class="n">args</span><span·class="p">,</span>·<span·class="n">extra_argument</span><span·class="o">=</span><span·class="kc">None</span><span·class="p">,</span>·<span·class="o">**</span><span·class="n">kwargs</span><span·class="p">):</span> | 381 | ····<span·class="k">def</span>·<span·class="fm">__init__</span><span·class="p">(</span><span·class="bp">self</span><span·class="p">,</span>·<span·class="o">*</span><span·class="n">args</span><span·class="p">,</span>·<span·class="n">extra_argument</span><span·class="o">=</span><span·class="kc">None</span><span·class="p">,</span>·<span·class="o">**</span><span·class="n">kwargs</span><span·class="p">):</span> |
382 | ········<span·class="nb">super</span><span·class="p">()</span><span·class="o">.</span><span·class="fm">__init__</span><span·class="p">(</span><span·class="o">*</span><span·class="n">args</span><span·class="p">,</span>·<span·class="o">**</span><span·class="n">kwargs</span><span·class="p">)</span> | 382 | ········<span·class="nb">super</span><span·class="p">()</span><span·class="o">.</span><span·class="fm">__init__</span><span·class="p">(</span><span·class="o">*</span><span·class="n">args</span><span·class="p">,</span>·<span·class="o">**</span><span·class="n">kwargs</span><span·class="p">)</span> |
Offset 270, 15 lines modified | Offset 270, 15 lines modified | ||
270 | ··········</label> | 270 | ··········</label> |
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="frequently-asked-questions"> | 273 | ··········<section·id="frequently-asked-questions"> |
274 | <h1>Frequently·asked·questions<a·class="headerlink"·href="#frequently-asked-questions"·title="Link·to·this·heading">#</a></h1> | 274 | <h1>Frequently·asked·questions<a·class="headerlink"·href="#frequently-asked-questions"·title="Link·to·this·heading">#</a></h1> |
275 | <div·class="seealso·admonition"> | 275 | <div·class="seealso·admonition"> |
276 | <p·class="admonition-title">Many·questions·asked·in·websockets’·issue·tracker·are·really | 276 | <p·class="admonition-title">Many·questions·asked·in·websockets’·issue·tracker·are·really |
277 | about·< | 277 | about·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.</p> |
278 | <p>Python’s·documentation·about·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-dev.html">developing·with·asyncio</a>·is·a·good | 278 | <p>Python’s·documentation·about·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-dev.html">developing·with·asyncio</a>·is·a·good |
279 | complement.</p> | 279 | complement.</p> |
280 | </div> | 280 | </div> |
281 | <div·class="toctree-wrapper·compound"> | 281 | <div·class="toctree-wrapper·compound"> |
282 | <ul> | 282 | <ul> |
283 | <li·class="toctree-l1"><a·class="reference·internal"·href="server/">Server</a><ul> | 283 | <li·class="toctree-l1"><a·class="reference·internal"·href="server/">Server</a><ul> |
284 | <li·class="toctree-l2"><a·class="reference·internal"·href="server/#why-does-the-server-close-the-connection-prematurely">Why·does·the·server·close·the·connection·prematurely?</a></li> | 284 | <li·class="toctree-l2"><a·class="reference·internal"·href="server/#why-does-the-server-close-the-connection-prematurely">Why·does·the·server·close·the·connection·prematurely?</a></li> |
Offset 277, 15 lines modified | Offset 277, 15 lines modified | ||
277 | <p>Often,·this·is·because·you·created·a·script·called·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.py</span></code>·in·your | 277 | <p>Often,·this·is·because·you·created·a·script·called·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.py</span></code>·in·your |
278 | current·working·directory.·Then·<code·class="docutils·literal·notranslate"><span·class="pre">import</span>·<span·class="pre">websockets</span></code>·imports·this·module | 278 | current·working·directory.·Then·<code·class="docutils·literal·notranslate"><span·class="pre">import</span>·<span·class="pre">websockets</span></code>·imports·this·module |
279 | instead·of·the·websockets·library.</p> | 279 | instead·of·the·websockets·library.</p> |
280 | </section> | 280 | </section> |
281 | <section·id="why-is-the-default-implementation-located-in-websockets-legacy"> | 281 | <section·id="why-is-the-default-implementation-located-in-websockets-legacy"> |
282 | <span·id="real-import-paths"></span><h2>Why·is·the·default·implementation·located·in·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.legacy</span></code>?<a·class="headerlink"·href="#why-is-the-default-implementation-located-in-websockets-legacy"·title="Link·to·this·heading">#</a></h2> | 282 | <span·id="real-import-paths"></span><h2>Why·is·the·default·implementation·located·in·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.legacy</span></code>?<a·class="headerlink"·href="#why-is-the-default-implementation-located-in-websockets-legacy"·title="Link·to·this·heading">#</a></h2> |
283 | <p>This·is·an·artifact·of·websockets’·history.·For·its·first·eight·years,·only·the | 283 | <p>This·is·an·artifact·of·websockets’·history.·For·its·first·eight·years,·only·the |
284 | < | 284 | <code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·implementation·existed.·Then,·the·Sans-I/O·implementation·was |
285 | added.·Moving·the·code·in·a·<code·class="docutils·literal·notranslate"><span·class="pre">legacy</span></code>·submodule·eased·this·refactoring·and | 285 | added.·Moving·the·code·in·a·<code·class="docutils·literal·notranslate"><span·class="pre">legacy</span></code>·submodule·eased·this·refactoring·and |
286 | optimized·maintainability.</p> | 286 | optimized·maintainability.</p> |
287 | <p>All·public·APIs·were·kept·at·their·original·locations.·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.legacy</span></code> | 287 | <p>All·public·APIs·were·kept·at·their·original·locations.·<code·class="docutils·literal·notranslate"><span·class="pre">websockets.legacy</span></code> |
288 | isn’t·a·public·API.·It’s·only·visible·in·the·source·code·and·in·stack·traces. | 288 | isn’t·a·public·API.·It’s·only·visible·in·the·source·code·and·in·stack·traces. |
289 | There·is·no·intent·to·deprecate·this·implementation·—·at·least·until·a·superior | 289 | There·is·no·intent·to·deprecate·this·implementation·—·at·least·until·a·superior |
290 | alternative·exists.</p> | 290 | alternative·exists.</p> |
291 | </section> | 291 | </section> |
Offset 411, 15 lines modified | Offset 411, 15 lines modified | ||
411 | <p><a·class="reference·internal"·href="../../howto/django/"><span·class="doc">Integrate·with·Django</span></a>·contains·a·complete·implementation·of·this·pattern.</p> | 411 | <p><a·class="reference·internal"·href="../../howto/django/"><span·class="doc">Integrate·with·Django</span></a>·contains·a·complete·implementation·of·this·pattern.</p> |
412 | <p>Again,·as·you·scale,·you·may·reach·the·performance·limits·of·a·basic·in-process | 412 | <p>Again,·as·you·scale,·you·may·reach·the·performance·limits·of·a·basic·in-process |
413 | implementation.·You·may·need·an·external·publish·/·subscribe·system·like·<a·class="reference·external"·href="https://redis.io/">Redis</a>.</p> | 413 | implementation.·You·may·need·an·external·publish·/·subscribe·system·like·<a·class="reference·external"·href="https://redis.io/">Redis</a>.</p> |
414 | </section> | 414 | </section> |
415 | <section·id="how-do-i-pass-arguments-to-the-connection-handler"> | 415 | <section·id="how-do-i-pass-arguments-to-the-connection-handler"> |
416 | <h2>How·do·I·pass·arguments·to·the·connection·handler?<a·class="headerlink"·href="#how-do-i-pass-arguments-to-the-connection-handler"·title="Link·to·this·heading">#</a></h2> | 416 | <h2>How·do·I·pass·arguments·to·the·connection·handler?<a·class="headerlink"·href="#how-do-i-pass-arguments-to-the-connection-handler"·title="Link·to·this·heading">#</a></h2> |
417 | <p>You·can·bind·additional·arguments·to·the·connection·handler·with | 417 | <p>You·can·bind·additional·arguments·to·the·connection·handler·with |
418 | < | 418 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">functools.partial()</span></code>:</p> |
419 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">asyncio</span> | 419 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">asyncio</span> |
420 | <span·class="kn">import</span>·<span·class="nn">functools</span> | 420 | <span·class="kn">import</span>·<span·class="nn">functools</span> |
421 | <span·class="kn">import</span>·<span·class="nn">websockets</span> | 421 | <span·class="kn">import</span>·<span·class="nn">websockets</span> |
422 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">,</span>·<span·class="n">extra_argument</span><span·class="p">):</span> | 422 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">,</span>·<span·class="n">extra_argument</span><span·class="p">):</span> |
423 | ····<span·class="o">...</span> | 423 | ····<span·class="o">...</span> |
Offset 470, 40 lines modified | Offset 470, 40 lines modified | ||
470 | </section> | 470 | </section> |
471 | <section·id="how-do-i-set-http-headers"> | 471 | <section·id="how-do-i-set-http-headers"> |
472 | <h2>How·do·I·set·HTTP·headers?<a·class="headerlink"·href="#how-do-i-set-http-headers"·title="Link·to·this·heading">#</a></h2> | 472 | <h2>How·do·I·set·HTTP·headers?<a·class="headerlink"·href="#how-do-i-set-http-headers"·title="Link·to·this·heading">#</a></h2> |
473 | <p>To·set·the·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Extensions</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Protocol</span></code>·headers·in | 473 | <p>To·set·the·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Extensions</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">Sec-WebSocket-Protocol</span></code>·headers·in |
474 | the·WebSocket·handshake·response,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">extensions</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">subprotocols</span></code> | 474 | the·WebSocket·handshake·response,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">extensions</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">subprotocols</span></code> |
475 | arguments·of·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> | 475 | arguments·of·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> |
476 | <p>To·override·the·<code·class="docutils·literal·notranslate"><span·class="pre">Server</span></code>·header,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">server_header</span></code>·argument.·Set·it·to | 476 | <p>To·override·the·<code·class="docutils·literal·notranslate"><span·class="pre">Server</span></code>·header,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">server_header</span></code>·argument.·Set·it·to |
477 | < | 477 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·remove·the·header.</p> |
478 | <p>To·set·other·HTTP·headers,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">extra_headers</span></code>·argument.</p> | 478 | <p>To·set·other·HTTP·headers,·use·the·<code·class="docutils·literal·notranslate"><span·class="pre">extra_headers</span></code>·argument.</p> |
479 | </section> | 479 | </section> |
480 | <section·id="how-do-i-get-the-ip-address-of-the-client"> | 480 | <section·id="how-do-i-get-the-ip-address-of-the-client"> |
481 | <h2>How·do·I·get·the·IP·address·of·the·client?<a·class="headerlink"·href="#how-do-i-get-the-ip-address-of-the-client"·title="Link·to·this·heading">#</a></h2> | 481 | <h2>How·do·I·get·the·IP·address·of·the·client?<a·class="headerlink"·href="#how-do-i-get-the-ip-address-of-the-client"·title="Link·to·this·heading">#</a></h2> |
482 | <p>It’s·available·in·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"·title="websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">remote_address</span></code></a>:</p> | 482 | <p>It’s·available·in·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"·title="websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">remote_address</span></code></a>:</p> |
483 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 483 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
484 | ····<span·class="n">remote_ip</span>·<span·class="o">=</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">remote_address</span><span·class="p">[</span><span·class="mi">0</span><span·class="p">]</span> | 484 | ····<span·class="n">remote_ip</span>·<span·class="o">=</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">remote_address</span><span·class="p">[</span><span·class="mi">0</span><span·class="p">]</span> |
485 | </pre></div> | 485 | </pre></div> |
486 | </div> | 486 | </div> |
487 | </section> | 487 | </section> |
488 | <section·id="how-do-i-set-the-ip-addresses-that-my-server-listens-on"> | 488 | <section·id="how-do-i-set-the-ip-addresses-that-my-server-listens-on"> |
489 | <h2>How·do·I·set·the·IP·addresses·that·my·server·listens·on?<a·class="headerlink"·href="#how-do-i-set-the-ip-addresses-that-my-server-listens-on"·title="Link·to·this·heading">#</a></h2> | 489 | <h2>How·do·I·set·the·IP·addresses·that·my·server·listens·on?<a·class="headerlink"·href="#how-do-i-set-the-ip-addresses-that-my-server-listens-on"·title="Link·to·this·heading">#</a></h2> |
490 | <p>Use·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·of·< | 490 | <p>Use·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·of·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>:</p> |
491 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">await</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="n">host</span><span·class="o">=</span><span·class="s2">"192.168.0.1"</span><span·class="p">,</span>·<span·class="n">port</span><span·class="o">=</span><span·class="mi">8080</span><span·class="p">)</span> | 491 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">await</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="n">host</span><span·class="o">=</span><span·class="s2">"192.168.0.1"</span><span·class="p">,</span>·<span·class="n">port</span><span·class="o">=</span><span·class="mi">8080</span><span·class="p">)</span> |
492 | </pre></div> | 492 | </pre></div> |
493 | </div> | 493 | </div> |
494 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·accepts·the·same·arguments·as | 494 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·accepts·the·same·arguments·as |
495 | < | 495 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>.</p> |
496 | </section> | 496 | </section> |
497 | <section·id="what-does-oserror-errno-99-error-while-attempting-to-bind-on-address-1-80-0-0-address-not-available-mean"> | 497 | <section·id="what-does-oserror-errno-99-error-while-attempting-to-bind-on-address-1-80-0-0-address-not-available-mean"> |
498 | <h2>What·does·<code·class="docutils·literal·notranslate"><span·class="pre">OSError:</span>·<span·class="pre">[Errno</span>·<span·class="pre">99]</span>·<span·class="pre">error</span>·<span·class="pre">while</span>·<span·class="pre">attempting</span>·<span·class="pre">to</span>·<span·class="pre">bind</span>·<span·class="pre">on</span>·<span·class="pre">address</span>·<span·class="pre">('::1',</span>·<span·class="pre">80,</span>·<span·class="pre">0,</span>·<span·class="pre">0):</span>·<span·class="pre">address</span>·<span·class="pre">not</span>·<span·class="pre">available</span></code>·mean?<a·class="headerlink"·href="#what-does-oserror-errno-99-error-while-attempting-to-bind-on-address-1-80-0-0-address-not-available-mean"·title="Link·to·this·heading">#</a></h2> | 498 | <h2>What·does·<code·class="docutils·literal·notranslate"><span·class="pre">OSError:</span>·<span·class="pre">[Errno</span>·<span·class="pre">99]</span>·<span·class="pre">error</span>·<span·class="pre">while</span>·<span·class="pre">attempting</span>·<span·class="pre">to</span>·<span·class="pre">bind</span>·<span·class="pre">on</span>·<span·class="pre">address</span>·<span·class="pre">('::1',</span>·<span·class="pre">80,</span>·<span·class="pre">0,</span>·<span·class="pre">0):</span>·<span·class="pre">address</span>·<span·class="pre">not</span>·<span·class="pre">available</span></code>·mean?<a·class="headerlink"·href="#what-does-oserror-errno-99-error-while-attempting-to-bind-on-address-1-80-0-0-address-not-available-mean"·title="Link·to·this·heading">#</a></h2> |
499 | <p>You·are·calling·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·without·a·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·in·a·context | 499 | <p>You·are·calling·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·without·a·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·argument·in·a·context |
500 | where·IPv6·isn’t·available.</p> | 500 | where·IPv6·isn’t·available.</p> |
501 | <p>To·listen·only·on·IPv4,·specify·<code·class="docutils·literal·notranslate"><span·class="pre">host="0.0.0.0"</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">family=socket.AF_INET</span></code>.</p> | 501 | <p>To·listen·only·on·IPv4,·specify·<code·class="docutils·literal·notranslate"><span·class="pre">host="0.0.0.0"</span></code>·or·<code·class="docutils·literal·notranslate"><span·class="pre">family=socket.AF_INET</span></code>.</p> |
502 | <p>Refer·to·the·documentation·of·< | 502 | <p>Refer·to·the·documentation·of·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·for·details.</p> |
503 | </section> | 503 | </section> |
504 | <section·id="how-do-i-close-a-connection"> | 504 | <section·id="how-do-i-close-a-connection"> |
505 | <h2>How·do·I·close·a·connection?<a·class="headerlink"·href="#how-do-i-close-a-connection"·title="Link·to·this·heading">#</a></h2> | 505 | <h2>How·do·I·close·a·connection?<a·class="headerlink"·href="#how-do-i-close-a-connection"·title="Link·to·this·heading">#</a></h2> |
506 | <p>websockets·takes·care·of·closing·the·connection·when·the·handler·exits.</p> | 506 | <p>websockets·takes·care·of·closing·the·connection·when·the·handler·exits.</p> |
507 | </section> | 507 | </section> |
508 | <section·id="how-do-i-stop-a-server"> | 508 | <section·id="how-do-i-stop-a-server"> |
509 | <h2>How·do·I·stop·a·server?<a·class="headerlink"·href="#how-do-i-stop-a-server"·title="Link·to·this·heading">#</a></h2> | 509 | <h2>How·do·I·stop·a·server?<a·class="headerlink"·href="#how-do-i-stop-a-server"·title="Link·to·this·heading">#</a></h2> |
Offset 280, 25 lines modified | Offset 280, 25 lines modified | ||
280 | <ul> | 280 | <ul> |
281 | <li><p>Call·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·and | 281 | <li><p>Call·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·and |
282 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·to·receive·and·send | 282 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·to·receive·and·send |
283 | messages·at·any·time.</p></li> | 283 | messages·at·any·time.</p></li> |
284 | <li><p>When·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·or | 284 | <li><p>When·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·or |
285 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises | 285 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises |
286 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>,·clean·up·and·exit.·If·you·started | 286 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>,·clean·up·and·exit.·If·you·started |
287 | other·< | 287 | other·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.Task</span></code>,·terminate·them·before·exiting.</p></li> |
288 | <li><p>If·you·aren’t·awaiting·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>, | 288 | <li><p>If·you·aren’t·awaiting·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>, |
289 | consider·awaiting·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.wait_closed"·title="websockets.legacy.protocol.WebSocketCommonProtocol.wait_closed"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">wait_closed()</span></code></a> | 289 | consider·awaiting·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.wait_closed"·title="websockets.legacy.protocol.WebSocketCommonProtocol.wait_closed"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">wait_closed()</span></code></a> |
290 | to·detect·quickly·when·the·connection·is·closed.</p></li> | 290 | to·detect·quickly·when·the·connection·is·closed.</p></li> |
291 | <li><p>You·may·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.ping"·title="websockets.legacy.protocol.WebSocketCommonProtocol.ping"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ping()</span></code></a>·or | 291 | <li><p>You·may·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.ping"·title="websockets.legacy.protocol.WebSocketCommonProtocol.ping"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ping()</span></code></a>·or |
292 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.pong"·title="websockets.legacy.protocol.WebSocketCommonProtocol.pong"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">pong()</span></code></a>·if·you·wish·but·it·isn’t | 292 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.pong"·title="websockets.legacy.protocol.WebSocketCommonProtocol.pong"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">pong()</span></code></a>·if·you·wish·but·it·isn’t |
293 | needed·in·general.</p></li> | 293 | needed·in·general.</p></li> |
294 | </ul> | 294 | </ul> |
295 | </li> | 295 | </li> |
296 | <li><p>Create·a·server·with·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·which·is·similar·to·asyncio’s | 296 | <li><p>Create·a·server·with·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·which·is·similar·to·asyncio’s |
297 | < | 297 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>.·You·can·also·use·it·as·an·asynchronous |
298 | context·manager.</p> | 298 | context·manager.</p> |
299 | <ul> | 299 | <ul> |
300 | <li><p>The·server·takes·care·of·establishing·connections,·then·lets·the·handler | 300 | <li><p>The·server·takes·care·of·establishing·connections,·then·lets·the·handler |
301 | execute·the·application·logic,·and·finally·closes·the·connection·after·the | 301 | execute·the·application·logic,·and·finally·closes·the·connection·after·the |
302 | handler·exits·normally·or·with·an·exception.</p></li> | 302 | handler·exits·normally·or·with·an·exception.</p></li> |
303 | <li><p>For·advanced·customization,·you·may·subclass | 303 | <li><p>For·advanced·customization,·you·may·subclass |
304 | <a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>·and·pass·either·this·subclass·or | 304 | <a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>·and·pass·either·this·subclass·or |
Offset 307, 15 lines modified | Offset 307, 15 lines modified | ||
307 | </li> | 307 | </li> |
308 | </ul> | 308 | </ul> |
309 | </section> | 309 | </section> |
310 | <section·id="client"> | 310 | <section·id="client"> |
311 | <h2>Client<a·class="headerlink"·href="#client"·title="Link·to·this·heading">#</a></h2> | 311 | <h2>Client<a·class="headerlink"·href="#client"·title="Link·to·this·heading">#</a></h2> |
312 | <ul·class="simple"> | 312 | <ul·class="simple"> |
313 | <li><p>Create·a·client·with·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·which·is·similar·to·asyncio’s | 313 | <li><p>Create·a·client·with·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·which·is·similar·to·asyncio’s |
314 | < | 314 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>.·You·can·also·use·it·as·an |
315 | asynchronous·context·manager.</p> | 315 | asynchronous·context·manager.</p> |
316 | <ul> | 316 | <ul> |
317 | <li><p>For·advanced·customization,·you·may·subclass | 317 | <li><p>For·advanced·customization,·you·may·subclass |
318 | <a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·and·pass·either·this·subclass·or | 318 | <a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·and·pass·either·this·subclass·or |
319 | a·factory·function·as·the·<code·class="docutils·literal·notranslate"><span·class="pre">create_protocol</span></code>·argument.</p></li> | 319 | a·factory·function·as·the·<code·class="docutils·literal·notranslate"><span·class="pre">create_protocol</span></code>·argument.</p></li> |
320 | </ul> | 320 | </ul> |
321 | </li> | 321 | </li> |
Offset 382, 18 lines modified | Offset 382, 18 lines modified | ||
382 | <code·class="docutils·literal·notranslate"><span·class="pre">DJANGO_SETTINGS_MODULE</span></code>·environment·variable·is·set·to·the·Python·path·to | 382 | <code·class="docutils·literal·notranslate"><span·class="pre">DJANGO_SETTINGS_MODULE</span></code>·environment·variable·is·set·to·the·Python·path·to |
383 | your·settings·module.</p> | 383 | your·settings·module.</p> |
384 | <p>The·connection·handler·reads·the·first·message·received·from·the·client,·which | 384 | <p>The·connection·handler·reads·the·first·message·received·from·the·client,·which |
385 | is·expected·to·contain·a·django-sesame·token.·Then·it·authenticates·the·user | 385 | is·expected·to·contain·a·django-sesame·token.·Then·it·authenticates·the·user |
386 | with·<code·class="docutils·literal·notranslate"><span·class="pre">get_user()</span></code>,·the·API·for·<a·class="reference·external"·href="https://django-sesame.readthedocs.io/en/stable/howto.html#outside-a-view">authentication·outside·a·view</a>.·If | 386 | with·<code·class="docutils·literal·notranslate"><span·class="pre">get_user()</span></code>,·the·API·for·<a·class="reference·external"·href="https://django-sesame.readthedocs.io/en/stable/howto.html#outside-a-view">authentication·outside·a·view</a>.·If |
387 | authentication·fails,·it·closes·the·connection·and·exits.</p> | 387 | authentication·fails,·it·closes·the·connection·and·exits.</p> |
388 | <p>When·we·call·an·API·that·makes·a·database·query·such·as·<code·class="docutils·literal·notranslate"><span·class="pre">get_user()</span></code>,·we | 388 | <p>When·we·call·an·API·that·makes·a·database·query·such·as·<code·class="docutils·literal·notranslate"><span·class="pre">get_user()</span></code>,·we |
389 | wrap·the·call·in·< | 389 | wrap·the·call·in·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">to_thread()</span></code>.·Indeed,·the·Django·ORM·doesn’t |
390 | support·asynchronous·I/O.·It·would·block·the·event·loop·if·it·didn’t·run·in·a | 390 | support·asynchronous·I/O.·It·would·block·the·event·loop·if·it·didn’t·run·in·a |
391 | separate·thread.·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread"·title="(in·Python·v3.12)"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">to_thread()</span></code></a>·is·available·since·Python·3.9.·In | ||
392 | 391 | separate·thread.·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">to_thread()</span></code>·is·available·since·Python·3.9.·In | |
392 | earlier·versions,·use·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">run_in_executor()</span></code>·instead.</p> | ||
393 | <p>Finally,·we·start·a·server·with·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> | 393 | <p>Finally,·we·start·a·server·with·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> |
394 | <p>We’re·ready·to·test!</p> | 394 | <p>We’re·ready·to·test!</p> |
395 | <p>Save·this·code·to·a·file·called·<code·class="docutils·literal·notranslate"><span·class="pre">authentication.py</span></code>,·make·sure·the | 395 | <p>Save·this·code·to·a·file·called·<code·class="docutils·literal·notranslate"><span·class="pre">authentication.py</span></code>,·make·sure·the |
396 | <code·class="docutils·literal·notranslate"><span·class="pre">DJANGO_SETTINGS_MODULE</span></code>·environment·variable·is·set·properly,·and·start·the | 396 | <code·class="docutils·literal·notranslate"><span·class="pre">DJANGO_SETTINGS_MODULE</span></code>·environment·variable·is·set·properly,·and·start·the |
397 | websockets·server:</p> | 397 | websockets·server:</p> |
398 | <div·class="highlight-console·notranslate"><div·class="highlight"><pre><span></span><span·class="gp">$·</span>python<span·class="w">·</span>authentication.py | 398 | <div·class="highlight-console·notranslate"><div·class="highlight"><pre><span></span><span·class="gp">$·</span>python<span·class="w">·</span>authentication.py |
399 | </pre></div> | 399 | </pre></div> |
Offset 592, 15 lines modified | Offset 592, 15 lines modified | ||
592 | <span·class="k">if</span>·<span·class="vm">__name__</span>·<span·class="o">==</span>·<span·class="s2">"__main__"</span><span·class="p">:</span> | 592 | <span·class="k">if</span>·<span·class="vm">__name__</span>·<span·class="o">==</span>·<span·class="s2">"__main__"</span><span·class="p">:</span> |
593 | ····<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> | 593 | ····<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> |
594 | </pre></div> | 594 | </pre></div> |
595 | </div> | 595 | </div> |
596 | <p>Since·the·<code·class="docutils·literal·notranslate"><span·class="pre">get_content_types()</span></code>·function·makes·a·database·query,·it·is | 596 | <p>Since·the·<code·class="docutils·literal·notranslate"><span·class="pre">get_content_types()</span></code>·function·makes·a·database·query,·it·is |
597 | wrapped·inside·< | 597 | wrapped·inside·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">asyncio.to_thread()</span></code>.·It·runs·once·when·each·WebSocket |
598 | connection·is·open;·then·its·result·is·cached·for·the·lifetime·of·the | 598 | connection·is·open;·then·its·result·is·cached·for·the·lifetime·of·the |
599 | connection.·Indeed,·running·it·for·each·message·would·trigger·database·queries | 599 | connection.·Indeed,·running·it·for·each·message·would·trigger·database·queries |
600 | for·all·connected·users·at·the·same·time,·which·would·hurt·the·database.</p> | 600 | for·all·connected·users·at·the·same·time,·which·would·hurt·the·database.</p> |
601 | <p>The·connection·handler·merely·registers·the·connection·in·a·global·variable, | 601 | <p>The·connection·handler·merely·registers·the·connection·in·a·global·variable, |
602 | associated·to·the·list·of·content·types·for·which·events·should·be·sent·to | 602 | associated·to·the·list·of·content·types·for·which·events·should·be·sent·to |
603 | that·connection,·and·waits·until·the·client·disconnects.</p> | 603 | that·connection,·and·waits·until·the·client·disconnects.</p> |
604 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">process_events()</span></code>·function·reads·events·from·Redis·and·broadcasts·them | 604 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">process_events()</span></code>·function·reads·events·from·Redis·and·broadcasts·them |
Offset 285, 29 lines modified | Offset 285, 29 lines modified | ||
285 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 285 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
286 | ····<span·class="k">async</span>·<span·class="k">for</span>·<span·class="n">message</span>·<span·class="ow">in</span>·<span·class="n">websocket</span><span·class="p">:</span> | 286 | ····<span·class="k">async</span>·<span·class="k">for</span>·<span·class="n">message</span>·<span·class="ow">in</span>·<span·class="n">websocket</span><span·class="p">:</span> |
287 | ········<span·class="k">await</span>·<span·class="n">consumer</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> | 287 | ········<span·class="k">await</span>·<span·class="n">consumer</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> |
288 | </pre></div> | 288 | </pre></div> |
289 | </div> | 289 | </div> |
290 | <p>In·this·example,·<code·class="docutils·literal·notranslate"><span·class="pre">consumer()</span></code>·is·a·coroutine·implementing·your·business | 290 | <p>In·this·example,·<code·class="docutils·literal·notranslate"><span·class="pre">consumer()</span></code>·is·a·coroutine·implementing·your·business |
291 | logic·for·processing·a·message·received·on·the·WebSocket·connection.·Each | 291 | logic·for·processing·a·message·received·on·the·WebSocket·connection.·Each |
292 | message·may·be·< | 292 | message·may·be·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>·or·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>.</p> |
293 | <p>Iteration·terminates·when·the·client·disconnects.</p> | 293 | <p>Iteration·terminates·when·the·client·disconnects.</p> |
294 | </section> | 294 | </section> |
295 | <section·id="producer"> | 295 | <section·id="producer"> |
296 | <h2>Producer<a·class="headerlink"·href="#producer"·title="Link·to·this·heading">#</a></h2> | 296 | <h2>Producer<a·class="headerlink"·href="#producer"·title="Link·to·this·heading">#</a></h2> |
297 | <p>To·send·messages·to·the·WebSocket·connection:</p> | 297 | <p>To·send·messages·to·the·WebSocket·connection:</p> |
298 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 298 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
299 | ····<span·class="k">while</span>·<span·class="kc">True</span><span·class="p">:</span> | 299 | ····<span·class="k">while</span>·<span·class="kc">True</span><span·class="p">:</span> |
300 | ········<span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">producer</span><span·class="p">()</span> | 300 | ········<span·class="n">message</span>·<span·class="o">=</span>·<span·class="k">await</span>·<span·class="n">producer</span><span·class="p">()</span> |
301 | ········<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> | 301 | ········<span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">message</span><span·class="p">)</span> |
302 | </pre></div> | 302 | </pre></div> |
303 | </div> | 303 | </div> |
304 | <p>In·this·example,·<code·class="docutils·literal·notranslate"><span·class="pre">producer()</span></code>·is·a·coroutine·implementing·your·business | 304 | <p>In·this·example,·<code·class="docutils·literal·notranslate"><span·class="pre">producer()</span></code>·is·a·coroutine·implementing·your·business |
305 | logic·for·generating·the·next·message·to·send·on·the·WebSocket·connection. | 305 | logic·for·generating·the·next·message·to·send·on·the·WebSocket·connection. |
306 | Each·message·must·be·< | 306 | Each·message·must·be·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>·or·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>.</p> |
307 | <p>Iteration·terminates·when·the·client·disconnects | 307 | <p>Iteration·terminates·when·the·client·disconnects |
308 | because·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.send"·title="websockets.server.WebSocketServerProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises·a | 308 | because·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.send"·title="websockets.server.WebSocketServerProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises·a |
309 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·exception, | 309 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·exception, |
310 | which·breaks·out·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">while</span> ·<span·class="pre">True</span></code>·loop.</p> | 310 | which·breaks·out·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">while</span> ·<span·class="pre">True</span></code>·loop.</p> |
311 | </section> | 311 | </section> |
312 | <section·id="consumer-and-producer"> | 312 | <section·id="consumer-and-producer"> |
313 | <h2>Consumer·and·producer<a·class="headerlink"·href="#consumer-and-producer"·title="Link·to·this·heading">#</a></h2> | 313 | <h2>Consumer·and·producer<a·class="headerlink"·href="#consumer-and-producer"·title="Link·to·this·heading">#</a></h2> |
Offset 317, 15 lines modified | Offset 317, 15 lines modified | ||
317 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 317 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
318 | ····<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">gather</span><span·class="p">(</span> | 318 | ····<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">gather</span><span·class="p">(</span> |
319 | ········<span·class="n">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">),</span> | 319 | ········<span·class="n">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">),</span> |
320 | ········<span·class="n">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">),</span> | 320 | ········<span·class="n">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">),</span> |
321 | ····<span·class="p">)</span> | 321 | ····<span·class="p">)</span> |
322 | </pre></div> | 322 | </pre></div> |
323 | </div> | 323 | </div> |
324 | <p>If·a·task·terminates,·< | 324 | <p>If·a·task·terminates,·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">gather()</span></code>·doesn’t·cancel·the·other·task. |
325 | This·can·result·in·a·situation·where·the·producer·keeps·running·after·the | 325 | This·can·result·in·a·situation·where·the·producer·keeps·running·after·the |
326 | consumer·finished,·which·may·leak·resources.</p> | 326 | consumer·finished,·which·may·leak·resources.</p> |
327 | <p>Here’s·a·way·to·exit·and·close·the·WebSocket·connection·as·soon·as·a·task | 327 | <p>Here’s·a·way·to·exit·and·close·the·WebSocket·connection·as·soon·as·a·task |
328 | terminates,·after·canceling·the·other·task:</p> | 328 | terminates,·after·canceling·the·other·task:</p> |
329 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 329 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
330 | ····<span·class="n">consumer_task</span>·<span·class="o">=</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">))</span> | 330 | ····<span·class="n">consumer_task</span>·<span·class="o">=</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">consumer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">))</span> |
331 | ····<span·class="n">producer_task</span>·<span·class="o">=</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">))</span> | 331 | ····<span·class="n">producer_task</span>·<span·class="o">=</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">producer_handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">))</span> |
Offset 415, 15 lines modified | Offset 415, 15 lines modified | ||
415 | certificate·signed·by·a·CA·that·your·Python·installation·trusts·—·you·can | 415 | certificate·signed·by·a·CA·that·your·Python·installation·trusts·—·you·can |
416 | simply·pass·<code·class="docutils·literal·notranslate"><span·class="pre">ssl=True</span></code>·to·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>.</p> | 416 | simply·pass·<code·class="docutils·literal·notranslate"><span·class="pre">ssl=True</span></code>·to·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>.</p> |
417 | <div·class="attention·admonition"> | 417 | <div·class="attention·admonition"> |
418 | <p·class="admonition-title">Configure·the·TLS·context·securely</p> | 418 | <p·class="admonition-title">Configure·the·TLS·context·securely</p> |
419 | <p>This·example·demonstrates·the·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·argument·with·a·TLS·certificate·shared | 419 | <p>This·example·demonstrates·the·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·argument·with·a·TLS·certificate·shared |
420 | between·the·client·and·the·server.·This·is·a·simplistic·setup.</p> | 420 | between·the·client·and·the·server.·This·is·a·simplistic·setup.</p> |
421 | <p>Please·review·the·advice·and·security·considerations·in·the·documentation·of | 421 | <p>Please·review·the·advice·and·security·considerations·in·the·documentation·of |
422 | the·< | 422 | the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">ssl</span></code>·module·to·configure·the·TLS·context·securely.</p> |
423 | </div> | 423 | </div> |
424 | </section> | 424 | </section> |
425 | <section·id="connect-from-a-browser"> | 425 | <section·id="connect-from-a-browser"> |
426 | <h2>Connect·from·a·browser<a·class="headerlink"·href="#connect-from-a-browser"·title="Link·to·this·heading">#</a></h2> | 426 | <h2>Connect·from·a·browser<a·class="headerlink"·href="#connect-from-a-browser"·title="Link·to·this·heading">#</a></h2> |
427 | <p>The·WebSocket·protocol·was·invented·for·the·web·—·as·the·name·says!</p> | 427 | <p>The·WebSocket·protocol·was·invented·for·the·web·—·as·the·name·says!</p> |
428 | <p>Here’s·how·to·connect·to·a·WebSocket·server·from·a·browser.</p> | 428 | <p>Here’s·how·to·connect·to·a·WebSocket·server·from·a·browser.</p> |
429 | <p>Run·this·script·in·a·console:</p> | 429 | <p>Run·this·script·in·a·console:</p> |
Offset 527, 15 lines modified | Offset 527, 15 lines modified | ||
527 | <p>Refresh·<code·class="docutils·literal·notranslate"><span·class="pre">show_time.html</span></code>·in·all·browsers.·Clocks·tick·in·sync.</p> | 527 | <p>Refresh·<code·class="docutils·literal·notranslate"><span·class="pre">show_time.html</span></code>·in·all·browsers.·Clocks·tick·in·sync.</p> |
528 | </section> | 528 | </section> |
529 | <section·id="manage-application-state"> | 529 | <section·id="manage-application-state"> |
530 | <h2>Manage·application·state<a·class="headerlink"·href="#manage-application-state"·title="Link·to·this·heading">#</a></h2> | 530 | <h2>Manage·application·state<a·class="headerlink"·href="#manage-application-state"·title="Link·to·this·heading">#</a></h2> |
531 | <p>A·WebSocket·server·can·receive·events·from·clients,·process·them·to·update·the | 531 | <p>A·WebSocket·server·can·receive·events·from·clients,·process·them·to·update·the |
532 | application·state,·and·broadcast·the·updated·state·to·all·connected·clients.</p> | 532 | application·state,·and·broadcast·the·updated·state·to·all·connected·clients.</p> |
533 | <p>Here’s·an·example·where·any·client·can·increment·or·decrement·a·counter.·The | 533 | <p>Here’s·an·example·where·any·client·can·increment·or·decrement·a·counter.·The |
534 | concurrency·model·of·< | 534 | concurrency·model·of·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·guarantees·that·updates·are·serialized.</p> |
535 | <p>Run·this·script·in·a·console:</p> | 535 | <p>Run·this·script·in·a·console:</p> |
536 | <div·class="literal-block-wrapper·docutils·container"·id="id9"> | 536 | <div·class="literal-block-wrapper·docutils·container"·id="id9"> |
537 | <div·class="code-block-caption"><span·class="caption-text">counter.py</span><a·class="headerlink"·href="#id9"·title="Link·to·this·code">#</a></div> | 537 | <div·class="code-block-caption"><span·class="caption-text">counter.py</span><a·class="headerlink"·href="#id9"·title="Link·to·this·code">#</a></div> |
538 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="linenos">·1</span><span·class="ch">#!/usr/bin/env·python</span> | 538 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="linenos">·1</span><span·class="ch">#!/usr/bin/env·python</span> |
539 | <span·class="linenos">·2</span> | 539 | <span·class="linenos">·2</span> |
540 | <span·class="linenos">·3</span><span·class="kn">import</span>·<span·class="nn">asyncio</span> | 540 | <span·class="linenos">·3</span><span·class="kn">import</span>·<span·class="nn">asyncio</span> |
541 | <span·class="linenos">·4</span><span·class="kn">import</span>·<span·class="nn">json</span> | 541 | <span·class="linenos">·4</span><span·class="kn">import</span>·<span·class="nn">json</span> |
Offset 286, 15 lines modified | Offset 286, 15 lines modified | ||
286 | <p>If·you’re·building·a·client,·parse·the·URI·you’d·like·to·connect·to:</p> | 286 | <p>If·you’re·building·a·client,·parse·the·URI·you’d·like·to·connect·to:</p> |
287 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">from</span>·<span·class="nn">websockets.uri</span>·<span·class="kn">import</span>·<span·class="n">parse_uri</span> | 287 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">from</span>·<span·class="nn">websockets.uri</span>·<span·class="kn">import</span>·<span·class="n">parse_uri</span> |
288 | <span·class="n">wsuri</span>·<span·class="o">=</span>·<span·class="n">parse_uri</span><span·class="p">(</span><span·class="s2">"ws://example.com/"</span><span·class="p">)</span> | 288 | <span·class="n">wsuri</span>·<span·class="o">=</span>·<span·class="n">parse_uri</span><span·class="p">(</span><span·class="s2">"ws://example.com/"</span><span·class="p">)</span> |
289 | </pre></div> | 289 | </pre></div> |
290 | </div> | 290 | </div> |
291 | <p>Open·a·TCP·connection·to·<code·class="docutils·literal·notranslate"><span·class="pre">(wsuri.host,</span>·<span·class="pre">wsuri.port)</span></code>·and·perform·a·TLS | 291 | <p>Open·a·TCP·connection·to·<code·class="docutils·literal·notranslate"><span·class="pre">(wsuri.host,</span>·<span·class="pre">wsuri.port)</span></code>·and·perform·a·TLS |
292 | handshake·if·<code·class="docutils·literal·notranslate"><span·class="pre">wsuri.secure</span></code>·is·< | 292 | handshake·if·<code·class="docutils·literal·notranslate"><span·class="pre">wsuri.secure</span></code>·is·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>.</p> |
293 | <p>Initialize·a·<a·class="reference·internal"·href="../../reference/sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientProtocol</span></code></a>:</p> | 293 | <p>Initialize·a·<a·class="reference·internal"·href="../../reference/sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientProtocol</span></code></a>:</p> |
294 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">from</span>·<span·class="nn">websockets.client</span>·<span·class="kn">import</span>·<span·class="n">ClientProtocol</span> | 294 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">from</span>·<span·class="nn">websockets.client</span>·<span·class="kn">import</span>·<span·class="n">ClientProtocol</span> |
295 | <span·class="n">protocol</span>·<span·class="o">=</span>·<span·class="n">ClientProtocol</span><span·class="p">(</span><span·class="n">wsuri</span><span·class="p">)</span> | 295 | <span·class="n">protocol</span>·<span·class="o">=</span>·<span·class="n">ClientProtocol</span><span·class="p">(</span><span·class="n">wsuri</span><span·class="p">)</span> |
296 | </pre></div> | 296 | </pre></div> |
297 | </div> | 297 | </div> |
298 | <p>Create·a·WebSocket·handshake·request | 298 | <p>Create·a·WebSocket·handshake·request |
Offset 369, 15 lines modified | Offset 369, 15 lines modified | ||
369 | <p>Go·through·the·five·steps·below·until·you·reach·the·end·of·the·data·stream.</p> | 369 | <p>Go·through·the·five·steps·below·until·you·reach·the·end·of·the·data·stream.</p> |
370 | <section·id="receive-data"> | 370 | <section·id="receive-data"> |
371 | <h3>Receive·data<a·class="headerlink"·href="#receive-data"·title="Link·to·this·heading">#</a></h3> | 371 | <h3>Receive·data<a·class="headerlink"·href="#receive-data"·title="Link·to·this·heading">#</a></h3> |
372 | <p>When·receiving·data·from·the·network,·feed·it·to·the·protocol’s | 372 | <p>When·receiving·data·from·the·network,·feed·it·to·the·protocol’s |
373 | <a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.receive_data"·title="websockets.protocol.Protocol.receive_data"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_data()</span></code></a>·method.</p> | 373 | <a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.receive_data"·title="websockets.protocol.Protocol.receive_data"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_data()</span></code></a>·method.</p> |
374 | <p>When·reaching·the·end·of·the·data·stream,·call·the·protocol’s | 374 | <p>When·reaching·the·end·of·the·data·stream,·call·the·protocol’s |
375 | <a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.receive_eof"·title="websockets.protocol.Protocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·method.</p> | 375 | <a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.receive_eof"·title="websockets.protocol.Protocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·method.</p> |
376 | <p>For·example,·if·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·is·a·< | 376 | <p>For·example,·if·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·is·a·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">socket</span></code>:</p> |
377 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">try</span><span·class="p">:</span> | 377 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">try</span><span·class="p">:</span> |
378 | ····<span·class="n">data</span>·<span·class="o">=</span>·<span·class="n">sock</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">(</span><span·class="mi">65536</span><span·class="p">)</span> | 378 | ····<span·class="n">data</span>·<span·class="o">=</span>·<span·class="n">sock</span><span·class="o">.</span><span·class="n">recv</span><span·class="p">(</span><span·class="mi">65536</span><span·class="p">)</span> |
379 | <span·class="k">except</span>·<span·class="ne">OSError</span><span·class="p">:</span>··<span·class="c1">#·socket·closed</span> | 379 | <span·class="k">except</span>·<span·class="ne">OSError</span><span·class="p">:</span>··<span·class="c1">#·socket·closed</span> |
380 | ····<span·class="n">data</span>·<span·class="o">=</span>·<span·class="sa">b</span><span·class="s2">""</span> | 380 | ····<span·class="n">data</span>·<span·class="o">=</span>·<span·class="sa">b</span><span·class="s2">""</span> |
381 | <span·class="k">if</span>·<span·class="n">data</span><span·class="p">:</span> | 381 | <span·class="k">if</span>·<span·class="n">data</span><span·class="p">:</span> |
382 | ····<span·class="n">protocol</span><span·class="o">.</span><span·class="n">receive_data</span><span·class="p">(</span><span·class="n">data</span><span·class="p">)</span> | 382 | ····<span·class="n">protocol</span><span·class="o">.</span><span·class="n">receive_data</span><span·class="p">(</span><span·class="n">data</span><span·class="p">)</span> |
383 | <span·class="k">else</span><span·class="p">:</span> | 383 | <span·class="k">else</span><span·class="p">:</span> |
Offset 408, 15 lines modified | Offset 408, 15 lines modified | ||
408 | <h3>Expect·TCP·connection·to·close<a·class="headerlink"·href="#expect-tcp-connection-to-close"·title="Link·to·this·heading">#</a></h3> | 408 | <h3>Expect·TCP·connection·to·close<a·class="headerlink"·href="#expect-tcp-connection-to-close"·title="Link·to·this·heading">#</a></h3> |
409 | <p>Closing·a·WebSocket·connection·normally·involves·a·two-way·WebSocket·closing | 409 | <p>Closing·a·WebSocket·connection·normally·involves·a·two-way·WebSocket·closing |
410 | handshake.·Then,·regardless·of·whether·the·closure·is·normal·or·abnormal,·the | 410 | handshake.·Then,·regardless·of·whether·the·closure·is·normal·or·abnormal,·the |
411 | server·starts·the·four-way·TCP·closing·handshake.·If·the·network·fails·at·the | 411 | server·starts·the·four-way·TCP·closing·handshake.·If·the·network·fails·at·the |
412 | wrong·point,·you·can·end·up·waiting·until·the·TCP·timeout,·which·is·very·long.</p> | 412 | wrong·point,·you·can·end·up·waiting·until·the·TCP·timeout,·which·is·very·long.</p> |
413 | <p>To·prevent·dangling·TCP·connections·when·you·expect·the·end·of·the·data·stream | 413 | <p>To·prevent·dangling·TCP·connections·when·you·expect·the·end·of·the·data·stream |
414 | but·you·never·reach·it,·call·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.close_expected"·title="websockets.protocol.Protocol.close_expected"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_expected()</span></code></a> | 414 | but·you·never·reach·it,·call·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.close_expected"·title="websockets.protocol.Protocol.close_expected"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_expected()</span></code></a> |
415 | and,·if·it·returns·< | 415 | and,·if·it·returns·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>,·schedule·closing·the·TCP·connection·after·a |
416 | short·timeout:</p> | 416 | short·timeout:</p> |
417 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="c1">#·start·a·new·execution·thread·to·run·this·code</span> | 417 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="c1">#·start·a·new·execution·thread·to·run·this·code</span> |
418 | <span·class="n">sleep</span><span·class="p">(</span><span·class="mi">10</span><span·class="p">)</span> | 418 | <span·class="n">sleep</span><span·class="p">(</span><span·class="mi">10</span><span·class="p">)</span> |
419 | <span·class="n">sock</span><span·class="o">.</span><span·class="n">close</span><span·class="p">()</span>··<span·class="c1">#·does·nothing·if·the·socket·is·already·closed</span> | 419 | <span·class="n">sock</span><span·class="o">.</span><span·class="n">close</span><span·class="p">()</span>··<span·class="c1">#·does·nothing·if·the·socket·is·already·closed</span> |
420 | </pre></div> | 420 | </pre></div> |
421 | </div> | 421 | </div> |
422 | <p>If·the·connection·is·still·open·when·the·timeout·elapses,·closing·the·socket | 422 | <p>If·the·connection·is·still·open·when·the·timeout·elapses,·closing·the·socket |
Offset 502, 15 lines modified | Offset 502, 15 lines modified | ||
502 | </ul> | 502 | </ul> |
503 | <p>Applying·the·rules·described·earlier·in·this·document·gives·the·intended | 503 | <p>Applying·the·rules·described·earlier·in·this·document·gives·the·intended |
504 | result.·As·a·reminder,·the·rules·are:</p> | 504 | result.·As·a·reminder,·the·rules·are:</p> |
505 | <ul·class="simple"> | 505 | <ul·class="simple"> |
506 | <li><p>When·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·returns·the·empty | 506 | <li><p>When·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·returns·the·empty |
507 | bytestring,·close·the·write·side·of·the·TCP·connection.</p></li> | 507 | bytestring,·close·the·write·side·of·the·TCP·connection.</p></li> |
508 | <li><p>When·you·reach·the·end·of·the·read·stream,·close·the·TCP·connection.</p></li> | 508 | <li><p>When·you·reach·the·end·of·the·read·stream,·close·the·TCP·connection.</p></li> |
509 | <li><p>When·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.close_expected"·title="websockets.protocol.Protocol.close_expected"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_expected()</span></code></a>·returns·< | 509 | <li><p>When·<a·class="reference·internal"·href="../../reference/sansio/common/#websockets.protocol.Protocol.close_expected"·title="websockets.protocol.Protocol.close_expected"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_expected()</span></code></a>·returns·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>,·if |
510 | you·don’t·reach·the·end·of·the·read·stream·quickly,·close·the·TCP·connection.</p></li> | 510 | you·don’t·reach·the·end·of·the·read·stream·quickly,·close·the·TCP·connection.</p></li> |
511 | </ul> | 511 | </ul> |
512 | </section> | 512 | </section> |
513 | <section·id="fragmentation"> | 513 | <section·id="fragmentation"> |
514 | <h2>Fragmentation<a·class="headerlink"·href="#fragmentation"·title="Link·to·this·heading">#</a></h2> | 514 | <h2>Fragmentation<a·class="headerlink"·href="#fragmentation"·title="Link·to·this·heading">#</a></h2> |
515 | <p>WebSocket·messages·may·be·fragmented.·Since·this·is·a·protocol-level·concern, | 515 | <p>WebSocket·messages·may·be·fragmented.·Since·this·is·a·protocol-level·concern, |
516 | you·may·choose·to·reassemble·fragmented·messages·before·handing·them·over·to | 516 | you·may·choose·to·reassemble·fragmented·messages·before·handing·them·over·to |
Offset 320, 15 lines modified | Offset 320, 15 lines modified | ||
320 | <span·class="k">if</span>·<span·class="vm">__name__</span>·<span·class="o">==</span>·<span·class="s2">"__main__"</span><span·class="p">:</span> | 320 | <span·class="k">if</span>·<span·class="vm">__name__</span>·<span·class="o">==</span>·<span·class="s2">"__main__"</span><span·class="p">:</span> |
321 | ····<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> | 321 | ····<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> |
322 | </pre></div> | 322 | </pre></div> |
323 | </div> | 323 | </div> |
324 | <p>This·is·an·echo·server·with·two·features·added·for·the·purpose·of·this·guide:</p> | 324 | <p>This·is·an·echo·server·with·two·features·added·for·the·purpose·of·this·guide:</p> |
325 | <ul·class="simple"> | 325 | <ul·class="simple"> |
326 | <li><p>It·shuts·down·gracefully·when·receiving·a·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>·signal;</p></li> | 326 | <li><p>It·shuts·down·gracefully·when·receiving·a·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>·signal;</p></li> |
327 | <li><p>It·enables·the·<code·class="docutils·literal·notranslate"><span·class="pre">reuse_port</span></code>·option·of·< | 327 | <li><p>It·enables·the·<code·class="docutils·literal·notranslate"><span·class="pre">reuse_port</span></code>·option·of·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>, |
328 | which·in·turns·sets·<code·class="docutils·literal·notranslate"><span·class="pre">SO_REUSEPORT</span></code>·on·the·accept·socket.</p></li> | 328 | which·in·turns·sets·<code·class="docutils·literal·notranslate"><span·class="pre">SO_REUSEPORT</span></code>·on·the·accept·socket.</p></li> |
329 | </ul> | 329 | </ul> |
330 | <p>Save·this·Supervisor·configuration·to·<code·class="docutils·literal·notranslate"><span·class="pre">supervisord.conf</span></code>:</p> | 330 | <p>Save·this·Supervisor·configuration·to·<code·class="docutils·literal·notranslate"><span·class="pre">supervisord.conf</span></code>:</p> |
331 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="p">[</span><span·class="n">supervisord</span><span·class="p">]</span> | 331 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="p">[</span><span·class="n">supervisord</span><span·class="p">]</span> |
332 | <span·class="p">[</span><span·class="n">program</span><span·class="p">:</span><span·class="n">websockets</span><span·class="o">-</span><span·class="n">test</span><span·class="p">]</span> | 332 | <span·class="p">[</span><span·class="n">program</span><span·class="p">:</span><span·class="n">websockets</span><span·class="o">-</span><span·class="n">test</span><span·class="p">]</span> |
333 | <span·class="n">command</span>·<span·class="o">=</span>·<span·class="n">python</span>·<span·class="n">app</span><span·class="o">.</span><span·class="n">py</span> | 333 | <span·class="n">command</span>·<span·class="o">=</span>·<span·class="n">python</span>·<span·class="n">app</span><span·class="o">.</span><span·class="n">py</span> |
Offset 273, 25 lines modified | Offset 273, 25 lines modified | ||
273 | ··········<section·id="websockets"> | 273 | ··········<section·id="websockets"> |
274 | <h1>websockets<a·class="headerlink"·href="#websockets"·title="Link·to·this·heading">#</a></h1> | 274 | <h1>websockets<a·class="headerlink"·href="#websockets"·title="Link·to·this·heading">#</a></h1> |
275 | <p><a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="licence"·src="https://img.shields.io/pypi/l/websockets.svg"·/></a>·<a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="version"·src="https://img.shields.io/pypi/v/websockets.svg"·/></a>·<a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="pyversions"·src="https://img.shields.io/pypi/pyversions/websockets.svg"·/></a>·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/actions/workflows/tests.yml"><img·alt="tests"·src="https://img.shields.io/github/checks-status/python-websockets/websockets/main?label=tests"·/></a>·<a·class="reference·external"·href="https://websockets.readthedocs.io/"><img·alt="docs"·src="https://img.shields.io/readthedocs/websockets.svg"·/></a>·<a·class="reference·external"·href="https://bestpractices.coreinfrastructure.org/projects/6475"><img·alt="openssf"·src="https://bestpractices.coreinfrastructure.org/projects/6475/badge"·/></a></p> | 275 | <p><a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="licence"·src="https://img.shields.io/pypi/l/websockets.svg"·/></a>·<a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="version"·src="https://img.shields.io/pypi/v/websockets.svg"·/></a>·<a·class="reference·external"·href="https://pypi.python.org/pypi/websockets"><img·alt="pyversions"·src="https://img.shields.io/pypi/pyversions/websockets.svg"·/></a>·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/actions/workflows/tests.yml"><img·alt="tests"·src="https://img.shields.io/github/checks-status/python-websockets/websockets/main?label=tests"·/></a>·<a·class="reference·external"·href="https://websockets.readthedocs.io/"><img·alt="docs"·src="https://img.shields.io/readthedocs/websockets.svg"·/></a>·<a·class="reference·external"·href="https://bestpractices.coreinfrastructure.org/projects/6475"><img·alt="openssf"·src="https://bestpractices.coreinfrastructure.org/projects/6475/badge"·/></a></p> |
276 | <p>websockets·is·a·library·for·building·<a·class="reference·external"·href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API">WebSocket</a>·servers·and·clients·in·Python | 276 | <p>websockets·is·a·library·for·building·<a·class="reference·external"·href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API">WebSocket</a>·servers·and·clients·in·Python |
277 | with·a·focus·on·correctness,·simplicity,·robustness,·and·performance.</p> | 277 | with·a·focus·on·correctness,·simplicity,·robustness,·and·performance.</p> |
278 | <p>It·supports·several·network·I/O·and·control·flow·paradigms:</p> | 278 | <p>It·supports·several·network·I/O·and·control·flow·paradigms:</p> |
279 | <ol·class="arabic·simple"> | 279 | <ol·class="arabic·simple"> |
280 | <li><p>The·default·implementation·builds·upon·< | 280 | <li><p>The·default·implementation·builds·upon·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>,·Python’s·standard |
281 | asynchronous·I/O·framework.·It·provides·an·elegant·coroutine-based·API.·It’s | 281 | asynchronous·I/O·framework.·It·provides·an·elegant·coroutine-based·API.·It’s |
282 | ideal·for·servers·that·handle·many·clients·concurrently.</p></li> | 282 | ideal·for·servers·that·handle·many·clients·concurrently.</p></li> |
283 | <li><p>The·<a·class="reference·external"·href="https://docs.python.org/3/library/threading.html#module-threading"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code></a>·implementation·is·a·good·alternative·for·clients, | ||
284 | 283 | <li><p>The·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·implementation·is·a·good·alternative·for·clients, | |
284 | especially·if·you·aren’t·familiar·with·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.·It·may·also·be·used | ||
285 | for·servers·that·don’t·need·to·serve·many·clients.</p></li> | 285 | for·servers·that·don’t·need·to·serve·many·clients.</p></li> |
286 | <li><p>The·<a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a>·implementation·is·designed·for·integrating·in·third-party | 286 | <li><p>The·<a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a>·implementation·is·designed·for·integrating·in·third-party |
287 | libraries,·typically·application·servers,·in·addition·being·used·internally | 287 | libraries,·typically·application·servers,·in·addition·being·used·internally |
288 | by·websockets.</p></li> | 288 | by·websockets.</p></li> |
289 | </ol> | 289 | </ol> |
290 | <p>Here’s·an·echo·server·with·the·< | 290 | <p>Here’s·an·echo·server·with·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·API:</p> |
291 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="ch">#!/usr/bin/env·python</span> | 291 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="ch">#!/usr/bin/env·python</span> |
292 | <span·class="kn">import</span>·<span·class="nn">asyncio</span> | 292 | <span·class="kn">import</span>·<span·class="nn">asyncio</span> |
293 | <span·class="kn">from</span>·<span·class="nn">websockets.server</span>·<span·class="kn">import</span>·<span·class="n">serve</span> | 293 | <span·class="kn">from</span>·<span·class="nn">websockets.server</span>·<span·class="kn">import</span>·<span·class="n">serve</span> |
294 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">echo</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 294 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">echo</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
295 | ····<span·class="k">async</span>·<span·class="k">for</span>·<span·class="n">message</span>·<span·class="ow">in</span>·<span·class="n">websocket</span><span·class="p">:</span> | 295 | ····<span·class="k">async</span>·<span·class="k">for</span>·<span·class="n">message</span>·<span·class="ow">in</span>·<span·class="n">websocket</span><span·class="p">:</span> |
Offset 300, 15 lines modified | Offset 300, 15 lines modified | ||
300 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">main</span><span·class="p">():</span> | 300 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">main</span><span·class="p">():</span> |
301 | ····<span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">serve</span><span·class="p">(</span><span·class="n">echo</span><span·class="p">,</span>·<span·class="s2">"localhost"</span><span·class="p">,</span>·<span·class="mi">8765</span><span·class="p">):</span> | 301 | ····<span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">serve</span><span·class="p">(</span><span·class="n">echo</span><span·class="p">,</span>·<span·class="s2">"localhost"</span><span·class="p">,</span>·<span·class="mi">8765</span><span·class="p">):</span> |
302 | ········<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">Future</span><span·class="p">()</span>··<span·class="c1">#·run·forever</span> | 302 | ········<span·class="k">await</span>·<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">Future</span><span·class="p">()</span>··<span·class="c1">#·run·forever</span> |
303 | <span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> | 303 | <span·class="n">asyncio</span><span·class="o">.</span><span·class="n">run</span><span·class="p">(</span><span·class="n">main</span><span·class="p">())</span> |
304 | </pre></div> | 304 | </pre></div> |
305 | </div> | 305 | </div> |
306 | <p>Here’s·how·a·client·sends·and·receives·messages·with·the·< | 306 | <p>Here’s·how·a·client·sends·and·receives·messages·with·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·API:</p> |
307 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="ch">#!/usr/bin/env·python</span> | 307 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="ch">#!/usr/bin/env·python</span> |
308 | <span·class="kn">import</span>·<span·class="nn">asyncio</span> | 308 | <span·class="kn">import</span>·<span·class="nn">asyncio</span> |
309 | <span·class="kn">from</span>·<span·class="nn">websockets.sync.client</span>·<span·class="kn">import</span>·<span·class="n">connect</span> | 309 | <span·class="kn">from</span>·<span·class="nn">websockets.sync.client</span>·<span·class="kn">import</span>·<span·class="n">connect</span> |
310 | <span·class="k">def</span>·<span·class="nf">hello</span><span·class="p">():</span> | 310 | <span·class="k">def</span>·<span·class="nf">hello</span><span·class="p">():</span> |
311 | ····<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="s2">"ws://localhost:8765"</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 311 | ····<span·class="k">with</span>·<span·class="n">connect</span><span·class="p">(</span><span·class="s2">"ws://localhost:8765"</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
Offset 296, 15 lines modified | Offset 296, 15 lines modified | ||
296 | <li><p>In·the·<a·class="reference·internal"·href="../tutorial3/"><span·class="doc">third·part</span></a>,·you·will·deploy·the·game·to·the | 296 | <li><p>In·the·<a·class="reference·internal"·href="../tutorial3/"><span·class="doc">third·part</span></a>,·you·will·deploy·the·game·to·the |
297 | web;·you·can·play·from·any·browser·connected·to·the·Internet.</p></li> | 297 | web;·you·can·play·from·any·browser·connected·to·the·Internet.</p></li> |
298 | </ul> | 298 | </ul> |
299 | </div> | 299 | </div> |
300 | <section·id="prerequisites"> | 300 | <section·id="prerequisites"> |
301 | <h2>Prerequisites<a·class="headerlink"·href="#prerequisites"·title="Link·to·this·heading">#</a></h2> | 301 | <h2>Prerequisites<a·class="headerlink"·href="#prerequisites"·title="Link·to·this·heading">#</a></h2> |
302 | <p>This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript.</p> | 302 | <p>This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript.</p> |
303 | <p>If·you’re·comfortable·with·< | 303 | <p>If·you’re·comfortable·with·<span·class="xref·std·std-doc">virtual·environments</span>, |
304 | you·can·use·one·for·this·tutorial.·Else,·don’t·worry:·websockets·doesn’t·have | 304 | you·can·use·one·for·this·tutorial.·Else,·don’t·worry:·websockets·doesn’t·have |
305 | any·dependencies;·it·shouldn’t·create·trouble·in·the·default·environment.</p> | 305 | any·dependencies;·it·shouldn’t·create·trouble·in·the·default·environment.</p> |
306 | <p>If·you·haven’t·installed·websockets·yet,·do·it·now:</p> | 306 | <p>If·you·haven’t·installed·websockets·yet,·do·it·now:</p> |
307 | <div·class="highlight-console·notranslate"><div·class="highlight"><pre><span></span><span·class="gp">$·</span>pip<span·class="w">·</span>install<span·class="w">·</span>websockets | 307 | <div·class="highlight-console·notranslate"><div·class="highlight"><pre><span></span><span·class="gp">$·</span>pip<span·class="w">·</span>install<span·class="w">·</span>websockets |
308 | </pre></div> | 308 | </pre></div> |
309 | </div> | 309 | </div> |
310 | <p>Confirm·that·websockets·is·installed:</p> | 310 | <p>Confirm·that·websockets·is·installed:</p> |
Offset 395, 15 lines modified | Offset 395, 15 lines modified | ||
395 | <li><p><strong>column</strong>·–·between·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">6</span></code>.</p></li> | 395 | <li><p><strong>column</strong>·–·between·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">6</span></code>.</p></li> |
396 | </ul> | 396 | </ul> |
397 | </dd> | 397 | </dd> |
398 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> | 398 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> |
399 | <dd·class="field-even"><p>Row·where·the·checker·lands,·between·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">5</span></code>.</p> | 399 | <dd·class="field-even"><p>Row·where·the·checker·lands,·between·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">5</span></code>.</p> |
400 | </dd> | 400 | </dd> |
401 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 401 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
402 | <dd·class="field-odd"><p>< | 402 | <dd·class="field-odd"><p><strong>RuntimeError</strong>·–·if·the·move·is·illegal.</p> |
403 | </dd> | 403 | </dd> |
404 | </dl> | 404 | </dl> |
405 | </dd></dl> | 405 | </dd></dl> |
406 | <dl·class="py·attribute"> | 406 | <dl·class="py·attribute"> |
407 | <dt·class="sig·sig-object·py"·id="connect4.Connect4.moves"> | 407 | <dt·class="sig·sig-object·py"·id="connect4.Connect4.moves"> |
408 | <span·class="sig-name·descname"><span·class="pre">moves</span></span><a·class="headerlink"·href="#connect4.Connect4.moves"·title="Link·to·this·definition">#</a></dt> | 408 | <span·class="sig-name·descname"><span·class="pre">moves</span></span><a·class="headerlink"·href="#connect4.Connect4.moves"·title="Link·to·this·definition">#</a></dt> |
Offset 411, 15 lines modified | Offset 411, 15 lines modified | ||
411 | tuples.</p> | 411 | tuples.</p> |
412 | </dd></dl> | 412 | </dd></dl> |
413 | <dl·class="py·attribute"> | 413 | <dl·class="py·attribute"> |
414 | <dt·class="sig·sig-object·py"·id="connect4.Connect4.winner"> | 414 | <dt·class="sig·sig-object·py"·id="connect4.Connect4.winner"> |
415 | <span·class="sig-name·descname"><span·class="pre">winner</span></span><a·class="headerlink"·href="#connect4.Connect4.winner"·title="Link·to·this·definition">#</a></dt> | 415 | <span·class="sig-name·descname"><span·class="pre">winner</span></span><a·class="headerlink"·href="#connect4.Connect4.winner"·title="Link·to·this·definition">#</a></dt> |
416 | <dd><p><a·class="reference·internal"·href="#id0"·title="connect4.PLAYER1"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">PLAYER1</span></code></a>·or·<a·class="reference·internal"·href="#id1"·title="connect4.PLAYER2"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">PLAYER2</span></code></a>·if·they | 416 | <dd><p><a·class="reference·internal"·href="#id0"·title="connect4.PLAYER1"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">PLAYER1</span></code></a>·or·<a·class="reference·internal"·href="#id1"·title="connect4.PLAYER2"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">PLAYER2</span></code></a>·if·they |
417 | won;·< | 417 | won;·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·if·the·game·is·still·ongoing.</p> |
418 | </dd></dl> | 418 | </dd></dl> |
419 | </dd></dl> | 419 | </dd></dl> |
420 | </section> | 420 | </section> |
421 | <section·id="bootstrap-the-web-ui"> | 421 | <section·id="bootstrap-the-web-ui"> |
422 | <h2>Bootstrap·the·web·UI<a·class="headerlink"·href="#bootstrap-the-web-ui"·title="Link·to·this·heading">#</a></h2> | 422 | <h2>Bootstrap·the·web·UI<a·class="headerlink"·href="#bootstrap-the-web-ui"·title="Link·to·this·heading">#</a></h2> |
Offset 716, 15 lines modified | Offset 716, 15 lines modified | ||
716 | it·by·modifying·the·server·to·send·some·events.</p> | 716 | it·by·modifying·the·server·to·send·some·events.</p> |
717 | <p>Sending·an·event·from·Python·is·quite·similar·to·JavaScript:</p> | 717 | <p>Sending·an·event·from·Python·is·quite·similar·to·JavaScript:</p> |
718 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="n">event</span>·<span·class="o">=</span>·<span·class="p">{</span><span·class="s2">"type"</span><span·class="p">:</span>·<span·class="s2">"play"</span><span·class="p">,</span>·<span·class="s2">"player"</span><span·class="p">:</span>·<span·class="s2">"red"</span><span·class="p">,</span>·<span·class="s2">"column"</span><span·class="p">:</span>·<span·class="mi">3</span><span·class="p">,</span>·<span·class="s2">"row"</span><span·class="p">:</span>·<span·class="mi">0</span><span·class="p">}</span> | 718 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="n">event</span>·<span·class="o">=</span>·<span·class="p">{</span><span·class="s2">"type"</span><span·class="p">:</span>·<span·class="s2">"play"</span><span·class="p">,</span>·<span·class="s2">"player"</span><span·class="p">:</span>·<span·class="s2">"red"</span><span·class="p">,</span>·<span·class="s2">"column"</span><span·class="p">:</span>·<span·class="mi">3</span><span·class="p">,</span>·<span·class="s2">"row"</span><span·class="p">:</span>·<span·class="mi">0</span><span·class="p">}</span> |
719 | <span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">json</span><span·class="o">.</span><span·class="n">dumps</span><span·class="p">(</span><span·class="n">event</span><span·class="p">))</span> | 719 | <span·class="k">await</span>·<span·class="n">websocket</span><span·class="o">.</span><span·class="n">send</span><span·class="p">(</span><span·class="n">json</span><span·class="o">.</span><span·class="n">dumps</span><span·class="p">(</span><span·class="n">event</span><span·class="p">))</span> |
720 | </pre></div> | 720 | </pre></div> |
721 | </div> | 721 | </div> |
722 | <div·class="tip·admonition"> | 722 | <div·class="tip·admonition"> |
723 | <p·class="admonition-title">Don’t·forget·to·serialize·the·event·with·< | 723 | <p·class="admonition-title">Don’t·forget·to·serialize·the·event·with·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">json.dumps()</span></code>.</p> |
724 | <p>Else,·websockets·raises·<code·class="docutils·literal·notranslate"><span·class="pre">TypeError:</span>·<span·class="pre">data</span>·<span·class="pre">is</span>·<span·class="pre">a</span>·<span·class="pre">dict-like</span>·<span·class="pre">object</span></code>.</p> | 724 | <p>Else,·websockets·raises·<code·class="docutils·literal·notranslate"><span·class="pre">TypeError:</span>·<span·class="pre">data</span>·<span·class="pre">is</span>·<span·class="pre">a</span>·<span·class="pre">dict-like</span>·<span·class="pre">object</span></code>.</p> |
725 | </div> | 725 | </div> |
726 | <p>Modify·the·<code·class="docutils·literal·notranslate"><span·class="pre">handler()</span></code>·coroutine·in·<code·class="docutils·literal·notranslate"><span·class="pre">app.py</span></code>·as·follows:</p> | 726 | <p>Modify·the·<code·class="docutils·literal·notranslate"><span·class="pre">handler()</span></code>·coroutine·in·<code·class="docutils·literal·notranslate"><span·class="pre">app.py</span></code>·as·follows:</p> |
727 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">json</span> | 727 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">json</span> |
728 | <span·class="kn">from</span>·<span·class="nn">connect4</span>·<span·class="kn">import</span>·<span·class="n">PLAYER1</span><span·class="p">,</span>·<span·class="n">PLAYER2</span> | 728 | <span·class="kn">from</span>·<span·class="nn">connect4</span>·<span·class="kn">import</span>·<span·class="n">PLAYER1</span><span·class="p">,</span>·<span·class="n">PLAYER2</span> |
Offset 774, 15 lines modified | Offset 774, 15 lines modified | ||
774 | </div> | 774 | </div> |
775 | <p>Then,·you’re·going·to·iterate·over·incoming·messages·and·take·these·steps:</p> | 775 | <p>Then,·you’re·going·to·iterate·over·incoming·messages·and·take·these·steps:</p> |
776 | <ul·class="simple"> | 776 | <ul·class="simple"> |
777 | <li><p>parse·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"play"</span></code>,·the·only·type·of·event·that·the·user | 777 | <li><p>parse·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"play"</span></code>,·the·only·type·of·event·that·the·user |
778 | interface·sends;</p></li> | 778 | interface·sends;</p></li> |
779 | <li><p>play·the·move·in·the·board·with·the·<a·class="reference·internal"·href="#connect4.Connect4.play"·title="connect4.Connect4.play"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">play()</span></code></a>·method, | 779 | <li><p>play·the·move·in·the·board·with·the·<a·class="reference·internal"·href="#connect4.Connect4.play"·title="connect4.Connect4.play"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">play()</span></code></a>·method, |
780 | alternating·between·the·two·players;</p></li> | 780 | alternating·between·the·two·players;</p></li> |
781 | <li><p>if·<a·class="reference·internal"·href="#connect4.Connect4.play"·title="connect4.Connect4.play"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">play()</span></code></a>·raises·< | 781 | <li><p>if·<a·class="reference·internal"·href="#connect4.Connect4.play"·title="connect4.Connect4.play"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">play()</span></code></a>·raises·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">RuntimeError</span></code>·because·the |
782 | move·is·illegal,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"error"</span></code>;</p></li> | 782 | move·is·illegal,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"error"</span></code>;</p></li> |
783 | <li><p>else,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"play"</span></code>·to·tell·the·user·interface·where·the | 783 | <li><p>else,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"play"</span></code>·to·tell·the·user·interface·where·the |
784 | checker·lands;</p></li> | 784 | checker·lands;</p></li> |
785 | <li><p>if·the·move·won·the·game,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"win"</span></code>.</p></li> | 785 | <li><p>if·the·move·won·the·game,·send·an·event·of·type·<code·class="docutils·literal·notranslate"><span·class="pre">"win"</span></code>.</p></li> |
786 | </ul> | 786 | </ul> |
787 | <p>Try·to·implement·this·by·yourself!</p> | 787 | <p>Try·to·implement·this·by·yourself!</p> |
788 | <p>Keep·in·mind·that·you·must·restart·the·WebSocket·server·and·reload·the·page·in | 788 | <p>Keep·in·mind·that·you·must·restart·the·WebSocket·server·and·reload·the·page·in |
Offset 116, 15 lines modified | Offset 116, 15 lines modified | ||
116 | ······can·play·if·you·share·the·same·browser. | 116 | ······can·play·if·you·share·the·same·browser. |
117 | ····*·In·the·second_part,·you·will·connect·a·second·browser;·you·can·play·from | 117 | ····*·In·the·second_part,·you·will·connect·a·second·browser;·you·can·play·from |
118 | ······different·browsers·on·a·local·network. | 118 | ······different·browsers·on·a·local·network. |
119 | ····*·In·the·third_part,·you·will·deploy·the·game·to·the·web;·you·can·play·from | 119 | ····*·In·the·third_part,·you·will·deploy·the·game·to·the·web;·you·can·play·from |
120 | ······any·browser·connected·to·the·Internet. | 120 | ······any·browser·connected·to·the·Internet. |
121 | *****·Prerequisites#·***** | 121 | *****·Prerequisites#·***** |
122 | This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript. | 122 | This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript. |
123 | If·youâre·comfortable·with·virtual | 123 | If·youâre·comfortable·with·virtual·environments,·you·can·use·one·for·this |
124 | tutorial.·Else,·donât·worry:·websockets·doesnât·have·any·dependencies;·it | 124 | tutorial.·Else,·donât·worry:·websockets·doesnât·have·any·dependencies;·it |
125 | shouldnât·create·trouble·in·the·default·environment. | 125 | shouldnât·create·trouble·in·the·default·environment. |
126 | If·you·havenât·installed·websockets·yet,·do·it·now: | 126 | If·you·havenât·installed·websockets·yet,·do·it·now: |
127 | $·pip·install·websockets | 127 | $·pip·install·websockets |
128 | Confirm·that·websockets·is·installed: | 128 | Confirm·that·websockets·is·installed: |
129 | $·python·-m·websockets·--version | 129 | $·python·-m·websockets·--version |
130 | This·tutorial·is·written·for·websockets·12.0. | 130 | This·tutorial·is·written·for·websockets·12.0. |
Offset 306, 15 lines modified | Offset 306, 15 lines modified | ||
306 | communicate·the·identifier·to·the·second·player.·When·the·second·player·joins | 306 | communicate·the·identifier·to·the·second·player.·When·the·second·player·joins |
307 | the·game,·you·look·it·up·with·the·identifier.</p> | 307 | the·game,·you·look·it·up·with·the·identifier.</p> |
308 | <p>In·addition·to·the·game·itself,·you·need·to·keep·track·of·the·WebSocket | 308 | <p>In·addition·to·the·game·itself,·you·need·to·keep·track·of·the·WebSocket |
309 | connections·of·the·two·players.·Since·both·players·receive·the·same·events, | 309 | connections·of·the·two·players.·Since·both·players·receive·the·same·events, |
310 | you·don’t·need·to·treat·the·two·connections·differently;·you·can·store·both | 310 | you·don’t·need·to·treat·the·two·connections·differently;·you·can·store·both |
311 | in·the·same·set.</p> | 311 | in·the·same·set.</p> |
312 | <p>Let’s·sketch·this·in·code.</p> | 312 | <p>Let’s·sketch·this·in·code.</p> |
313 | <p>A·module-level·< | 313 | <p>A·module-level·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">dict</span></code>·enables·lookups·by·identifier:</p> |
314 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="n">JOIN</span>·<span·class="o">=</span>·<span·class="p">{}</span> | 314 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="n">JOIN</span>·<span·class="o">=</span>·<span·class="p">{}</span> |
315 | </pre></div> | 315 | </pre></div> |
316 | </div> | 316 | </div> |
317 | <p>When·the·first·player·starts·the·game,·initialize·and·store·it:</p> | 317 | <p>When·the·first·player·starts·the·game,·initialize·and·store·it:</p> |
318 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">secrets</span> | 318 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">secrets</span> |
319 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 319 | <span·class="k">async</span>·<span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
Offset 346, 15 lines modified | Offset 346, 15 lines modified | ||
346 | ····<span·class="n">loop</span><span·class="o">.</span><span·class="n">add_signal_handler</span><span·class="p">(</span><span·class="n">signal</span><span·class="o">.</span><span·class="n">SIGTERM</span><span·class="p">,</span>·<span·class="n">stop</span><span·class="o">.</span><span·class="n">set_result</span><span·class="p">,</span>·<span·class="kc">None</span><span·class="p">)</span> | 346 | ····<span·class="n">loop</span><span·class="o">.</span><span·class="n">add_signal_handler</span><span·class="p">(</span><span·class="n">signal</span><span·class="o">.</span><span·class="n">SIGTERM</span><span·class="p">,</span>·<span·class="n">stop</span><span·class="o">.</span><span·class="n">set_result</span><span·class="p">,</span>·<span·class="kc">None</span><span·class="p">)</span> |
347 | ····<span·class="n">port</span>·<span·class="o">=</span>·<span·class="nb">int</span><span·class="p">(</span><span·class="n">os</span><span·class="o">.</span><span·class="n">environ</span><span·class="o">.</span><span·class="n">get</span><span·class="p">(</span><span·class="s2">"PORT"</span><span·class="p">,</span>·<span·class="s2">"8001"</span><span·class="p">))</span> | 347 | ····<span·class="n">port</span>·<span·class="o">=</span>·<span·class="nb">int</span><span·class="p">(</span><span·class="n">os</span><span·class="o">.</span><span·class="n">environ</span><span·class="o">.</span><span·class="n">get</span><span·class="p">(</span><span·class="s2">"PORT"</span><span·class="p">,</span>·<span·class="s2">"8001"</span><span·class="p">))</span> |
348 | ····<span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="s2">""</span><span·class="p">,</span>·<span·class="n">port</span><span·class="p">):</span> | 348 | ····<span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="s2">""</span><span·class="p">,</span>·<span·class="n">port</span><span·class="p">):</span> |
349 | ········<span·class="k">await</span>·<span·class="n">stop</span> | 349 | ········<span·class="k">await</span>·<span·class="n">stop</span> |
350 | </pre></div> | 350 | </pre></div> |
351 | </div> | 351 | </div> |
352 | <p>To·catch·the·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>·signal,·<code·class="docutils·literal·notranslate"><span·class="pre">main()</span></code>·creates·a·< | 352 | <p>To·catch·the·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>·signal,·<code·class="docutils·literal·notranslate"><span·class="pre">main()</span></code>·creates·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Future</span></code> |
353 | called·<code·class="docutils·literal·notranslate"><span·class="pre">stop</span></code>·and·registers·a·signal·handler·that·sets·the·result·of·this | 353 | called·<code·class="docutils·literal·notranslate"><span·class="pre">stop</span></code>·and·registers·a·signal·handler·that·sets·the·result·of·this |
354 | future.·The·value·of·the·future·doesn’t·matter;·it’s·only·for·waiting·for | 354 | future.·The·value·of·the·future·doesn’t·matter;·it’s·only·for·waiting·for |
355 | <code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>.</p> | 355 | <code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>.</p> |
356 | <p>Then,·by·using·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·as·a·context·manager·and·exiting·the | 356 | <p>Then,·by·using·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·as·a·context·manager·and·exiting·the |
357 | context·when·<code·class="docutils·literal·notranslate"><span·class="pre">stop</span></code>·has·a·result,·<code·class="docutils·literal·notranslate"><span·class="pre">main()</span></code>·ensures·that·the·server·closes | 357 | context·when·<code·class="docutils·literal·notranslate"><span·class="pre">stop</span></code>·has·a·result,·<code·class="docutils·literal·notranslate"><span·class="pre">main()</span></code>·ensures·that·the·server·closes |
358 | connections·cleanly·and·exits·on·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>.</p> | 358 | connections·cleanly·and·exits·on·<code·class="docutils·literal·notranslate"><span·class="pre">SIGTERM</span></code>.</p> |
359 | <p>The·app·is·now·fully·compatible·with·Heroku.</p> | 359 | <p>The·app·is·now·fully·compatible·with·Heroku.</p> |
Offset 298, 36 lines modified | Offset 298, 36 lines modified | ||
298 | </section> | 298 | </section> |
299 | <section·id="improvements"> | 299 | <section·id="improvements"> |
300 | <h3>Improvements<a·class="headerlink"·href="#improvements"·title="Link·to·this·heading">#</a></h3> | 300 | <h3>Improvements<a·class="headerlink"·href="#improvements"·title="Link·to·this·heading">#</a></h3> |
301 | <ul·class="simple"> | 301 | <ul·class="simple"> |
302 | <li><p>Made·convenience·imports·from·<code·class="docutils·literal·notranslate"><span·class="pre">websockets</span></code>·compatible·with·static·code | 302 | <li><p>Made·convenience·imports·from·<code·class="docutils·literal·notranslate"><span·class="pre">websockets</span></code>·compatible·with·static·code |
303 | analysis·tools·such·as·auto-completion·in·an·IDE·or·type·checking·with·<a·class="reference·external"·href="https://github.com/python/mypy">mypy</a>.</p> | 303 | analysis·tools·such·as·auto-completion·in·an·IDE·or·type·checking·with·<a·class="reference·external"·href="https://github.com/python/mypy">mypy</a>.</p> |
304 | </li> | 304 | </li> |
305 | <li><p>Accepted·a·plain·< | 305 | <li><p>Accepted·a·plain·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">int</span></code>·where·an·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">HTTPStatus</span></code>·is·expected.</p></li> |
306 | <li><p>Added·<a·class="reference·internal"·href="../../reference/datastructures/#websockets.frames.CloseCode"·title="websockets.frames.CloseCode"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">CloseCode</span></code></a>.</p></li> | 306 | <li><p>Added·<a·class="reference·internal"·href="../../reference/datastructures/#websockets.frames.CloseCode"·title="websockets.frames.CloseCode"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">CloseCode</span></code></a>.</p></li> |
307 | </ul> | 307 | </ul> |
308 | </section> | 308 | </section> |
309 | </section> | 309 | </section> |
310 | <section·id="id3"> | 310 | <section·id="id3"> |
311 | <h2>11.0.3<a·class="headerlink"·href="#id3"·title="Link·to·this·heading">#</a></h2> | 311 | <h2>11.0.3<a·class="headerlink"·href="#id3"·title="Link·to·this·heading">#</a></h2> |
312 | <p><em>May·7,·2023</em></p> | 312 | <p><em>May·7,·2023</em></p> |
313 | <section·id="bug-fixes"> | 313 | <section·id="bug-fixes"> |
314 | <h3>Bug·fixes<a·class="headerlink"·href="#bug-fixes"·title="Link·to·this·heading">#</a></h3> | 314 | <h3>Bug·fixes<a·class="headerlink"·href="#bug-fixes"·title="Link·to·this·heading">#</a></h3> |
315 | <ul·class="simple"> | 315 | <ul·class="simple"> |
316 | <li><p>Fixed·the·< | 316 | <li><p>Fixed·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·implementation·of·servers·on·Windows.</p></li> |
317 | </ul> | 317 | </ul> |
318 | </section> | 318 | </section> |
319 | </section> | 319 | </section> |
320 | <section·id="id4"> | 320 | <section·id="id4"> |
321 | <h2>11.0.2<a·class="headerlink"·href="#id4"·title="Link·to·this·heading">#</a></h2> | 321 | <h2>11.0.2<a·class="headerlink"·href="#id4"·title="Link·to·this·heading">#</a></h2> |
322 | <p><em>April·18,·2023</em></p> | 322 | <p><em>April·18,·2023</em></p> |
323 | <section·id="id5"> | 323 | <section·id="id5"> |
324 | <h3>Bug·fixes<a·class="headerlink"·href="#id5"·title="Link·to·this·heading">#</a></h3> | 324 | <h3>Bug·fixes<a·class="headerlink"·href="#id5"·title="Link·to·this·heading">#</a></h3> |
325 | <ul·class="simple"> | 325 | <ul·class="simple"> |
326 | <li><p>Fixed·a·deadlock·in·the·< | 326 | <li><p>Fixed·a·deadlock·in·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·implementation·when·closing·a |
327 | connection·without·reading·all·messages.</p></li> | 327 | connection·without·reading·all·messages.</p></li> |
328 | </ul> | 328 | </ul> |
329 | </section> | 329 | </section> |
330 | </section> | 330 | </section> |
331 | <section·id="id6"> | 331 | <section·id="id6"> |
332 | <h2>11.0.1<a·class="headerlink"·href="#id6"·title="Link·to·this·heading">#</a></h2> | 332 | <h2>11.0.1<a·class="headerlink"·href="#id6"·title="Link·to·this·heading">#</a></h2> |
333 | <p><em>April·6,·2023</em></p> | 333 | <p><em>April·6,·2023</em></p> |
Offset 367, 23 lines modified | Offset 367, 23 lines modified | ||
367 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>.</p> | 367 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>.</p> |
368 | <p>As·a·consequence,·calling·<code·class="docutils·literal·notranslate"><span·class="pre">WebSocket.close()</span></code>·without·arguments·in·a | 368 | <p>As·a·consequence,·calling·<code·class="docutils·literal·notranslate"><span·class="pre">WebSocket.close()</span></code>·without·arguments·in·a |
369 | browser·isn’t·reported·as·an·error·anymore.</p> | 369 | browser·isn’t·reported·as·an·error·anymore.</p> |
370 | </div> | 370 | </div> |
371 | <div·class="note·admonition"> | 371 | <div·class="note·admonition"> |
372 | <p·class="admonition-title"><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·times·out·on·the·opening·handshake·after·10·seconds·by·default.</p> | 372 | <p·class="admonition-title"><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·times·out·on·the·opening·handshake·after·10·seconds·by·default.</p> |
373 | <p>You·can·adjust·the·timeout·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·parameter.·Set·it·to | 373 | <p>You·can·adjust·the·timeout·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·parameter.·Set·it·to |
374 | < | 374 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·the·timeout·entirely.</p> |
375 | </div> | 375 | </div> |
376 | </section> | 376 | </section> |
377 | <section·id="new-features"> | 377 | <section·id="new-features"> |
378 | <h3>New·features<a·class="headerlink"·href="#new-features"·title="Link·to·this·heading">#</a></h3> | 378 | <h3>New·features<a·class="headerlink"·href="#new-features"·title="Link·to·this·heading">#</a></h3> |
379 | <div·class="important·admonition"> | 379 | <div·class="important·admonition"> |
380 | <p·class="admonition-title">websockets·11.0·introduces·a·implementation·on·top·of·< | 380 | <p·class="admonition-title">websockets·11.0·introduces·a·implementation·on·top·of·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>.</p> |
381 | <p>It·may·be·more·convenient·if·you·don’t·need·to·manage·many·connections·and | 381 | <p>It·may·be·more·convenient·if·you·don’t·need·to·manage·many·connections·and |
382 | you’re·more·comfortable·with·< | 382 | you’re·more·comfortable·with·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>·than·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.</p> |
383 | <p>It·is·particularly·suited·to·client·applications·that·establish·only·one | 383 | <p>It·is·particularly·suited·to·client·applications·that·establish·only·one |
384 | connection.·It·may·be·used·for·servers·handling·few·connections.</p> | 384 | connection.·It·may·be·used·for·servers·handling·few·connections.</p> |
385 | <p>See·<a·class="reference·internal"·href="../../reference/sync/client/#websockets.sync.client.connect"·title="websockets.sync.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/sync/server/#websockets.sync.server.serve"·title="websockets.sync.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·for·details.</p> | 385 | <p>See·<a·class="reference·internal"·href="../../reference/sync/client/#websockets.sync.client.connect"·title="websockets.sync.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/sync/server/#websockets.sync.server.serve"·title="websockets.sync.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·for·details.</p> |
386 | </div> | 386 | </div> |
387 | <ul·class="simple"> | 387 | <ul·class="simple"> |
388 | <li><p>Added·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·to·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p></li> | 388 | <li><p>Added·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·to·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p></li> |
389 | <li><p>Made·it·possible·to·close·a·server·without·closing·existing·connections.</p></li> | 389 | <li><p>Made·it·possible·to·close·a·server·without·closing·existing·connections.</p></li> |
Offset 435, 15 lines modified | Offset 435, 15 lines modified | ||
435 | <a·class="reference·internal"·href="../../reference/sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientProtocol</span></code></a>·instead.</p> | 435 | <a·class="reference·internal"·href="../../reference/sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientProtocol</span></code></a>·instead.</p> |
436 | <p>See·<a·class="reference·internal"·href="../../howto/sansio/"><span·class="doc">Integrate·the·Sans-I/O·layer</span></a>·for·details.</p> | 436 | <p>See·<a·class="reference·internal"·href="../../howto/sansio/"><span·class="doc">Integrate·the·Sans-I/O·layer</span></a>·for·details.</p> |
437 | </div> | 437 | </div> |
438 | </section> | 438 | </section> |
439 | <section·id="id16"> | 439 | <section·id="id16"> |
440 | <h3>Improvements<a·class="headerlink"·href="#id16"·title="Link·to·this·heading">#</a></h3> | 440 | <h3>Improvements<a·class="headerlink"·href="#id16"·title="Link·to·this·heading">#</a></h3> |
441 | <ul·class="simple"> | 441 | <ul·class="simple"> |
442 | <li><p>Reduced·noise·in·logs·when·< | 442 | <li><p>Reduced·noise·in·logs·when·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">ssl</span></code>·or·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">zlib</span></code>·raise·exceptions.</p></li> |
443 | </ul> | 443 | </ul> |
444 | </section> | 444 | </section> |
445 | </section> | 445 | </section> |
446 | <section·id="id17"> | 446 | <section·id="id17"> |
447 | <h2>10.2<a·class="headerlink"·href="#id17"·title="Link·to·this·heading">#</a></h2> | 447 | <h2>10.2<a·class="headerlink"·href="#id17"·title="Link·to·this·heading">#</a></h2> |
448 | <p><em>February·21,·2022</em></p> | 448 | <p><em>February·21,·2022</em></p> |
449 | <section·id="id18"> | 449 | <section·id="id18"> |
Offset 453, 15 lines modified | Offset 453, 15 lines modified | ||
453 | <li><p>Improved·FAQ·and·quick·start·guide.</p></li> | 453 | <li><p>Improved·FAQ·and·quick·start·guide.</p></li> |
454 | </ul> | 454 | </ul> |
455 | </section> | 455 | </section> |
456 | <section·id="id19"> | 456 | <section·id="id19"> |
457 | <h3>Bug·fixes<a·class="headerlink"·href="#id19"·title="Link·to·this·heading">#</a></h3> | 457 | <h3>Bug·fixes<a·class="headerlink"·href="#id19"·title="Link·to·this·heading">#</a></h3> |
458 | <ul·class="simple"> | 458 | <ul·class="simple"> |
459 | <li><p>Fixed·backwards-incompatibility·in·10.1·for·connection·handlers·created·with | 459 | <li><p>Fixed·backwards-incompatibility·in·10.1·for·connection·handlers·created·with |
460 | < | 460 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">functools.partial()</span></code>.</p></li> |
461 | <li><p>Avoided·leaking·open·sockets·when·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·is·canceled.</p></li> | 461 | <li><p>Avoided·leaking·open·sockets·when·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·is·canceled.</p></li> |
462 | </ul> | 462 | </ul> |
463 | </section> | 463 | </section> |
464 | </section> | 464 | </section> |
465 | <section·id="id20"> | 465 | <section·id="id20"> |
466 | <h2>10.1<a·class="headerlink"·href="#id20"·title="Link·to·this·heading">#</a></h2> | 466 | <h2>10.1<a·class="headerlink"·href="#id20"·title="Link·to·this·heading">#</a></h2> |
467 | <p><em>November·14,·2021</em></p> | 467 | <p><em>November·14,·2021</em></p> |
Offset 491, 15 lines modified | Offset 491, 15 lines modified | ||
491 | <section·id="id22"> | 491 | <section·id="id22"> |
492 | <h3>Improvements<a·class="headerlink"·href="#id22"·title="Link·to·this·heading">#</a></h3> | 492 | <h3>Improvements<a·class="headerlink"·href="#id22"·title="Link·to·this·heading">#</a></h3> |
493 | <ul·class="simple"> | 493 | <ul·class="simple"> |
494 | <li><p>Added·wheels·for·Python·3.10,·PyPy·3.7,·and·for·more·platforms.</p></li> | 494 | <li><p>Added·wheels·for·Python·3.10,·PyPy·3.7,·and·for·more·platforms.</p></li> |
495 | <li><p>Reverted·optimization·of·default·compression·settings·for·clients,·mainly·to | 495 | <li><p>Reverted·optimization·of·default·compression·settings·for·clients,·mainly·to |
496 | avoid·triggering·bugs·in·poorly·implemented·servers·like·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/issues/1065">AWS·API·Gateway</a>.</p> | 496 | avoid·triggering·bugs·in·poorly·implemented·servers·like·<a·class="reference·external"·href="https://github.com/python-websockets/websockets/issues/1065">AWS·API·Gateway</a>.</p> |
497 | </li> | 497 | </li> |
498 | <li><p>Mirrored·the·entire·< | 498 | <li><p>Mirrored·the·entire·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Server</span></code>·API |
499 | in·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>.</p></li> | 499 | in·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>.</p></li> |
500 | <li><p>Improved·performance·for·large·messages·on·ARM·processors.</p></li> | 500 | <li><p>Improved·performance·for·large·messages·on·ARM·processors.</p></li> |
501 | <li><p>Documented·how·to·auto-reload·on·code·changes·in·development.</p></li> | 501 | <li><p>Documented·how·to·auto-reload·on·code·changes·in·development.</p></li> |
502 | </ul> | 502 | </ul> |
503 | </section> | 503 | </section> |
504 | <section·id="id23"> | 504 | <section·id="id23"> |
505 | <h3>Bug·fixes<a·class="headerlink"·href="#id23"·title="Link·to·this·heading">#</a></h3> | 505 | <h3>Bug·fixes<a·class="headerlink"·href="#id23"·title="Link·to·this·heading">#</a></h3> |
Offset 523, 15 lines modified | Offset 523, 15 lines modified | ||
523 | Python·3.10·for·details.</p> | 523 | Python·3.10·for·details.</p> |
524 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">loop</span></code>·parameter·is·also·removed | 524 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">loop</span></code>·parameter·is·also·removed |
525 | from·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>.·This·should·be·transparent.</p> | 525 | from·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>.·This·should·be·transparent.</p> |
526 | </div> | 526 | </div> |
527 | <div·class="note·admonition"> | 527 | <div·class="note·admonition"> |
528 | <p·class="admonition-title"><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·times·out·after·10·seconds·by·default.</p> | 528 | <p·class="admonition-title"><a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·times·out·after·10·seconds·by·default.</p> |
529 | <p>You·can·adjust·the·timeout·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·parameter.·Set·it·to | 529 | <p>You·can·adjust·the·timeout·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">open_timeout</span></code>·parameter.·Set·it·to |
530 | < | 530 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·the·timeout·entirely.</p> |
531 | </div> | 531 | </div> |
532 | <div·class="note·admonition"> | 532 | <div·class="note·admonition"> |
533 | <p·class="admonition-title">The·<code·class="docutils·literal·notranslate"><span·class="pre">legacy_recv</span></code>·option·is·deprecated.</p> | 533 | <p·class="admonition-title">The·<code·class="docutils·literal·notranslate"><span·class="pre">legacy_recv</span></code>·option·is·deprecated.</p> |
534 | <p>See·the·release·notes·of·websockets·3.0·for·details.</p> | 534 | <p>See·the·release·notes·of·websockets·3.0·for·details.</p> |
535 | </div> | 535 | </div> |
536 | <div·class="note·admonition"> | 536 | <div·class="note·admonition"> |
537 | <p·class="admonition-title">The·signature·of·<a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·changed.</p> | 537 | <p·class="admonition-title">The·signature·of·<a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·changed.</p> |
Offset 668, 28 lines modified | Offset 668, 28 lines modified | ||
668 | </ul> | 668 | </ul> |
669 | </section> | 669 | </section> |
Max diff block lines reached; 24197/37640 bytes (64.29%) of diff not shown. |
Offset 295, 15 lines modified | Offset 295, 15 lines modified | ||
295 | </section> | 295 | </section> |
296 | <section·id="questions"> | 296 | <section·id="questions"> |
297 | <h2>Questions<a·class="headerlink"·href="#questions"·title="Link·to·this·heading">#</a></h2> | 297 | <h2>Questions<a·class="headerlink"·href="#questions"·title="Link·to·this·heading">#</a></h2> |
298 | <p>GitHub·issues·aren’t·a·good·medium·for·handling·questions.·There·are·better | 298 | <p>GitHub·issues·aren’t·a·good·medium·for·handling·questions.·There·are·better |
299 | places·to·ask·questions,·for·example·Stack·Overflow.</p> | 299 | places·to·ask·questions,·for·example·Stack·Overflow.</p> |
300 | <p>If·you·want·to·ask·a·question·anyway,·please·make·sure·that:</p> | 300 | <p>If·you·want·to·ask·a·question·anyway,·please·make·sure·that:</p> |
301 | <ul·class="simple"> | 301 | <ul·class="simple"> |
302 | <li><p>it’s·a·question·about·websockets·and·not·about·< | 302 | <li><p>it’s·a·question·about·websockets·and·not·about·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>;</p></li> |
303 | <li><p>it·isn’t·answered·in·the·documentation;</p></li> | 303 | <li><p>it·isn’t·answered·in·the·documentation;</p></li> |
304 | <li><p>it·wasn’t·asked·already.</p></li> | 304 | <li><p>it·wasn’t·asked·already.</p></li> |
305 | </ul> | 305 | </ul> |
306 | <p>A·good·question·can·be·written·as·a·suggestion·to·improve·the·documentation.</p> | 306 | <p>A·good·question·can·be·written·as·a·suggestion·to·improve·the·documentation.</p> |
307 | </section> | 307 | </section> |
308 | <section·id="cryptocurrency-users"> | 308 | <section·id="cryptocurrency-users"> |
309 | <h2>Cryptocurrency·users<a·class="headerlink"·href="#cryptocurrency-users"·title="Link·to·this·heading">#</a></h2> | 309 | <h2>Cryptocurrency·users<a·class="headerlink"·href="#cryptocurrency-users"·title="Link·to·this·heading">#</a></h2> |
Offset 267, 15 lines modified | Offset 267, 15 lines modified | ||
267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
270 | ··········</label> | 270 | ··········</label> |
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="module-websockets.client"> | 273 | ··········<section·id="module-websockets.client"> |
274 | <span·id="client-asyncio"></span><h1>Client·(< | 274 | <span·id="client-asyncio"></span><h1>Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)<a·class="headerlink"·href="#module-websockets.client"·title="Link·to·this·heading">#</a></h1> |
275 | <section·id="opening-a-connection"> | 275 | <section·id="opening-a-connection"> |
276 | <h2>Opening·a·connection<a·class="headerlink"·href="#opening-a-connection"·title="Link·to·this·heading">#</a></h2> | 276 | <h2>Opening·a·connection<a·class="headerlink"·href="#opening-a-connection"·title="Link·to·this·heading">#</a></h2> |
277 | <dl·class="py·function"> | 277 | <dl·class="py·function"> |
278 | <dt·class="sig·sig-object·py"·id="websockets.client.connect"> | 278 | <dt·class="sig·sig-object·py"·id="websockets.client.connect"> |
279 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.client.</span></span><span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.connect"·title="Link·to·this·definition">#</a></dt> | 279 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.client.</span></span><span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.connect"·title="Link·to·this·definition">#</a></dt> |
280 | <dd><p>Connect·to·the·WebSocket·server·at·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p> | 280 | <dd><p>Connect·to·the·WebSocket·server·at·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p> |
281 | <p>Awaiting·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·yields·a·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·which | 281 | <p>Awaiting·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·yields·a·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·which |
Offset 302, 79 lines modified | Offset 302, 79 lines modified | ||
302 | <p>If·an·error·occurs·in·the·body·of·the·loop,·you·can·handle·the·exception | 302 | <p>If·an·error·occurs·in·the·body·of·the·loop,·you·can·handle·the·exception |
303 | and·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·will·reconnect·with·the·next·iteration;·or·you·can | 303 | and·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·will·reconnect·with·the·next·iteration;·or·you·can |
304 | let·the·exception·bubble·up·and·break·out·of·the·loop.·This·lets·you | 304 | let·the·exception·bubble·up·and·break·out·of·the·loop.·This·lets·you |
305 | decide·which·errors·trigger·a·reconnection·and·which·errors·are·fatal.</p> | 305 | decide·which·errors·trigger·a·reconnection·and·which·errors·are·fatal.</p> |
306 | <dl·class="field-list·simple"> | 306 | <dl·class="field-list·simple"> |
307 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 307 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
308 | <dd·class="field-odd"><ul·class="simple"> | 308 | <dd·class="field-odd"><ul·class="simple"> |
309 | <li><p><strong>uri</strong>·(< | 309 | <li><p><strong>uri</strong>·(<em>str</em>)·–·URI·of·the·WebSocket·server.</p></li> |
310 | <li><p><strong>create_protocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>...</em><em>,·</em><a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><em>WebSocketClientProtocol</em></a><em>]</em><em>]</em>)·–·Factory·for·the·< | 310 | <li><p><strong>create_protocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>...</em><em>,·</em><a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><em>WebSocketClientProtocol</em></a><em>]</em><em>]</em>)·–·Factory·for·the·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.Protocol</span></code>·managing |
311 | the·connection.·It·defaults·to·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>. | 311 | the·connection.·It·defaults·to·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>. |
312 | Set·it·to·a·wrapper·or·a·subclass·to·customize·connection·handling.</p></li> | 312 | Set·it·to·a·wrapper·or·a·subclass·to·customize·connection·handling.</p></li> |
313 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·client. | 313 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·client. |
314 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>. | 314 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>. |
315 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 315 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
316 | <li><p><strong>compression</strong>·(<em>Optional</em><em>[</em>< | 316 | <li><p><strong>compression</strong>·(<em>Optional</em><em>[</em><em>str</em><em>]</em>)·–·The·“permessage-deflate”·extension·is·enabled·by·default. |
317 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·< | 317 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·it.·See·the |
318 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> | 318 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> |
319 | <li><p><strong>origin</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em>)·–·Value·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·servers·that·require·it.</p></li> | 319 | <li><p><strong>origin</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em>)·–·Value·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·servers·that·require·it.</p></li> |
320 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ClientExtensionFactory"·title="websockets.extensions.ClientExtensionFactory"><em>ClientExtensionFactory</em></a><em>]</em><em>]</em>)·–·List·of·supported·extensions,·in·order·in·which·they | 320 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ClientExtensionFactory"·title="websockets.extensions.ClientExtensionFactory"><em>ClientExtensionFactory</em></a><em>]</em><em>]</em>)·–·List·of·supported·extensions,·in·order·in·which·they |
321 | should·be·negotiated·and·run.</p></li> | 321 | should·be·negotiated·and·run.</p></li> |
322 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing | 322 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing |
323 | preference.</p></li> | 323 | preference.</p></li> |
324 | <li><p><strong>extra_headers</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>]</em>)·–·Arbitrary·HTTP·headers·to·add·to·the·handshake·request.</p></li> | 324 | <li><p><strong>extra_headers</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>]</em>)·–·Arbitrary·HTTP·headers·to·add·to·the·handshake·request.</p></li> |
325 | <li><p><strong>user_agent_header</strong>·(<em>Optional</em><em>[</em>< | 325 | <li><p><strong>user_agent_header</strong>·(<em>Optional</em><em>[</em><em>str</em><em>]</em>)·–·Value·of··the·<code·class="docutils·literal·notranslate"><span·class="pre">User-Agent</span></code>·request·header. |
326 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. | 326 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. |
327 | Setting·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·removes·the·header.</p></li> | ||
328 | <li><p><strong>open_timeout</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>]</em>)·–·Timeout·for·opening·the·connection·in·seconds. | ||
329 | 327 | Setting·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·removes·the·header.</p></li> | |
328 | <li><p><strong>open_timeout</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Timeout·for·opening·the·connection·in·seconds. | ||
329 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
330 | </ul> | 330 | </ul> |
331 | </dd> | 331 | </dd> |
332 | </dl> | 332 | </dl> |
333 | <p>See·<a·class="reference·internal"·href="../common/#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·for·the | 333 | <p>See·<a·class="reference·internal"·href="../common/#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·for·the |
334 | documentation·of·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>, | 334 | documentation·of·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>, |
335 | <code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>,·and·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>.</p> | 335 | <code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>,·and·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>.</p> |
336 | <p>Any·other·keyword·arguments·are·passed·the·event·loop’s | 336 | <p>Any·other·keyword·arguments·are·passed·the·event·loop’s |
337 | < | 337 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_connection()</span></code>·method.</p> |
338 | <p>For·example:</p> | 338 | <p>For·example:</p> |
339 | <ul·class="simple"> | 339 | <ul·class="simple"> |
340 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·to·a·< | 340 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·to·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">SSLContext</span></code>·to·enforce·TLS |
341 | settings.·When·connecting·to·a·<code·class="docutils·literal·notranslate"><span·class="pre">wss://</span></code>·URI,·if·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·isn’t | 341 | settings.·When·connecting·to·a·<code·class="docutils·literal·notranslate"><span·class="pre">wss://</span></code>·URI,·if·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·isn’t |
342 | provided,·a·TLS·context·is·created | 342 | provided,·a·TLS·context·is·created |
343 | with·< | 343 | with·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">create_default_context()</span></code>.</p></li> |
344 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·to·connect·to·a·different·host·and | 344 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·to·connect·to·a·different·host·and |
345 | port·from·those·found·in·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.·This·only·changes·the·destination·of | 345 | port·from·those·found·in·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.·This·only·changes·the·destination·of |
346 | the·TCP·connection.·The·host·name·from·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·is·still·used·in·the·TLS | 346 | the·TCP·connection.·The·host·name·from·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·is·still·used·in·the·TLS |
347 | handshake·for·secure·connections·and·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">Host</span></code>·header.</p></li> | 347 | handshake·for·secure·connections·and·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">Host</span></code>·header.</p></li> |
348 | </ul> | 348 | </ul> |
349 | <dl·class="field-list·simple"> | 349 | <dl·class="field-list·simple"> |
350 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 350 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
351 | <dd·class="field-odd"><ul·class="simple"> | 351 | <dd·class="field-odd"><ul·class="simple"> |
352 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidURI"·title="websockets.exceptions.InvalidURI"><strong>InvalidURI</strong></a>·–·If·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·isn’t·a·valid·WebSocket·URI.</p></li> | 352 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidURI"·title="websockets.exceptions.InvalidURI"><strong>InvalidURI</strong></a>·–·If·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·isn’t·a·valid·WebSocket·URI.</p></li> |
353 | <li><p>< | 353 | <li><p><strong>OSError</strong>·–·If·the·TCP·connection·fails.</p></li> |
354 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidHandshake"·title="websockets.exceptions.InvalidHandshake"><strong>InvalidHandshake</strong></a>·–·If·the·opening·handshake·fails.</p></li> | 354 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidHandshake"·title="websockets.exceptions.InvalidHandshake"><strong>InvalidHandshake</strong></a>·–·If·the·opening·handshake·fails.</p></li> |
355 | <li><p>< | 355 | <li><p><strong>TimeoutError</strong>·–·If·the·opening·handshake·times·out.</p></li> |
356 | </ul> | 356 | </ul> |
357 | </dd> | 357 | </dd> |
358 | </dl> | 358 | </dl> |
359 | </dd></dl> | 359 | </dd></dl> |
360 | <dl·class="py·function"> | 360 | <dl·class="py·function"> |
361 | <dt·class="sig·sig-object·py"·id="websockets.client.unix_connect"> | 361 | <dt·class="sig·sig-object·py"·id="websockets.client.unix_connect"> |
362 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.client.</span></span><span·class="sig-name·descname"><span·class="pre">unix_connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">path</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'ws://localhost/'</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.unix_connect"·title="Link·to·this·definition">#</a></dt> | 362 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.client.</span></span><span·class="sig-name·descname"><span·class="pre">unix_connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">path</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'ws://localhost/'</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.unix_connect"·title="Link·to·this·definition">#</a></dt> |
363 | <dd><p>Similar·to·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>,·but·for·connecting·to·a·Unix·socket.</p> | 363 | <dd><p>Similar·to·<a·class="reference·internal"·href="#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>,·but·for·connecting·to·a·Unix·socket.</p> |
364 | <p>This·function·builds·upon·the·event·loop’s | 364 | <p>This·function·builds·upon·the·event·loop’s |
365 | < | 365 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_unix_connection()</span></code>·method.</p> |
366 | <p>It·is·only·available·on·Unix.</p> | 366 | <p>It·is·only·available·on·Unix.</p> |
367 | <p>It’s·mainly·useful·for·debugging·servers·listening·on·Unix·sockets.</p> | 367 | <p>It’s·mainly·useful·for·debugging·servers·listening·on·Unix·sockets.</p> |
368 | <dl·class="field-list·simple"> | 368 | <dl·class="field-list·simple"> |
369 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 369 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
370 | <dd·class="field-odd"><ul·class="simple"> | 370 | <dd·class="field-odd"><ul·class="simple"> |
371 | <li><p><strong>path</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·File·system·path·to·the·Unix·socket.</p></li> | ||
372 | <li><p><strong> | 371 | <li><p><strong>path</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·File·system·path·to·the·Unix·socket.</p></li> |
372 | <li><p><strong>uri</strong>·(<em>str</em>)·–·URI·of·the·WebSocket·server;·the·host·is·used·in·the·TLS | ||
373 | handshake·for·secure·connections·and·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">Host</span></code>·header.</p></li> | 373 | handshake·for·secure·connections·and·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">Host</span></code>·header.</p></li> |
374 | </ul> | 374 | </ul> |
375 | </dd> | 375 | </dd> |
376 | </dl> | 376 | </dl> |
377 | </dd></dl> | 377 | </dd></dl> |
378 | </section> | 378 | </section> |
Offset 413, 48 lines modified | Offset 413, 48 lines modified | ||
413 | connection·closure·and | 413 | connection·closure·and |
414 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol | 414 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol |
415 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the | 415 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the |
416 | message·stream.</p> | 416 | message·stream.</p> |
417 | <p>Canceling·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·safe.·There’s·no·risk·of·losing·the·next | 417 | <p>Canceling·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·safe.·There’s·no·risk·of·losing·the·next |
418 | message.·The·next·invocation·of·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·return·it.</p> | 418 | message.·The·next·invocation·of·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·return·it.</p> |
419 | <p>This·makes·it·possible·to·enforce·a·timeout·by·wrapping·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·in | 419 | <p>This·makes·it·possible·to·enforce·a·timeout·by·wrapping·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·in |
420 | < | 420 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">timeout()</span></code>·or·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">wait_for()</span></code>.</p> |
421 | <dl·class="field-list·simple"> | 421 | <dl·class="field-list·simple"> |
422 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> | 422 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> |
423 | <dd·class="field-odd"><p><p>A·string·(< | 423 | <dd·class="field-odd"><p><p>A·string·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame.·A·bytestring |
424 | (< | 424 | (<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>·frame.</p> |
425 | </p> | 425 | </p> |
426 | </dd> | 426 | </dd> |
427 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> | 427 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> |
428 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../types/#websockets.typing.Data"·title="websockets.typing.Data">Data</a></p> | 428 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../types/#websockets.typing.Data"·title="websockets.typing.Data">Data</a></p> |
429 | </dd> | 429 | </dd> |
430 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 430 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
431 | <dd·class="field-odd"><ul·class="simple"> | 431 | <dd·class="field-odd"><ul·class="simple"> |
432 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> | 432 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> |
433 | <li><p>< | 433 | <li><p><strong>RuntimeError</strong>·–·If·two·coroutines·call·<a·class="reference·internal"·href="#websockets.client.WebSocketClientProtocol.recv"·title="websockets.client.WebSocketClientProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·concurrently.</p></li> |
434 | </ul> | 434 | </ul> |
435 | </dd> | 435 | </dd> |
436 | </dl> | 436 | </dl> |
437 | </dd></dl> | 437 | </dd></dl> |
438 | <dl·class="py·method"> | 438 | <dl·class="py·method"> |
439 | <dt·class="sig·sig-object·py"·id="websockets.client.WebSocketClientProtocol.send"> | 439 | <dt·class="sig·sig-object·py"·id="websockets.client.WebSocketClientProtocol.send"> |
Max diff block lines reached; 38207/67204 bytes (56.85%) of diff not shown. |
Offset 265, 15 lines modified | Offset 265, 15 lines modified | ||
265 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 265 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
266 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 266 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
267 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 267 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
268 | ··········</label> | 268 | ··········</label> |
269 | ········</div> | 269 | ········</div> |
270 | ········<article·role="main"> | 270 | ········<article·role="main"> |
271 | ··········<section·id="module-websockets.legacy.protocol"> | 271 | ··········<section·id="module-websockets.legacy.protocol"> |
272 | <span·id="both-sides-asyncio"></span><h1>Both·sides·(< | 272 | <span·id="both-sides-asyncio"></span><h1>Both·sides·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)<a·class="headerlink"·href="#module-websockets.legacy.protocol"·title="Link·to·this·heading">#</a></h1> |
273 | <dl·class="py·class"> | 273 | <dl·class="py·class"> |
274 | <dt·class="sig·sig-object·py"·id="websockets.legacy.protocol.WebSocketCommonProtocol"> | 274 | <dt·class="sig·sig-object·py"·id="websockets.legacy.protocol.WebSocketCommonProtocol"> |
275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.legacy.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketCommonProtocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.legacy.protocol.WebSocketCommonProtocol"·title="Link·to·this·definition">#</a></dt> | 275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.legacy.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketCommonProtocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.legacy.protocol.WebSocketCommonProtocol"·title="Link·to·this·definition">#</a></dt> |
276 | <dd><p>WebSocket·connection.</p> | 276 | <dd><p>WebSocket·connection.</p> |
277 | <p><a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·provides·APIs·shared·between·WebSocket | 277 | <p><a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·provides·APIs·shared·between·WebSocket |
278 | servers·and·clients.·You·shouldn’t·use·it·directly.·Instead,·use | 278 | servers·and·clients.·You·shouldn’t·use·it·directly.·Instead,·use |
279 | <a·class="reference·internal"·href="../client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·or | 279 | <a·class="reference·internal"·href="../client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·or |
Offset 281, 79 lines modified | Offset 281, 79 lines modified | ||
281 | <p>This·documentation·focuses·on·low-level·details·that·aren’t·covered·in·the | 281 | <p>This·documentation·focuses·on·low-level·details·that·aren’t·covered·in·the |
282 | documentation·of·<a·class="reference·internal"·href="../client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·and | 282 | documentation·of·<a·class="reference·internal"·href="../client/#websockets.client.WebSocketClientProtocol"·title="websockets.client.WebSocketClientProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketClientProtocol</span></code></a>·and |
283 | <a·class="reference·internal"·href="../server/#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>·for·the·sake·of | 283 | <a·class="reference·internal"·href="../server/#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>·for·the·sake·of |
284 | simplicity.</p> | 284 | simplicity.</p> |
285 | <p>Once·the·connection·is·open,·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2">Ping</a>·frame·is·sent·every·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code> | 285 | <p>Once·the·connection·is·open,·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2">Ping</a>·frame·is·sent·every·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code> |
286 | seconds.·This·serves·as·a·keepalive.·It·helps·keeping·the·connection·open, | 286 | seconds.·This·serves·as·a·keepalive.·It·helps·keeping·the·connection·open, |
287 | especially·in·the·presence·of·proxies·with·short·timeouts·on·inactive | 287 | especially·in·the·presence·of·proxies·with·short·timeouts·on·inactive |
288 | connections.·Set·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·to·< | 288 | connections.·Set·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·this·behavior.</p> |
289 | <p>If·the·corresponding·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3">Pong</a>·frame·isn’t·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code> | 289 | <p>If·the·corresponding·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3">Pong</a>·frame·isn’t·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code> |
290 | seconds,·the·connection·is·considered·unusable·and·is·closed·with·code·1011. | 290 | seconds,·the·connection·is·considered·unusable·and·is·closed·with·code·1011. |
291 | This·ensures·that·the·remote·endpoint·remains·responsive.·Set | 291 | This·ensures·that·the·remote·endpoint·remains·responsive.·Set |
292 | <code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·to·< | 292 | <code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·this·behavior.</p> |
293 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../../topics/timeouts/"><span·class="doc">timeouts</span></a>·for·details.</p> | 293 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../../topics/timeouts/"><span·class="doc">timeouts</span></a>·for·details.</p> |
294 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·parameter·defines·a·maximum·wait·time·for·completing | 294 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·parameter·defines·a·maximum·wait·time·for·completing |
295 | the·closing·handshake·and·terminating·the·TCP·connection.·For·legacy | 295 | the·closing·handshake·and·terminating·the·TCP·connection.·For·legacy |
296 | reasons,·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·completes·in·at·most·<code·class="docutils·literal·notranslate"><span·class="pre">5</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>·seconds | 296 | reasons,·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·completes·in·at·most·<code·class="docutils·literal·notranslate"><span·class="pre">5</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>·seconds |
297 | for·clients·and·<code·class="docutils·literal·notranslate"><span·class="pre">4</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>·for·servers.</p> | 297 | for·clients·and·<code·class="docutils·literal·notranslate"><span·class="pre">4</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>·for·servers.</p> |
298 | <p><code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·is·a·parameter·of·the·protocol·because·websockets·usually | 298 | <p><code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·is·a·parameter·of·the·protocol·because·websockets·usually |
299 | calls·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·implicitly·upon·exit:</p> | 299 | calls·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·implicitly·upon·exit:</p> |
300 | <ul·class="simple"> | 300 | <ul·class="simple"> |
301 | <li><p>on·the·client·side,·when·using·<a·class="reference·internal"·href="../client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·as·a | 301 | <li><p>on·the·client·side,·when·using·<a·class="reference·internal"·href="../client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·as·a |
302 | context·manager;</p></li> | 302 | context·manager;</p></li> |
303 | <li><p>on·the·server·side,·when·the·connection·handler·terminates.</p></li> | 303 | <li><p>on·the·server·side,·when·the·connection·handler·terminates.</p></li> |
304 | </ul> | 304 | </ul> |
305 | <p>To·apply·a·timeout·to·any·other·API,·wrap·it·in·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-task.html#asyncio.timeout"·title="(in·Python·v3.12)"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">timeout()</span></code></a>·or | ||
306 | < | 305 | <p>To·apply·a·timeout·to·any·other·API,·wrap·it·in·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">timeout()</span></code>·or |
306 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">wait_for()</span></code>.</p> | ||
307 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>·parameter·enforces·the·maximum·size·for·incoming·messages | 307 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>·parameter·enforces·the·maximum·size·for·incoming·messages |
308 | in·bytes.·The·default·value·is·1 MiB.·If·a·larger·message·is·received, | 308 | in·bytes.·The·default·value·is·1 MiB.·If·a·larger·message·is·received, |
309 | <a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·raise·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a> | 309 | <a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·raise·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a> |
310 | and·the·connection·will·be·closed·with·code·1009.</p> | 310 | and·the·connection·will·be·closed·with·code·1009.</p> |
311 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>·parameter·sets·the·maximum·length·of·the·queue·that | 311 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>·parameter·sets·the·maximum·length·of·the·queue·that |
312 | holds·incoming·messages.·The·default·value·is·<code·class="docutils·literal·notranslate"><span·class="pre">32</span></code>.·Messages·are·added | 312 | holds·incoming·messages.·The·default·value·is·<code·class="docutils·literal·notranslate"><span·class="pre">32</span></code>.·Messages·are·added |
313 | to·an·in-memory·queue·when·they’re·received;·then·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·pops·from | 313 | to·an·in-memory·queue·when·they’re·received;·then·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·pops·from |
314 | that·queue.·In·order·to·prevent·excessive·memory·consumption·when | 314 | that·queue.·In·order·to·prevent·excessive·memory·consumption·when |
315 | messages·are·received·faster·than·they·can·be·processed,·the·queue·must | 315 | messages·are·received·faster·than·they·can·be·processed,·the·queue·must |
316 | be·bounded.·If·the·queue·fills·up,·the·protocol·stops·processing·incoming | 316 | be·bounded.·If·the·queue·fills·up,·the·protocol·stops·processing·incoming |
317 | data·until·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·called.·In·this·situation,·various·receive | 317 | data·until·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·called.·In·this·situation,·various·receive |
318 | buffers·(at·least·in·< | 318 | buffers·(at·least·in·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·and·in·the·OS)·will·fill·up,·then·the |
319 | TCP·receive·window·will·shrink,·slowing·down·transmission·to·avoid·packet | 319 | TCP·receive·window·will·shrink,·slowing·down·transmission·to·avoid·packet |
320 | loss.</p> | 320 | loss.</p> |
321 | <p>Since·Python·can·use·up·to·4·bytes·of·memory·to·represent·a·single | 321 | <p>Since·Python·can·use·up·to·4·bytes·of·memory·to·represent·a·single |
322 | character,·each·connection·may·use·up·to·<code·class="docutils·literal·notranslate"><span·class="pre">4</span>·<span·class="pre">*</span>·<span·class="pre">max_size</span>·<span·class="pre">*</span>·<span·class="pre">max_queue</span></code> | 322 | character,·each·connection·may·use·up·to·<code·class="docutils·literal·notranslate"><span·class="pre">4</span>·<span·class="pre">*</span>·<span·class="pre">max_size</span>·<span·class="pre">*</span>·<span·class="pre">max_queue</span></code> |
323 | bytes·of·memory·to·store·incoming·messages.·By·default,·this·is·128 MiB. | 323 | bytes·of·memory·to·store·incoming·messages.·By·default,·this·is·128 MiB. |
324 | You·may·want·to·lower·the·limits,·depending·on·your·application’s | 324 | You·may·want·to·lower·the·limits,·depending·on·your·application’s |
325 | requirements.</p> | 325 | requirements.</p> |
326 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>·argument·sets·the·high-water·limit·of·the·buffer·for | 326 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>·argument·sets·the·high-water·limit·of·the·buffer·for |
327 | incoming·bytes.·The·low-water·limit·is·half·the·high-water·limit.·The | 327 | incoming·bytes.·The·low-water·limit·is·half·the·high-water·limit.·The |
328 | default·value·is·64 KiB,·half·of·asyncio’s·default·(based·on·the·current | 328 | default·value·is·64 KiB,·half·of·asyncio’s·default·(based·on·the·current |
329 | implementation·of·< | 329 | implementation·of·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">StreamReader</span></code>).</p> |
330 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>·argument·sets·the·high-water·limit·of·the·buffer·for | 330 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>·argument·sets·the·high-water·limit·of·the·buffer·for |
331 | outgoing·bytes.·The·low-water·limit·is·a·quarter·of·the·high-water·limit. | 331 | outgoing·bytes.·The·low-water·limit·is·a·quarter·of·the·high-water·limit. |
332 | The·default·value·is·64 KiB,·equal·to·asyncio’s·default·(based·on·the | 332 | The·default·value·is·64 KiB,·equal·to·asyncio’s·default·(based·on·the |
333 | current·implementation·of·<code·class="docutils·literal·notranslate"><span·class="pre">FlowControlMixin</span></code>).</p> | 333 | current·implementation·of·<code·class="docutils·literal·notranslate"><span·class="pre">FlowControlMixin</span></code>).</p> |
334 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../../topics/memory/"><span·class="doc">memory·usage</span></a>·for·details.</p> | 334 | <p>See·the·discussion·of·<a·class="reference·internal"·href="../../../topics/memory/"><span·class="doc">memory·usage</span></a>·for·details.</p> |
335 | <dl·class="field-list·simple"> | 335 | <dl·class="field-list·simple"> |
336 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 336 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
337 | <dd·class="field-odd"><ul·class="simple"> | 337 | <dd·class="field-odd"><ul·class="simple"> |
338 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. | 338 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. |
339 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.protocol")</span></code>. | 339 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.protocol")</span></code>. |
340 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 340 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
341 | <li><p><strong>ping_interval</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>]</em>)·–·Delay·between·keepalive·pings·in·seconds. | ||
342 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·keepalive·pings.</p></li> | ||
343 | <li><p><strong>ping_timeout</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>]</em>)·–·Timeout·for·keepalive·pings·in·seconds. | ||
344 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·timeouts.</p></li> | ||
345 | <li><p><strong> | 341 | <li><p><strong>ping_interval</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Delay·between·keepalive·pings·in·seconds. |
342 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·keepalive·pings.</p></li> | ||
343 | <li><p><strong>ping_timeout</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Timeout·for·keepalive·pings·in·seconds. | ||
344 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·timeouts.</p></li> | ||
345 | <li><p><strong>close_timeout</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Timeout·for·closing·the·connection·in·seconds. | ||
346 | For·legacy·reasons,·the·actual·timeout·is·4·or·5·times·larger.</p></li> | 346 | For·legacy·reasons,·the·actual·timeout·is·4·or·5·times·larger.</p></li> |
347 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·Maximum·size·of·incoming·messages·in·bytes. | ||
348 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·limit.</p></li> | ||
349 | <li><p><strong>max_queue</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·Maximum·number·of·incoming·messages·in·receive·buffer. | ||
350 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·limit.</p></li> | ||
351 | <li><p><strong>read_limit</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a>)·–·High-water·mark·of·read·buffer·in·bytes.</p></li> | ||
352 | <li><p><strong> | 347 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·Maximum·size·of·incoming·messages·in·bytes. |
348 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
349 | <li><p><strong>max_queue</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·Maximum·number·of·incoming·messages·in·receive·buffer. | ||
350 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
351 | <li><p><strong>read_limit</strong>·(<em>int</em>)·–·High-water·mark·of·read·buffer·in·bytes.</p></li> | ||
352 | <li><p><strong>write_limit</strong>·(<em>int</em>)·–·High-water·mark·of·write·buffer·in·bytes.</p></li> | ||
353 | </ul> | 353 | </ul> |
354 | </dd> | 354 | </dd> |
355 | </dl> | 355 | </dl> |
356 | <dl·class="py·method"> | 356 | <dl·class="py·method"> |
357 | <dt·class="sig·sig-object·py"·id="websockets.legacy.protocol.WebSocketCommonProtocol.recv"> | 357 | <dt·class="sig·sig-object·py"·id="websockets.legacy.protocol.WebSocketCommonProtocol.recv"> |
358 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-name·descname"><span·class="pre">recv</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="Link·to·this·definition">#</a></dt> | 358 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-name·descname"><span·class="pre">recv</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="Link·to·this·definition">#</a></dt> |
359 | <dd><p>Receive·the·next·message.</p> | 359 | <dd><p>Receive·the·next·message.</p> |
Offset 363, 48 lines modified | Offset 363, 48 lines modified | ||
363 | connection·closure·and | 363 | connection·closure·and |
364 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol | 364 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol |
365 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the | 365 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the |
366 | message·stream.</p> | 366 | message·stream.</p> |
367 | <p>Canceling·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·safe.·There’s·no·risk·of·losing·the·next | 367 | <p>Canceling·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·is·safe.·There’s·no·risk·of·losing·the·next |
368 | message.·The·next·invocation·of·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·return·it.</p> | 368 | message.·The·next·invocation·of·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·will·return·it.</p> |
369 | <p>This·makes·it·possible·to·enforce·a·timeout·by·wrapping·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·in | 369 | <p>This·makes·it·possible·to·enforce·a·timeout·by·wrapping·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·in |
370 | < | 370 | <code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">timeout()</span></code>·or·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">wait_for()</span></code>.</p> |
371 | <dl·class="field-list·simple"> | 371 | <dl·class="field-list·simple"> |
372 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> | 372 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> |
373 | <dd·class="field-odd"><p><p>A·string·(< | 373 | <dd·class="field-odd"><p><p>A·string·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame.·A·bytestring |
374 | (< | 374 | (<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>·frame.</p> |
375 | </p> | 375 | </p> |
376 | </dd> | 376 | </dd> |
377 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> | 377 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> |
378 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../types/#websockets.typing.Data"·title="websockets.typing.Data">Data</a></p> | 378 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../types/#websockets.typing.Data"·title="websockets.typing.Data">Data</a></p> |
379 | </dd> | 379 | </dd> |
380 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 380 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
381 | <dd·class="field-odd"><ul·class="simple"> | 381 | <dd·class="field-odd"><ul·class="simple"> |
382 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> | 382 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> |
383 | <li><p>< | 383 | <li><p><strong>RuntimeError</strong>·–·If·two·coroutines·call·<a·class="reference·internal"·href="#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·concurrently.</p></li> |
Max diff block lines reached; 40340/63853 bytes (63.18%) of diff not shown. |
Offset 267, 15 lines modified | Offset 267, 15 lines modified | ||
267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
270 | ··········</label> | 270 | ··········</label> |
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="module-websockets.server"> | 273 | ··········<section·id="module-websockets.server"> |
274 | <span·id="server-asyncio"></span><h1>Server·(< | 274 | <span·id="server-asyncio"></span><h1>Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)<a·class="headerlink"·href="#module-websockets.server"·title="Link·to·this·heading">#</a></h1> |
275 | <section·id="starting-a-server"> | 275 | <section·id="starting-a-server"> |
276 | <h2>Starting·a·server<a·class="headerlink"·href="#starting-a-server"·title="Link·to·this·heading">#</a></h2> | 276 | <h2>Starting·a·server<a·class="headerlink"·href="#starting-a-server"·title="Link·to·this·heading">#</a></h2> |
277 | <dl·class="py·function"> | 277 | <dl·class="py·function"> |
278 | <dt·class="sig·sig-object·py"·id="websockets.server.serve"> | 278 | <dt·class="sig·sig-object·py"·id="websockets.server.serve"> |
279 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">ws_handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">host</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">port</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.serve"·title="Link·to·this·definition">#</a></dt> | 279 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">ws_handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">host</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">port</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.serve"·title="Link·to·this·definition">#</a></dt> |
280 | <dd><p>Start·a·WebSocket·server·listening·on·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>.</p> | 280 | <dd><p>Start·a·WebSocket·server·listening·on·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>.</p> |
281 | <p>Whenever·a·client·connects,·the·server·creates·a | 281 | <p>Whenever·a·client·connects,·the·server·creates·a |
Offset 301, 61 lines modified | Offset 301, 61 lines modified | ||
301 | <span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">serve</span><span·class="p">(</span><span·class="o">...</span><span·class="p">):</span> | 301 | <span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">serve</span><span·class="p">(</span><span·class="o">...</span><span·class="p">):</span> |
302 | ····<span·class="k">await</span>·<span·class="n">stop</span> | 302 | ····<span·class="k">await</span>·<span·class="n">stop</span> |
303 | </pre></div> | 303 | </pre></div> |
304 | </div> | 304 | </div> |
305 | <dl·class="field-list·simple"> | 305 | <dl·class="field-list·simple"> |
306 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 306 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
307 | <dd·class="field-odd"><ul·class="simple"> | 307 | <dd·class="field-odd"><ul·class="simple"> |
308 | <li><p><strong>ws_handler</strong>·(<em>Union</em><em>[</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>]</em><em>,·</em><em>Awaitable</em><em>[</em><em>Any</em><em>]</em><em>]</em><em>,·</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>,·</em>< | 308 | <li><p><strong>ws_handler</strong>·(<em>Union</em><em>[</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>]</em><em>,·</em><em>Awaitable</em><em>[</em><em>Any</em><em>]</em><em>]</em><em>,·</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>,·</em><em>str</em><em>]</em><em>,·</em><em>Awaitable</em><em>[</em><em>Any</em><em>]</em><em>]</em><em>]</em>)·–·Connection·handler.·It·receives·the·WebSocket·connection, |
309 | which·is·a·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>,·in·argument.</p></li> | 309 | which·is·a·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>,·in·argument.</p></li> |
310 | <li><p><strong>host</strong>·(<em>Optional</em><em>[</em><em>Union</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a><em>]</em><em>]</em><em>]</em>)·–·Network·interfaces·the·server·binds·to. | ||
311 | See·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.create_server"·title="(in·Python·v3.12)"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code></a>·for·details.</p></li> | ||
312 | <li><p><strong>port</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·TCP·port·the·server·listens·on. | ||
313 | 310 | <li><p><strong>host</strong>·(<em>Optional</em><em>[</em><em>Union</em><em>[</em><em>str</em><em>,·</em><em>Sequence</em><em>[</em><em>str</em><em>]</em><em>]</em><em>]</em>)·–·Network·interfaces·the·server·binds·to. | |
311 | See·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·for·details.</p></li> | ||
312 | <li><p><strong>port</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·TCP·port·the·server·listens·on. | ||
313 | See·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·for·details.</p></li> | ||
314 | <li><p><strong>create_protocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>...</em><em>,·</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>]</em><em>]</em>)·–·Factory·for·the·< | 314 | <li><p><strong>create_protocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>...</em><em>,·</em><a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><em>WebSocketServerProtocol</em></a><em>]</em><em>]</em>)·–·Factory·for·the·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.Protocol</span></code>·managing |
315 | the·connection.·It·defaults·to·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>. | 315 | the·connection.·It·defaults·to·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol"·title="websockets.server.WebSocketServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServerProtocol</span></code></a>. |
316 | Set·it·to·a·wrapper·or·a·subclass·to·customize·connection·handling.</p></li> | 316 | Set·it·to·a·wrapper·or·a·subclass·to·customize·connection·handling.</p></li> |
317 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. | 317 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. |
318 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>. | 318 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>. |
319 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 319 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
320 | <li><p><strong>compression</strong>·(<em>Optional</em><em>[</em>< | 320 | <li><p><strong>compression</strong>·(<em>Optional</em><em>[</em><em>str</em><em>]</em>)·–·The·“permessage-deflate”·extension·is·enabled·by·default. |
321 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·< | 321 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·it.·See·the |
322 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> | 322 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> |
323 | <li><p><strong>origins</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em><em>]</em><em>]</em>)·–·Acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·defending | 323 | <li><p><strong>origins</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em><em>]</em><em>]</em>)·–·Acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·defending |
324 | against·Cross-Site·WebSocket·Hijacking·attacks.·Include·< | 324 | against·Cross-Site·WebSocket·Hijacking·attacks.·Include·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code> |
325 | in·the·list·if·the·lack·of·an·origin·is·acceptable.</p></li> | 325 | in·the·list·if·the·lack·of·an·origin·is·acceptable.</p></li> |
326 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ServerExtensionFactory"·title="websockets.extensions.ServerExtensionFactory"><em>ServerExtensionFactory</em></a><em>]</em><em>]</em>)·–·List·of·supported·extensions,·in·order·in·which·they | 326 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ServerExtensionFactory"·title="websockets.extensions.ServerExtensionFactory"><em>ServerExtensionFactory</em></a><em>]</em><em>]</em>)·–·List·of·supported·extensions,·in·order·in·which·they |
327 | should·be·negotiated·and·run.</p></li> | 327 | should·be·negotiated·and·run.</p></li> |
328 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing | 328 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing |
329 | preference.</p></li> | 329 | preference.</p></li> |
330 | <li><p><strong>extra_headers</strong>·(<em>Union</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>,·</em><em>Callable</em><em>[</em><em>[</em>< | 330 | <li><p><strong>extra_headers</strong>·(<em>Union</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>,·</em><em>Callable</em><em>[</em><em>[</em><em>str</em><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><em>Headers</em></a><em>]</em><em>,·</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>]</em><em>]</em>)·–·Arbitrary·HTTP·headers·to·add·to·the·response.·This·can·be |
331 | a·<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">HeadersLike</span></code></a>·or·a·callable | 331 | a·<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">HeadersLike</span></code></a>·or·a·callable |
332 | taking·the·request·path·and·headers·in·arguments·and·returning | 332 | taking·the·request·path·and·headers·in·arguments·and·returning |
333 | a·<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">HeadersLike</span></code></a>.</p></li> | 333 | a·<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">HeadersLike</span></code></a>.</p></li> |
334 | <li><p><strong>server_header</strong>·(<em>Optional</em><em>[</em>< | 334 | <li><p><strong>server_header</strong>·(<em>Optional</em><em>[</em><em>str</em><em>]</em>)·–·Value·of··the·<code·class="docutils·literal·notranslate"><span·class="pre">Server</span></code>·response·header. |
335 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. | 335 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. |
336 | Setting·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·removes·the·header.</p></li> | ||
337 | 336 | Setting·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·removes·the·header.</p></li> | |
337 | <li><p><strong>process_request</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>[</em><em>str</em><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><em>Headers</em></a><em>]</em><em>,·············</em><em>Awaitable</em><em>[</em><em>Optional</em><em>[</em><em>Tuple</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.StatusLike"·title="websockets.typing.StatusLike"><em>StatusLike</em></a><em>,·</em><a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>,·</em><em>bytes</em><em>]</em><em>]</em><em>]</em><em>]</em><em>]</em>)·–·Intercept·HTTP·request·before·the·opening·handshake. | ||
338 | See·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol.process_request"·title="websockets.server.WebSocketServerProtocol.process_request"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">process_request()</span></code></a>·for·details.</p></li> | 338 | See·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol.process_request"·title="websockets.server.WebSocketServerProtocol.process_request"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">process_request()</span></code></a>·for·details.</p></li> |
339 | <li><p><strong>select_subprotocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>,·</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·Select·a·subprotocol·supported·by·the·client. | 339 | <li><p><strong>select_subprotocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>,·</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·Select·a·subprotocol·supported·by·the·client. |
340 | See·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol.select_subprotocol"·title="websockets.server.WebSocketServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">select_subprotocol()</span></code></a>·for·details.</p></li> | 340 | See·<a·class="reference·internal"·href="#websockets.server.WebSocketServerProtocol.select_subprotocol"·title="websockets.server.WebSocketServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">select_subprotocol()</span></code></a>·for·details.</p></li> |
341 | <li><p><strong>open_timeout</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>]</em>)·–·Timeout·for·opening·connections·in·seconds. | ||
342 | < | 341 | <li><p><strong>open_timeout</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Timeout·for·opening·connections·in·seconds. |
342 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
343 | </ul> | 343 | </ul> |
344 | </dd> | 344 | </dd> |
345 | </dl> | 345 | </dl> |
346 | <p>See·<a·class="reference·internal"·href="../common/#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·for·the | 346 | <p>See·<a·class="reference·internal"·href="../common/#websockets.legacy.protocol.WebSocketCommonProtocol"·title="websockets.legacy.protocol.WebSocketCommonProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketCommonProtocol</span></code></a>·for·the |
347 | documentation·of·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>, | 347 | documentation·of·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>, |
348 | <code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>,·and·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>.</p> | 348 | <code·class="docutils·literal·notranslate"><span·class="pre">max_size</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">max_queue</span></code>,·<code·class="docutils·literal·notranslate"><span·class="pre">read_limit</span></code>,·and·<code·class="docutils·literal·notranslate"><span·class="pre">write_limit</span></code>.</p> |
349 | <p>Any·other·keyword·arguments·are·passed·the·event·loop’s | 349 | <p>Any·other·keyword·arguments·are·passed·the·event·loop’s |
350 | < | 350 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·method.</p> |
351 | <p>For·example:</p> | 351 | <p>For·example:</p> |
352 | <ul·class="simple"> | 352 | <ul·class="simple"> |
353 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·to·a·< | 353 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">ssl</span></code>·to·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">SSLContext</span></code>·to·enable·TLS.</p></li> |
354 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·to·a·< | 354 | <li><p>You·can·set·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·to·a·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">socket</span></code>·that·you·created |
355 | outside·of·websockets.</p></li> | 355 | outside·of·websockets.</p></li> |
356 | </ul> | 356 | </ul> |
357 | <dl·class="field-list·simple"> | 357 | <dl·class="field-list·simple"> |
358 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> | 358 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> |
359 | <dd·class="field-odd"><p>WebSocket·server.</p> | 359 | <dd·class="field-odd"><p>WebSocket·server.</p> |
360 | </dd> | 360 | </dd> |
361 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> | 361 | <dt·class="field-even">Return·type<span·class="colon">:</span></dt> |
Offset 367, 49 lines modified | Offset 367, 49 lines modified | ||
367 | <dl·class="py·function"> | 367 | <dl·class="py·function"> |
368 | <dt·class="sig·sig-object·py"·id="websockets.server.unix_serve"> | 368 | <dt·class="sig·sig-object·py"·id="websockets.server.unix_serve"> |
369 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">unix_serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">ws_handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">path</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.unix_serve"·title="Link·to·this·definition">#</a></dt> | 369 | <em·class="property"><span·class="pre">await</span>·</em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">unix_serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">ws_handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">path</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_protocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extra_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_interval</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ping_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_queue</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**5</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">read_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">write_limit</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**16</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">**</span></span><span·class="n"><span·class="pre">kwds</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.unix_serve"·title="Link·to·this·definition">#</a></dt> |
370 | <dd><p>Start·a·WebSocket·server·listening·on·a·Unix·socket.</p> | 370 | <dd><p>Start·a·WebSocket·server·listening·on·a·Unix·socket.</p> |
371 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>,·except·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and | 371 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>,·except·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and |
372 | <code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·arguments·are·replaced·by·<code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>.·It·is·only·available·on·Unix.</p> | 372 | <code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·arguments·are·replaced·by·<code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>.·It·is·only·available·on·Unix.</p> |
373 | <p>Unrecognized·keyword·arguments·are·passed·the·event·loop’s | 373 | <p>Unrecognized·keyword·arguments·are·passed·the·event·loop’s |
374 | < | 374 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">create_unix_server()</span></code>·method.</p> |
375 | <p>It’s·useful·for·deploying·a·server·behind·a·reverse·proxy·such·as·nginx.</p> | 375 | <p>It’s·useful·for·deploying·a·server·behind·a·reverse·proxy·such·as·nginx.</p> |
376 | <dl·class="field-list·simple"> | 376 | <dl·class="field-list·simple"> |
377 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 377 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
378 | <dd·class="field-odd"><p><strong>path</strong>·(< | 378 | <dd·class="field-odd"><p><strong>path</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·File·system·path·to·the·Unix·socket.</p> |
379 | </dd> | 379 | </dd> |
380 | </dl> | 380 | </dl> |
381 | </dd></dl> | 381 | </dd></dl> |
382 | </section> | 382 | </section> |
383 | <section·id="stopping-a-server"> | 383 | <section·id="stopping-a-server"> |
384 | <h2>Stopping·a·server<a·class="headerlink"·href="#stopping-a-server"·title="Link·to·this·heading">#</a></h2> | 384 | <h2>Stopping·a·server<a·class="headerlink"·href="#stopping-a-server"·title="Link·to·this·heading">#</a></h2> |
385 | <dl·class="py·class"> | 385 | <dl·class="py·class"> |
386 | <dt·class="sig·sig-object·py"·id="websockets.server.WebSocketServer"> | 386 | <dt·class="sig·sig-object·py"·id="websockets.server.WebSocketServer"> |
387 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketServer</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.WebSocketServer"·title="Link·to·this·definition">#</a></dt> | 387 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketServer</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.WebSocketServer"·title="Link·to·this·definition">#</a></dt> |
388 | <dd><p>WebSocket·server·returned·by·<a·class="reference·internal"·href="#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> | 388 | <dd><p>WebSocket·server·returned·by·<a·class="reference·internal"·href="#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.</p> |
389 | <p>This·class·provides·the·same·interface·as·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.Server"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Server</span></code></a>, | ||
390 | notably·the·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.Server.close"·title="(in·Python·v3.12)"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a> | ||
391 | 389 | <p>This·class·provides·the·same·interface·as·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Server</span></code>, | |
390 | notably·the·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code> | ||
391 | and·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">wait_closed()</span></code>·methods.</p> | ||
392 | <p>It·keeps·track·of·WebSocket·connections·in·order·to·close·them·properly | 392 | <p>It·keeps·track·of·WebSocket·connections·in·order·to·close·them·properly |
393 | when·shutting·down.</p> | 393 | when·shutting·down.</p> |
394 | <dl·class="field-list·simple"> | 394 | <dl·class="field-list·simple"> |
395 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 395 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
396 | <dd·class="field-odd"><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. | 396 | <dd·class="field-odd"><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·Logger·for·this·server. |
397 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>. | 397 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>. |
398 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p> | 398 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p> |
399 | </dd> | 399 | </dd> |
400 | </dl> | 400 | </dl> |
401 | <dl·class="py·method"> | 401 | <dl·class="py·method"> |
402 | <dt·class="sig·sig-object·py"·id="websockets.server.WebSocketServer.close"> | 402 | <dt·class="sig·sig-object·py"·id="websockets.server.WebSocketServer.close"> |
403 | <span·class="sig-name·descname"><span·class="pre">close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">close_connections</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.WebSocketServer.close"·title="Link·to·this·definition">#</a></dt> | 403 | <span·class="sig-name·descname"><span·class="pre">close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">close_connections</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.WebSocketServer.close"·title="Link·to·this·definition">#</a></dt> |
404 | <dd><p>Close·the·server.</p> | 404 | <dd><p>Close·the·server.</p> |
405 | <ul·class="simple"> | 405 | <ul·class="simple"> |
406 | <li><p>Close·the·underlying·< | 406 | <li><p>Close·the·underlying·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Server</span></code>.</p></li> |
407 | <li><p>When·<code·class="docutils·literal·notranslate"><span·class="pre">close_connections</span></code>·is·< | 407 | <li><p>When·<code·class="docutils·literal·notranslate"><span·class="pre">close_connections</span></code>·is·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>,·which·is·the·default, |
Max diff block lines reached; 78574/114374 bytes (68.70%) of diff not shown. |
Offset 293, 59 lines modified | Offset 293, 59 lines modified | ||
293 | <dl·class="py·attribute"> | 293 | <dl·class="py·attribute"> |
294 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.data"> | 294 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.data"> |
295 | <span·class="sig-name·descname"><span·class="pre">data</span></span><a·class="headerlink"·href="#websockets.frames.Frame.data"·title="Link·to·this·definition">#</a></dt> | 295 | <span·class="sig-name·descname"><span·class="pre">data</span></span><a·class="headerlink"·href="#websockets.frames.Frame.data"·title="Link·to·this·definition">#</a></dt> |
296 | <dd><p>Payload·data.</p> | 296 | <dd><p>Payload·data.</p> |
297 | <dl·class="field-list·simple"> | 297 | <dl·class="field-list·simple"> |
298 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 298 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
299 | <dd·class="field-odd"><p> | 299 | <dd·class="field-odd"><p>bytes</p> |
300 | </dd> | 300 | </dd> |
301 | </dl> | 301 | </dl> |
302 | </dd></dl> | 302 | </dd></dl> |
303 | <dl·class="py·attribute"> | 303 | <dl·class="py·attribute"> |
304 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.fin"> | 304 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.fin"> |
305 | <span·class="sig-name·descname"><span·class="pre">fin</span></span><a·class="headerlink"·href="#websockets.frames.Frame.fin"·title="Link·to·this·definition">#</a></dt> | 305 | <span·class="sig-name·descname"><span·class="pre">fin</span></span><a·class="headerlink"·href="#websockets.frames.Frame.fin"·title="Link·to·this·definition">#</a></dt> |
306 | <dd><p>FIN·bit.</p> | 306 | <dd><p>FIN·bit.</p> |
307 | <dl·class="field-list·simple"> | 307 | <dl·class="field-list·simple"> |
308 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 308 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
309 | <dd·class="field-odd"><p> | 309 | <dd·class="field-odd"><p>bool</p> |
310 | </dd> | 310 | </dd> |
311 | </dl> | 311 | </dl> |
312 | </dd></dl> | 312 | </dd></dl> |
313 | <dl·class="py·attribute"> | 313 | <dl·class="py·attribute"> |
314 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv1"> | 314 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv1"> |
315 | <span·class="sig-name·descname"><span·class="pre">rsv1</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv1"·title="Link·to·this·definition">#</a></dt> | 315 | <span·class="sig-name·descname"><span·class="pre">rsv1</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv1"·title="Link·to·this·definition">#</a></dt> |
316 | <dd><p>RSV1·bit.</p> | 316 | <dd><p>RSV1·bit.</p> |
317 | <dl·class="field-list·simple"> | 317 | <dl·class="field-list·simple"> |
318 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 318 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
319 | <dd·class="field-odd"><p> | 319 | <dd·class="field-odd"><p>bool</p> |
320 | </dd> | 320 | </dd> |
321 | </dl> | 321 | </dl> |
322 | </dd></dl> | 322 | </dd></dl> |
323 | <dl·class="py·attribute"> | 323 | <dl·class="py·attribute"> |
324 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv2"> | 324 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv2"> |
325 | <span·class="sig-name·descname"><span·class="pre">rsv2</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv2"·title="Link·to·this·definition">#</a></dt> | 325 | <span·class="sig-name·descname"><span·class="pre">rsv2</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv2"·title="Link·to·this·definition">#</a></dt> |
326 | <dd><p>RSV2·bit.</p> | 326 | <dd><p>RSV2·bit.</p> |
327 | <dl·class="field-list·simple"> | 327 | <dl·class="field-list·simple"> |
328 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 328 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
329 | <dd·class="field-odd"><p> | 329 | <dd·class="field-odd"><p>bool</p> |
330 | </dd> | 330 | </dd> |
331 | </dl> | 331 | </dl> |
332 | </dd></dl> | 332 | </dd></dl> |
333 | <dl·class="py·attribute"> | 333 | <dl·class="py·attribute"> |
334 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv3"> | 334 | <dt·class="sig·sig-object·py"·id="websockets.frames.Frame.rsv3"> |
335 | <span·class="sig-name·descname"><span·class="pre">rsv3</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv3"·title="Link·to·this·definition">#</a></dt> | 335 | <span·class="sig-name·descname"><span·class="pre">rsv3</span></span><a·class="headerlink"·href="#websockets.frames.Frame.rsv3"·title="Link·to·this·definition">#</a></dt> |
336 | <dd><p>RSV3·bit.</p> | 336 | <dd><p>RSV3·bit.</p> |
337 | <dl·class="field-list·simple"> | 337 | <dl·class="field-list·simple"> |
338 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 338 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
339 | <dd·class="field-odd"><p> | 339 | <dd·class="field-odd"><p>bool</p> |
340 | </dd> | 340 | </dd> |
341 | </dl> | 341 | </dl> |
342 | </dd></dl> | 342 | </dd></dl> |
343 | <p>Only·these·fields·are·needed.·The·MASK·bit,·payload·length·and·masking-key | 343 | <p>Only·these·fields·are·needed.·The·MASK·bit,·payload·length·and·masking-key |
344 | are·handled·on·the·fly·when·parsing·and·serializing·frames.</p> | 344 | are·handled·on·the·fly·when·parsing·and·serializing·frames.</p> |
345 | </dd></dl> | 345 | </dd></dl> |
Offset 394, 26 lines modified | Offset 394, 26 lines modified | ||
394 | </dl> | 394 | </dl> |
395 | <dl·class="py·attribute"> | 395 | <dl·class="py·attribute"> |
396 | <dt·class="sig·sig-object·py"·id="websockets.frames.Close.code"> | 396 | <dt·class="sig·sig-object·py"·id="websockets.frames.Close.code"> |
397 | <span·class="sig-name·descname"><span·class="pre">code</span></span><a·class="headerlink"·href="#websockets.frames.Close.code"·title="Link·to·this·definition">#</a></dt> | 397 | <span·class="sig-name·descname"><span·class="pre">code</span></span><a·class="headerlink"·href="#websockets.frames.Close.code"·title="Link·to·this·definition">#</a></dt> |
398 | <dd><p>Close·code.</p> | 398 | <dd><p>Close·code.</p> |
399 | <dl·class="field-list·simple"> | 399 | <dl·class="field-list·simple"> |
400 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 400 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
401 | <dd·class="field-odd"><p> | 401 | <dd·class="field-odd"><p>int</p> |
402 | </dd> | 402 | </dd> |
403 | </dl> | 403 | </dl> |
404 | </dd></dl> | 404 | </dd></dl> |
405 | <dl·class="py·attribute"> | 405 | <dl·class="py·attribute"> |
406 | <dt·class="sig·sig-object·py"·id="websockets.frames.Close.reason"> | 406 | <dt·class="sig·sig-object·py"·id="websockets.frames.Close.reason"> |
407 | <span·class="sig-name·descname"><span·class="pre">reason</span></span><a·class="headerlink"·href="#websockets.frames.Close.reason"·title="Link·to·this·definition">#</a></dt> | 407 | <span·class="sig-name·descname"><span·class="pre">reason</span></span><a·class="headerlink"·href="#websockets.frames.Close.reason"·title="Link·to·this·definition">#</a></dt> |
408 | <dd><p>Close·reason.</p> | 408 | <dd><p>Close·reason.</p> |
409 | <dl·class="field-list·simple"> | 409 | <dl·class="field-list·simple"> |
410 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 410 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
411 | <dd·class="field-odd"><p> | 411 | <dd·class="field-odd"><p>str</p> |
412 | </dd> | 412 | </dd> |
413 | </dl> | 413 | </dl> |
414 | </dd></dl> | 414 | </dd></dl> |
415 | </dd></dl> | 415 | </dd></dl> |
416 | <dl·class="py·class"> | 416 | <dl·class="py·class"> |
Offset 508, 15 lines modified | Offset 508, 15 lines modified | ||
508 | </dl> | 508 | </dl> |
509 | <dl·class="py·attribute"> | 509 | <dl·class="py·attribute"> |
510 | <dt·class="sig·sig-object·py"·id="websockets.http11.Request.path"> | 510 | <dt·class="sig·sig-object·py"·id="websockets.http11.Request.path"> |
511 | <span·class="sig-name·descname"><span·class="pre">path</span></span><a·class="headerlink"·href="#websockets.http11.Request.path"·title="Link·to·this·definition">#</a></dt> | 511 | <span·class="sig-name·descname"><span·class="pre">path</span></span><a·class="headerlink"·href="#websockets.http11.Request.path"·title="Link·to·this·definition">#</a></dt> |
512 | <dd><p>Request·path,·including·optional·query.</p> | 512 | <dd><p>Request·path,·including·optional·query.</p> |
513 | <dl·class="field-list·simple"> | 513 | <dl·class="field-list·simple"> |
514 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 514 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
515 | <dd·class="field-odd"><p> | 515 | <dd·class="field-odd"><p>str</p> |
516 | </dd> | 516 | </dd> |
517 | </dl> | 517 | </dl> |
518 | </dd></dl> | 518 | </dd></dl> |
519 | <dl·class="py·attribute"> | 519 | <dl·class="py·attribute"> |
520 | <dt·class="sig·sig-object·py"·id="websockets.http11.Request.headers"> | 520 | <dt·class="sig·sig-object·py"·id="websockets.http11.Request.headers"> |
521 | <span·class="sig-name·descname"><span·class="pre">headers</span></span><a·class="headerlink"·href="#websockets.http11.Request.headers"·title="Link·to·this·definition">#</a></dt> | 521 | <span·class="sig-name·descname"><span·class="pre">headers</span></span><a·class="headerlink"·href="#websockets.http11.Request.headers"·title="Link·to·this·definition">#</a></dt> |
Offset 538, 26 lines modified | Offset 538, 26 lines modified | ||
538 | </dl> | 538 | </dl> |
539 | <dl·class="py·attribute"> | 539 | <dl·class="py·attribute"> |
540 | <dt·class="sig·sig-object·py"·id="websockets.http11.Response.status_code"> | 540 | <dt·class="sig·sig-object·py"·id="websockets.http11.Response.status_code"> |
541 | <span·class="sig-name·descname"><span·class="pre">status_code</span></span><a·class="headerlink"·href="#websockets.http11.Response.status_code"·title="Link·to·this·definition">#</a></dt> | 541 | <span·class="sig-name·descname"><span·class="pre">status_code</span></span><a·class="headerlink"·href="#websockets.http11.Response.status_code"·title="Link·to·this·definition">#</a></dt> |
542 | <dd><p>Response·code.</p> | 542 | <dd><p>Response·code.</p> |
543 | <dl·class="field-list·simple"> | 543 | <dl·class="field-list·simple"> |
544 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 544 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
545 | <dd·class="field-odd"><p> | 545 | <dd·class="field-odd"><p>int</p> |
546 | </dd> | 546 | </dd> |
547 | </dl> | 547 | </dl> |
548 | </dd></dl> | 548 | </dd></dl> |
549 | <dl·class="py·attribute"> | 549 | <dl·class="py·attribute"> |
550 | <dt·class="sig·sig-object·py"·id="websockets.http11.Response.reason_phrase"> | 550 | <dt·class="sig·sig-object·py"·id="websockets.http11.Response.reason_phrase"> |
551 | <span·class="sig-name·descname"><span·class="pre">reason_phrase</span></span><a·class="headerlink"·href="#websockets.http11.Response.reason_phrase"·title="Link·to·this·definition">#</a></dt> | 551 | <span·class="sig-name·descname"><span·class="pre">reason_phrase</span></span><a·class="headerlink"·href="#websockets.http11.Response.reason_phrase"·title="Link·to·this·definition">#</a></dt> |
552 | <dd><p>Response·reason.</p> | 552 | <dd><p>Response·reason.</p> |
553 | <dl·class="field-list·simple"> | 553 | <dl·class="field-list·simple"> |
554 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 554 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
555 | <dd·class="field-odd"><p> | 555 | <dd·class="field-odd"><p>str</p> |
556 | </dd> | 556 | </dd> |
557 | </dl> | 557 | </dl> |
558 | </dd></dl> | 558 | </dd></dl> |
559 | <dl·class="py·attribute"> | 559 | <dl·class="py·attribute"> |
Max diff block lines reached; 16682/23444 bytes (71.16%) of diff not shown. |
Offset 335, 15 lines modified | Offset 335, 15 lines modified | ||
335 | </dl> | 335 | </dl> |
336 | <dl·class="py·attribute"> | 336 | <dl·class="py·attribute"> |
337 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.status"> | 337 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.status"> |
338 | <span·class="sig-name·descname"><span·class="pre">status</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.status"·title="Link·to·this·definition">#</a></dt> | 338 | <span·class="sig-name·descname"><span·class="pre">status</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.status"·title="Link·to·this·definition">#</a></dt> |
339 | <dd><p>HTTP·status·code.</p> | 339 | <dd><p>HTTP·status·code.</p> |
340 | <dl·class="field-list·simple"> | 340 | <dl·class="field-list·simple"> |
341 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 341 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
342 | <dd·class="field-odd"><p>< | 342 | <dd·class="field-odd"><p><em>HTTPStatus</em></p> |
343 | </dd> | 343 | </dd> |
344 | </dl> | 344 | </dl> |
345 | </dd></dl> | 345 | </dd></dl> |
346 | <dl·class="py·attribute"> | 346 | <dl·class="py·attribute"> |
347 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.headers"> | 347 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.headers"> |
348 | <span·class="sig-name·descname"><span·class="pre">headers</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.headers"·title="Link·to·this·definition">#</a></dt> | 348 | <span·class="sig-name·descname"><span·class="pre">headers</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.headers"·title="Link·to·this·definition">#</a></dt> |
Offset 357, 15 lines modified | Offset 357, 15 lines modified | ||
357 | <dl·class="py·attribute"> | 357 | <dl·class="py·attribute"> |
358 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.body"> | 358 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.AbortHandshake.body"> |
359 | <span·class="sig-name·descname"><span·class="pre">body</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.body"·title="Link·to·this·definition">#</a></dt> | 359 | <span·class="sig-name·descname"><span·class="pre">body</span></span><a·class="headerlink"·href="#websockets.exceptions.AbortHandshake.body"·title="Link·to·this·definition">#</a></dt> |
360 | <dd><p>HTTP·response·body.</p> | 360 | <dd><p>HTTP·response·body.</p> |
361 | <dl·class="field-list·simple"> | 361 | <dl·class="field-list·simple"> |
362 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 362 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
363 | <dd·class="field-odd"><p> | 363 | <dd·class="field-odd"><p>bytes</p> |
364 | </dd> | 364 | </dd> |
365 | </dl> | 365 | </dl> |
366 | </dd></dl> | 366 | </dd></dl> |
367 | </dd></dl> | 367 | </dd></dl> |
368 | <dl·class="py·exception"> | 368 | <dl·class="py·exception"> |
Offset 402, 15 lines modified | Offset 402, 15 lines modified | ||
402 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.ConnectionClosed.rcvd_then_sent"> | 402 | <dt·class="sig·sig-object·py"·id="websockets.exceptions.ConnectionClosed.rcvd_then_sent"> |
403 | <span·class="sig-name·descname"><span·class="pre">rcvd_then_sent</span></span><a·class="headerlink"·href="#websockets.exceptions.ConnectionClosed.rcvd_then_sent"·title="Link·to·this·definition">#</a></dt> | 403 | <span·class="sig-name·descname"><span·class="pre">rcvd_then_sent</span></span><a·class="headerlink"·href="#websockets.exceptions.ConnectionClosed.rcvd_then_sent"·title="Link·to·this·definition">#</a></dt> |
404 | <dd><p>if·close·frames·were·received·and | 404 | <dd><p>if·close·frames·were·received·and |
405 | sent,·this·attribute·tells·in·which·order·this·happened,·from·the | 405 | sent,·this·attribute·tells·in·which·order·this·happened,·from·the |
406 | perspective·of·this·side·of·the·connection.</p> | 406 | perspective·of·this·side·of·the·connection.</p> |
407 | <dl·class="field-list·simple"> | 407 | <dl·class="field-list·simple"> |
408 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> | 408 | <dt·class="field-odd">Type<span·class="colon">:</span></dt> |
409 | <dd·class="field-odd"><p>Optional[ | 409 | <dd·class="field-odd"><p>Optional[bool]</p> |
410 | </dd> | 410 | </dd> |
411 | </dl> | 411 | </dl> |
412 | </dd></dl> | 412 | </dd></dl> |
413 | </dd></dl> | 413 | </dd></dl> |
414 | <dl·class="py·exception"> | 414 | <dl·class="py·exception"> |
Offset 283, 52 lines modified | Offset 283, 52 lines modified | ||
283 | <p>Refer·to·the·<a·class="reference·internal"·href="../../topics/compression/"><span·class="doc">topic·guide·on·compression</span></a>·to | 283 | <p>Refer·to·the·<a·class="reference·internal"·href="../../topics/compression/"><span·class="doc">topic·guide·on·compression</span></a>·to |
284 | learn·more·about·tuning·compression·settings.</p> | 284 | learn·more·about·tuning·compression·settings.</p> |
285 | <dl·class="py·class"> | 285 | <dl·class="py·class"> |
286 | <dt·class="sig·sig-object·py"·id="websockets.extensions.permessage_deflate.ClientPerMessageDeflateFactory"> | 286 | <dt·class="sig·sig-object·py"·id="websockets.extensions.permessage_deflate.ClientPerMessageDeflateFactory"> |
287 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.extensions.permessage_deflate.</span></span><span·class="sig-name·descname"><span·class="pre">ClientPerMessageDeflateFactory</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">server_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compress_settings</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.permessage_deflate.ClientPerMessageDeflateFactory"·title="Link·to·this·definition">#</a></dt> | 287 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.extensions.permessage_deflate.</span></span><span·class="sig-name·descname"><span·class="pre">ClientPerMessageDeflateFactory</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">server_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compress_settings</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.permessage_deflate.ClientPerMessageDeflateFactory"·title="Link·to·this·definition">#</a></dt> |
288 | <dd><p>Client-side·extension·factory·for·the·Per-Message·Deflate·extension.</p> | 288 | <dd><p>Client-side·extension·factory·for·the·Per-Message·Deflate·extension.</p> |
289 | <p>Parameters·behave·as·described·in·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1">section·7.1·of·RFC·7692</a>.</p> | 289 | <p>Parameters·behave·as·described·in·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1">section·7.1·of·RFC·7692</a>.</p> |
290 | <p>Set·them·to·< | 290 | <p>Set·them·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·to·include·them·in·the·negotiation·offer·without·a |
291 | value·or·to·an·integer·value·to·include·them·with·this·value.</p> | 291 | value·or·to·an·integer·value·to·include·them·with·this·value.</p> |
292 | <dl·class="field-list·simple"> | 292 | <dl·class="field-list·simple"> |
293 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 293 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
294 | <dd·class="field-odd"><ul·class="simple"> | 294 | <dd·class="field-odd"><ul·class="simple"> |
295 | <li><p><strong>server_no_context_takeover</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·prevent·server·from·using·context·takeover.</p></li> | ||
296 | <li><p><strong>client_no_context_takeover</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·prevent·client·from·using·context·takeover.</p></li> | ||
297 | <li><p><strong>server_ | 295 | <li><p><strong>server_no_context_takeover</strong>·(<em>bool</em>)·–·prevent·server·from·using·context·takeover.</p></li> |
296 | <li><p><strong>client_no_context_takeover</strong>·(<em>bool</em>)·–·prevent·client·from·using·context·takeover.</p></li> | ||
297 | <li><p><strong>server_max_window_bits</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·the·server’s·LZ77·sliding·window | ||
298 | in·bits,·between·8·and·15.</p></li> | 298 | in·bits,·between·8·and·15.</p></li> |
299 | <li><p><strong>client_max_window_bits</strong>·(<em>Optional</em><em>[</em><em>Union</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>,·</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a><em>]</em><em>]</em>)·–·maximum·size·of·the·client’s·LZ77·sliding·window | ||
300 | 299 | <li><p><strong>client_max_window_bits</strong>·(<em>Optional</em><em>[</em><em>Union</em><em>[</em><em>int</em><em>,·</em><em>bool</em><em>]</em><em>]</em>)·–·maximum·size·of·the·client’s·LZ77·sliding·window | |
300 | in·bits,·between·8·and·15,·or·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·to·indicate·support·without | ||
301 | setting·a·limit.</p></li> | 301 | setting·a·limit.</p></li> |
302 | <li><p><strong>compress_settings</strong>·(<em>Optional</em><em>[</em><em>Dict</em><em>[</em>< | 302 | <li><p><strong>compress_settings</strong>·(<em>Optional</em><em>[</em><em>Dict</em><em>[</em><em>str</em><em>,·</em><em>Any</em><em>]</em><em>]</em>)·–·additional·keyword·arguments·for·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">zlib.compressobj()</span></code>, |
303 | excluding·<code·class="docutils·literal·notranslate"><span·class="pre">wbits</span></code>.</p></li> | 303 | excluding·<code·class="docutils·literal·notranslate"><span·class="pre">wbits</span></code>.</p></li> |
304 | </ul> | 304 | </ul> |
305 | </dd> | 305 | </dd> |
306 | </dl> | 306 | </dl> |
307 | </dd></dl> | 307 | </dd></dl> |
308 | <dl·class="py·class"> | 308 | <dl·class="py·class"> |
309 | <dt·class="sig·sig-object·py"·id="websockets.extensions.permessage_deflate.ServerPerMessageDeflateFactory"> | 309 | <dt·class="sig·sig-object·py"·id="websockets.extensions.permessage_deflate.ServerPerMessageDeflateFactory"> |
310 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.extensions.permessage_deflate.</span></span><span·class="sig-name·descname"><span·class="pre">ServerPerMessageDeflateFactory</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">server_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compress_settings</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">require_client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.permessage_deflate.ServerPerMessageDeflateFactory"·title="Link·to·this·definition">#</a></dt> | 310 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.extensions.permessage_deflate.</span></span><span·class="sig-name·descname"><span·class="pre">ServerPerMessageDeflateFactory</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">server_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_no_context_takeover</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compress_settings</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">require_client_max_window_bits</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">False</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.permessage_deflate.ServerPerMessageDeflateFactory"·title="Link·to·this·definition">#</a></dt> |
311 | <dd><p>Server-side·extension·factory·for·the·Per-Message·Deflate·extension.</p> | 311 | <dd><p>Server-side·extension·factory·for·the·Per-Message·Deflate·extension.</p> |
312 | <p>Parameters·behave·as·described·in·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1">section·7.1·of·RFC·7692</a>.</p> | 312 | <p>Parameters·behave·as·described·in·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1">section·7.1·of·RFC·7692</a>.</p> |
313 | <p>Set·them·to·< | 313 | <p>Set·them·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·to·include·them·in·the·negotiation·offer·without·a |
314 | value·or·to·an·integer·value·to·include·them·with·this·value.</p> | 314 | value·or·to·an·integer·value·to·include·them·with·this·value.</p> |
315 | <dl·class="field-list·simple"> | 315 | <dl·class="field-list·simple"> |
316 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 316 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
317 | <dd·class="field-odd"><ul·class="simple"> | 317 | <dd·class="field-odd"><ul·class="simple"> |
318 | <li><p><strong>server_no_context_takeover</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·prevent·server·from·using·context·takeover.</p></li> | ||
319 | <li><p><strong>client_no_context_takeover</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·prevent·client·from·using·context·takeover.</p></li> | ||
320 | <li><p><strong>server_ | 318 | <li><p><strong>server_no_context_takeover</strong>·(<em>bool</em>)·–·prevent·server·from·using·context·takeover.</p></li> |
319 | <li><p><strong>client_no_context_takeover</strong>·(<em>bool</em>)·–·prevent·client·from·using·context·takeover.</p></li> | ||
320 | <li><p><strong>server_max_window_bits</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·the·server’s·LZ77·sliding·window | ||
321 | in·bits,·between·8·and·15.</p></li> | 321 | in·bits,·between·8·and·15.</p></li> |
322 | <li><p><strong>client_max_window_bits</strong>·(<em>Optional</em><em>[</em>< | 322 | <li><p><strong>client_max_window_bits</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·the·client’s·LZ77·sliding·window |
323 | in·bits,·between·8·and·15.</p></li> | 323 | in·bits,·between·8·and·15.</p></li> |
324 | <li><p><strong>compress_settings</strong>·(<em>Optional</em><em>[</em><em>Dict</em><em>[</em>< | 324 | <li><p><strong>compress_settings</strong>·(<em>Optional</em><em>[</em><em>Dict</em><em>[</em><em>str</em><em>,·</em><em>Any</em><em>]</em><em>]</em>)·–·additional·keyword·arguments·for·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">zlib.compressobj()</span></code>, |
325 | excluding·<code·class="docutils·literal·notranslate"><span·class="pre">wbits</span></code>.</p></li> | 325 | excluding·<code·class="docutils·literal·notranslate"><span·class="pre">wbits</span></code>.</p></li> |
326 | <li><p><strong>require_client_max_window_bits</strong>·(< | 326 | <li><p><strong>require_client_max_window_bits</strong>·(<em>bool</em>)·–·do·not·enable·compression·at·all·if |
327 | client·doesn’t·advertise·support·for·<code·class="docutils·literal·notranslate"><span·class="pre">client_max_window_bits</span></code>; | 327 | client·doesn’t·advertise·support·for·<code·class="docutils·literal·notranslate"><span·class="pre">client_max_window_bits</span></code>; |
328 | the·default·behavior·is·to·enable·compression·without·enforcing | 328 | the·default·behavior·is·to·enable·compression·without·enforcing |
329 | <code·class="docutils·literal·notranslate"><span·class="pre">client_max_window_bits</span></code>.</p></li> | 329 | <code·class="docutils·literal·notranslate"><span·class="pre">client_max_window_bits</span></code>.</p></li> |
330 | </ul> | 330 | </ul> |
331 | </dd> | 331 | </dd> |
332 | </dl> | 332 | </dl> |
333 | </dd></dl> | 333 | </dd></dl> |
Offset 356, 15 lines modified | Offset 356, 15 lines modified | ||
356 | <dt·class="sig·sig-object·py"·id="websockets.extensions.Extension.decode"> | 356 | <dt·class="sig·sig-object·py"·id="websockets.extensions.Extension.decode"> |
357 | <span·class="sig-name·descname"><span·class="pre">decode</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">frame</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.Extension.decode"·title="Link·to·this·definition">#</a></dt> | 357 | <span·class="sig-name·descname"><span·class="pre">decode</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">frame</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.extensions.Extension.decode"·title="Link·to·this·definition">#</a></dt> |
358 | <dd><p>Decode·an·incoming·frame.</p> | 358 | <dd><p>Decode·an·incoming·frame.</p> |
359 | <dl·class="field-list·simple"> | 359 | <dl·class="field-list·simple"> |
360 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 360 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
361 | <dd·class="field-odd"><ul·class="simple"> | 361 | <dd·class="field-odd"><ul·class="simple"> |
362 | <li><p><strong>frame</strong>·(<a·class="reference·internal"·href="../datastructures/#websockets.frames.Frame"·title="websockets.frames.Frame"><em>Frame</em></a>)·–·incoming·frame.</p></li> | 362 | <li><p><strong>frame</strong>·(<a·class="reference·internal"·href="../datastructures/#websockets.frames.Frame"·title="websockets.frames.Frame"><em>Frame</em></a>)·–·incoming·frame.</p></li> |
363 | <li><p><strong>max_size</strong>·(< | 363 | <li><p><strong>max_size</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·maximum·payload·size·in·bytes.</p></li> |
364 | </ul> | 364 | </ul> |
365 | </dd> | 365 | </dd> |
366 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> | 366 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> |
367 | <dd·class="field-even"><p>Decoded·frame.</p> | 367 | <dd·class="field-even"><p>Decoded·frame.</p> |
368 | </dd> | 368 | </dd> |
369 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> | 369 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> |
370 | <dd·class="field-odd"><p><a·class="reference·internal"·href="../datastructures/#websockets.frames.Frame"·title="websockets.frames.Frame">Frame</a></p> | 370 | <dd·class="field-odd"><p><a·class="reference·internal"·href="../datastructures/#websockets.frames.Frame"·title="websockets.frames.Frame">Frame</a></p> |
Offset 280, 16 lines modified | Offset 280, 16 lines modified | ||
280 | ····.support-matrix-table·td:not(:first-child)·{·text-align:·center;·} | 280 | ····.support-matrix-table·td:not(:first-child)·{·text-align:·center;·} |
281 | </style><section·id="both-sides"> | 281 | </style><section·id="both-sides"> |
282 | <h2>Both·sides<a·class="headerlink"·href="#both-sides"·title="Link·to·this·heading">#</a></h2> | 282 | <h2>Both·sides<a·class="headerlink"·href="#both-sides"·title="Link·to·this·heading">#</a></h2> |
283 | <div·class="table-wrapper·support-matrix-table·docutils·container"> | 283 | <div·class="table-wrapper·support-matrix-table·docutils·container"> |
284 | <table·class="support-matrix-table·docutils·align-default"> | 284 | <table·class="support-matrix-table·docutils·align-default"> |
285 | <thead> | 285 | <thead> |
286 | <tr·class="row-odd"><th·class="head"></th> | 286 | <tr·class="row-odd"><th·class="head"></th> |
287 | <th·class="head"><p><a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a></p></th> | ||
288 | <th·class="head"><p>< | 287 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></p></th> |
288 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code></p></th> | ||
289 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> | 289 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> |
290 | </tr> | 290 | </tr> |
291 | </thead> | 291 | </thead> |
292 | <tbody> | 292 | <tbody> |
293 | <tr·class="row-even"><td><p>Perform·the·opening·handshake</p></td> | 293 | <tr·class="row-even"><td><p>Perform·the·opening·handshake</p></td> |
294 | <td><p>✅</p></td> | 294 | <td><p>✅</p></td> |
295 | <td><p>✅</p></td> | 295 | <td><p>✅</p></td> |
Offset 414, 16 lines modified | Offset 414, 16 lines modified | ||
414 | </section> | 414 | </section> |
415 | <section·id="server"> | 415 | <section·id="server"> |
416 | <h2>Server<a·class="headerlink"·href="#server"·title="Link·to·this·heading">#</a></h2> | 416 | <h2>Server<a·class="headerlink"·href="#server"·title="Link·to·this·heading">#</a></h2> |
417 | <div·class="table-wrapper·support-matrix-table·docutils·container"> | 417 | <div·class="table-wrapper·support-matrix-table·docutils·container"> |
418 | <table·class="support-matrix-table·docutils·align-default"> | 418 | <table·class="support-matrix-table·docutils·align-default"> |
419 | <thead> | 419 | <thead> |
420 | <tr·class="row-odd"><th·class="head"></th> | 420 | <tr·class="row-odd"><th·class="head"></th> |
421 | <th·class="head"><p><a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a></p></th> | ||
422 | <th·class="head"><p>< | 421 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></p></th> |
422 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code></p></th> | ||
423 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> | 423 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> |
424 | </tr> | 424 | </tr> |
425 | </thead> | 425 | </thead> |
426 | <tbody> | 426 | <tbody> |
427 | <tr·class="row-even"><td><p>Listen·on·a·TCP·socket</p></td> | 427 | <tr·class="row-even"><td><p>Listen·on·a·TCP·socket</p></td> |
428 | <td><p>✅</p></td> | 428 | <td><p>✅</p></td> |
429 | <td><p>✅</p></td> | 429 | <td><p>✅</p></td> |
Offset 505, 16 lines modified | Offset 505, 16 lines modified | ||
505 | </section> | 505 | </section> |
506 | <section·id="client"> | 506 | <section·id="client"> |
507 | <h2>Client<a·class="headerlink"·href="#client"·title="Link·to·this·heading">#</a></h2> | 507 | <h2>Client<a·class="headerlink"·href="#client"·title="Link·to·this·heading">#</a></h2> |
508 | <div·class="table-wrapper·support-matrix-table·docutils·container"> | 508 | <div·class="table-wrapper·support-matrix-table·docutils·container"> |
509 | <table·class="support-matrix-table·docutils·align-default"> | 509 | <table·class="support-matrix-table·docutils·align-default"> |
510 | <thead> | 510 | <thead> |
511 | <tr·class="row-odd"><th·class="head"></th> | 511 | <tr·class="row-odd"><th·class="head"></th> |
512 | <th·class="head"><p><a·class="reference·external"·href="https://docs.python.org/3/library/asyncio.html#module-asyncio"·title="(in·Python·v3.12)"><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></a></p></th> | ||
513 | <th·class="head"><p>< | 512 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code></p></th> |
513 | <th·class="head"><p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code></p></th> | ||
514 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> | 514 | <th·class="head"><p><a·class="reference·external"·href="https://sans-io.readthedocs.io/">Sans-I/O</a></p></th> |
515 | </tr> | 515 | </tr> |
516 | </thead> | 516 | </thead> |
517 | <tbody> | 517 | <tbody> |
518 | <tr·class="row-even"><td><p>Connect·to·a·TCP·socket</p></td> | 518 | <tr·class="row-even"><td><p>Connect·to·a·TCP·socket</p></td> |
519 | <td><p>✅</p></td> | 519 | <td><p>✅</p></td> |
520 | <td><p>✅</p></td> | 520 | <td><p>✅</p></td> |
Offset 278, 26 lines modified | Offset 278, 26 lines modified | ||
278 | <div·class="toctree-wrapper·compound"> | 278 | <div·class="toctree-wrapper·compound"> |
279 | <ul> | 279 | <ul> |
280 | <li·class="toctree-l1"><a·class="reference·internal"·href="features/">Features</a></li> | 280 | <li·class="toctree-l1"><a·class="reference·internal"·href="features/">Features</a></li> |
281 | </ul> | 281 | </ul> |
282 | </div> | 282 | </div> |
283 | </section> | 283 | </section> |
284 | <section·id="asyncio"> | 284 | <section·id="asyncio"> |
285 | <h2>< | 285 | <h2><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code><a·class="headerlink"·href="#asyncio"·title="Link·to·this·heading">#</a></h2> |
286 | <p>This·is·the·default·implementation.·It’s·ideal·for·servers·that·handle·many | 286 | <p>This·is·the·default·implementation.·It’s·ideal·for·servers·that·handle·many |
287 | clients·concurrently.</p> | 287 | clients·concurrently.</p> |
288 | <div·class="toctree-wrapper·compound"> | 288 | <div·class="toctree-wrapper·compound"> |
289 | <ul> | 289 | <ul> |
290 | <li·class="toctree-l1"><a·class="reference·internal"·href="asyncio/server/">Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)</a></li> | 290 | <li·class="toctree-l1"><a·class="reference·internal"·href="asyncio/server/">Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)</a></li> |
291 | <li·class="toctree-l1"><a·class="reference·internal"·href="asyncio/client/">Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)</a></li> | 291 | <li·class="toctree-l1"><a·class="reference·internal"·href="asyncio/client/">Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>)</a></li> |
292 | </ul> | 292 | </ul> |
293 | </div> | 293 | </div> |
294 | </section> | 294 | </section> |
295 | <section·id="threading"> | 295 | <section·id="threading"> |
296 | <h2>< | 296 | <h2><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code><a·class="headerlink"·href="#threading"·title="Link·to·this·heading">#</a></h2> |
297 | <p>This·alternative·implementation·can·be·a·good·choice·for·clients.</p> | 297 | <p>This·alternative·implementation·can·be·a·good·choice·for·clients.</p> |
298 | <div·class="toctree-wrapper·compound"> | 298 | <div·class="toctree-wrapper·compound"> |
299 | <ul> | 299 | <ul> |
300 | <li·class="toctree-l1"><a·class="reference·internal"·href="sync/server/">Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)</a></li> | 300 | <li·class="toctree-l1"><a·class="reference·internal"·href="sync/server/">Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)</a></li> |
301 | <li·class="toctree-l1"><a·class="reference·internal"·href="sync/client/">Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)</a></li> | 301 | <li·class="toctree-l1"><a·class="reference·internal"·href="sync/client/">Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)</a></li> |
302 | </ul> | 302 | </ul> |
303 | </div> | 303 | </div> |
Offset 283, 16 lines modified | Offset 283, 16 lines modified | ||
283 | to·a·server·that·validates·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header·to·defend·against | 283 | to·a·server·that·validates·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header·to·defend·against |
284 | Cross-Site·WebSocket·Hijacking·attacks.</p></li> | 284 | Cross-Site·WebSocket·Hijacking·attacks.</p></li> |
285 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ClientExtensionFactory"·title="websockets.extensions.ClientExtensionFactory"><em>ClientExtensionFactory</em></a><em>]</em><em>]</em>)·–·list·of·supported·extensions,·in·order·in·which·they | 285 | <li><p><strong>extensions</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ClientExtensionFactory"·title="websockets.extensions.ClientExtensionFactory"><em>ClientExtensionFactory</em></a><em>]</em><em>]</em>)·–·list·of·supported·extensions,·in·order·in·which·they |
286 | should·be·tried.</p></li> | 286 | should·be·tried.</p></li> |
287 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·list·of·supported·subprotocols,·in·order·of·decreasing | 287 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·list·of·supported·subprotocols,·in·order·of·decreasing |
288 | preference.</p></li> | 288 | preference.</p></li> |
289 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="../common/#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> | 289 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="../common/#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> |
290 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; | ||
291 | < | 290 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; |
291 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
292 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·logger·for·this·connection; | 292 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·logger·for·this·connection; |
293 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>; | 293 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>; |
294 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 294 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
295 | </ul> | 295 | </ul> |
296 | </dd> | 296 | </dd> |
297 | </dl> | 297 | </dl> |
298 | <dl·class="py·method"> | 298 | <dl·class="py·method"> |
Offset 302, 15 lines modified | Offset 302, 15 lines modified | ||
302 | <p>After·calling·this·method:</p> | 302 | <p>After·calling·this·method:</p> |
303 | <ul·class="simple"> | 303 | <ul·class="simple"> |
304 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.data_to_send"·title="websockets.client.ClientProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> | 304 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.data_to_send"·title="websockets.client.ClientProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> |
305 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.events_received"·title="websockets.client.ClientProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> | 305 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.events_received"·title="websockets.client.ClientProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> |
306 | </ul> | 306 | </ul> |
307 | <dl·class="field-list·simple"> | 307 | <dl·class="field-list·simple"> |
308 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 308 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
309 | <dd·class="field-odd"><p>< | 309 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.receive_eof"·title="websockets.client.ClientProtocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
310 | </dd> | 310 | </dd> |
311 | </dl> | 311 | </dl> |
312 | </dd></dl> | 312 | </dd></dl> |
313 | <dl·class="py·method"> | 313 | <dl·class="py·method"> |
314 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.receive_eof"> | 314 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.receive_eof"> |
315 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.receive_eof"·title="Link·to·this·definition">#</a></dt> | 315 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.receive_eof"·title="Link·to·this·definition">#</a></dt> |
Offset 320, 15 lines modified | Offset 320, 15 lines modified | ||
320 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.data_to_send"·title="websockets.client.ClientProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; | 320 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.data_to_send"·title="websockets.client.ClientProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; |
321 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> | 321 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> |
322 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.events_received"·title="websockets.client.ClientProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return | 322 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.events_received"·title="websockets.client.ClientProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return |
323 | any·new·events.</p></li> | 323 | any·new·events.</p></li> |
324 | </ul> | 324 | </ul> |
325 | <dl·class="field-list·simple"> | 325 | <dl·class="field-list·simple"> |
326 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 326 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
327 | <dd·class="field-odd"><p>< | 327 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.client.ClientProtocol.receive_eof"·title="websockets.client.ClientProtocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
328 | </dd> | 328 | </dd> |
329 | </dl> | 329 | </dl> |
330 | </dd></dl> | 330 | </dd></dl> |
331 | <dl·class="py·method"> | 331 | <dl·class="py·method"> |
332 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.connect"> | 332 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.connect"> |
333 | <span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.connect"·title="Link·to·this·definition">#</a></dt> | 333 | <span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.connect"·title="Link·to·this·definition">#</a></dt> |
Offset 359, 18 lines modified | Offset 359, 18 lines modified | ||
359 | <dl·class="py·method"> | 359 | <dl·class="py·method"> |
360 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_continuation"> | 360 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_continuation"> |
361 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_continuation"·title="Link·to·this·definition">#</a></dt> | 361 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_continuation"·title="Link·to·this·definition">#</a></dt> |
362 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> | 362 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> |
363 | <dl·class="field-list·simple"> | 363 | <dl·class="field-list·simple"> |
364 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 364 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
365 | <dd·class="field-odd"><ul·class="simple"> | 365 | <dd·class="field-odd"><ul·class="simple"> |
366 | <li><p><strong>data</strong>·(< | 366 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·the·same·kind·of·data |
367 | as·the·initial·frame.</p></li> | 367 | as·the·initial·frame.</p></li> |
368 | <li><p><strong>fin</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·FIN·bit;·set·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#True"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code></a>·if·this·is·the·last·frame | ||
369 | 368 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·if·this·is·the·last·frame | |
369 | of·a·fragmented·message·and·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·otherwise.</p></li> | ||
370 | </ul> | 370 | </ul> |
371 | </dd> | 371 | </dd> |
372 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 372 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
373 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> | 373 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> |
374 | </dd> | 374 | </dd> |
375 | </dl> | 375 | </dl> |
376 | </dd></dl> | 376 | </dd></dl> |
Offset 378, 16 lines modified | Offset 378, 16 lines modified | ||
378 | <dl·class="py·method"> | 378 | <dl·class="py·method"> |
379 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_text"> | 379 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_text"> |
380 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_text"·title="Link·to·this·definition">#</a></dt> | 380 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_text"·title="Link·to·this·definition">#</a></dt> |
381 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> | 381 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> |
382 | <dl·class="field-list·simple"> | 382 | <dl·class="field-list·simple"> |
383 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 383 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
384 | <dd·class="field-odd"><ul·class="simple"> | 384 | <dd·class="field-odd"><ul·class="simple"> |
385 | <li><p><strong>data</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><em>bytes</em></a>)·–·payload·containing·text·encoded·with·UTF-8.</p></li> | ||
386 | <li><p><strong> | 385 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·text·encoded·with·UTF-8.</p></li> |
386 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·if·this·is·the·first·frame·of | ||
387 | a·fragmented·message.</p></li> | 387 | a·fragmented·message.</p></li> |
388 | </ul> | 388 | </ul> |
389 | </dd> | 389 | </dd> |
390 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 390 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
391 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> | 391 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> |
392 | </dd> | 392 | </dd> |
393 | </dl> | 393 | </dl> |
Offset 396, 16 lines modified | Offset 396, 16 lines modified | ||
396 | <dl·class="py·method"> | 396 | <dl·class="py·method"> |
397 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_binary"> | 397 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_binary"> |
398 | <span·class="sig-name·descname"><span·class="pre">send_binary</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_binary"·title="Link·to·this·definition">#</a></dt> | 398 | <span·class="sig-name·descname"><span·class="pre">send_binary</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_binary"·title="Link·to·this·definition">#</a></dt> |
399 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Binary·frame</a>.</p> | 399 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Binary·frame</a>.</p> |
400 | <dl·class="field-list·simple"> | 400 | <dl·class="field-list·simple"> |
401 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 401 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
402 | <dd·class="field-odd"><ul·class="simple"> | 402 | <dd·class="field-odd"><ul·class="simple"> |
403 | <li><p><strong>data</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><em>bytes</em></a>)·–·payload·containing·arbitrary·binary·data.</p></li> | ||
404 | <li><p><strong> | 403 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·arbitrary·binary·data.</p></li> |
404 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·if·this·is·the·first·frame·of | ||
405 | a·fragmented·message.</p></li> | 405 | a·fragmented·message.</p></li> |
406 | </ul> | 406 | </ul> |
407 | </dd> | 407 | </dd> |
408 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 408 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
409 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> | 409 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> |
410 | </dd> | 410 | </dd> |
411 | </dl> | 411 | </dl> |
Offset 414, 16 lines modified | Offset 414, 16 lines modified | ||
414 | <dl·class="py·method"> | 414 | <dl·class="py·method"> |
415 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_close"> | 415 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_close"> |
416 | <span·class="sig-name·descname"><span·class="pre">send_close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">code</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">reason</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">''</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_close"·title="Link·to·this·definition">#</a></dt> | 416 | <span·class="sig-name·descname"><span·class="pre">send_close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">code</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">reason</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">''</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.client.ClientProtocol.send_close"·title="Link·to·this·definition">#</a></dt> |
417 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1">Close·frame</a>.</p> | 417 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1">Close·frame</a>.</p> |
418 | <dl·class="field-list·simple"> | 418 | <dl·class="field-list·simple"> |
419 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 419 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
420 | <dd·class="field-odd"><ul·class="simple"> | 420 | <dd·class="field-odd"><ul·class="simple"> |
421 | <li><p><strong>code</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·close·code.</p></li> | ||
422 | <li><p><strong> | 421 | <li><p><strong>code</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·close·code.</p></li> |
422 | <li><p><strong>reason</strong>·(<em>str</em>)·–·close·reason.</p></li> | ||
423 | </ul> | 423 | </ul> |
424 | </dd> | 424 | </dd> |
425 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 425 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
426 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·being·sent,·if·the·code | 426 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·being·sent,·if·the·code |
427 | ····isn’t·valid,·or·if·a·reason·is·provided·without·a·code</p> | 427 | ····isn’t·valid,·or·if·a·reason·is·provided·without·a·code</p> |
428 | </dd> | 428 | </dd> |
429 | </dl> | 429 | </dl> |
Offset 431, 39 lines modified | Offset 431, 39 lines modified | ||
431 | <dl·class="py·method"> | 431 | <dl·class="py·method"> |
432 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_ping"> | 432 | <dt·class="sig·sig-object·py"·id="websockets.client.ClientProtocol.send_ping"> |
Max diff block lines reached; 15670/31919 bytes (49.09%) of diff not shown. |
Offset 275, 16 lines modified | Offset 275, 16 lines modified | ||
275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">Protocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">side</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">state</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">State.OPEN</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol"·title="Link·to·this·definition">#</a></dt> | 275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">Protocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">side</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">state</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">State.OPEN</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol"·title="Link·to·this·definition">#</a></dt> |
276 | <dd><p>Sans-I/O·implementation·of·a·WebSocket·connection.</p> | 276 | <dd><p>Sans-I/O·implementation·of·a·WebSocket·connection.</p> |
277 | <dl·class="field-list·simple"> | 277 | <dl·class="field-list·simple"> |
278 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 278 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
279 | <dd·class="field-odd"><ul·class="simple"> | 279 | <dd·class="field-odd"><ul·class="simple"> |
280 | <li><p><strong>side</strong>·(<a·class="reference·internal"·href="#websockets.protocol.Side"·title="websockets.protocol.Side"><em>Side</em></a>)·–·<a·class="reference·internal"·href="#websockets.protocol.Side.CLIENT"·title="websockets.protocol.Side.CLIENT"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">CLIENT</span></code></a>·or·<a·class="reference·internal"·href="#websockets.protocol.Side.SERVER"·title="websockets.protocol.Side.SERVER"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">SERVER</span></code></a>.</p></li> | 280 | <li><p><strong>side</strong>·(<a·class="reference·internal"·href="#websockets.protocol.Side"·title="websockets.protocol.Side"><em>Side</em></a>)·–·<a·class="reference·internal"·href="#websockets.protocol.Side.CLIENT"·title="websockets.protocol.Side.CLIENT"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">CLIENT</span></code></a>·or·<a·class="reference·internal"·href="#websockets.protocol.Side.SERVER"·title="websockets.protocol.Side.SERVER"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">SERVER</span></code></a>.</p></li> |
281 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> | 281 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> |
282 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; | ||
283 | < | 282 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; |
283 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
284 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·logger·for·this·connection;·depending·on·<code·class="docutils·literal·notranslate"><span·class="pre">side</span></code>, | 284 | <li><p><strong>logger</strong>·(<em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.LoggerLike"·title="websockets.typing.LoggerLike"><em>LoggerLike</em></a><em>]</em>)·–·logger·for·this·connection;·depending·on·<code·class="docutils·literal·notranslate"><span·class="pre">side</span></code>, |
285 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code> | 285 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code> |
286 | or·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>; | 286 | or·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>; |
287 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 287 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
288 | </ul> | 288 | </ul> |
289 | </dd> | 289 | </dd> |
290 | </dl> | 290 | </dl> |
Offset 295, 15 lines modified | Offset 295, 15 lines modified | ||
295 | <p>After·calling·this·method:</p> | 295 | <p>After·calling·this·method:</p> |
296 | <ul·class="simple"> | 296 | <ul·class="simple"> |
297 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> | 297 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> |
298 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> | 298 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> |
299 | </ul> | 299 | </ul> |
300 | <dl·class="field-list·simple"> | 300 | <dl·class="field-list·simple"> |
301 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 301 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
302 | <dd·class="field-odd"><p>< | 302 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.protocol.Protocol.receive_eof"·title="websockets.protocol.Protocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
303 | </dd> | 303 | </dd> |
304 | </dl> | 304 | </dl> |
305 | </dd></dl> | 305 | </dd></dl> |
306 | <dl·class="py·method"> | 306 | <dl·class="py·method"> |
307 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.receive_eof"> | 307 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.receive_eof"> |
308 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.receive_eof"·title="Link·to·this·definition">#</a></dt> | 308 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.receive_eof"·title="Link·to·this·definition">#</a></dt> |
Offset 313, 30 lines modified | Offset 313, 30 lines modified | ||
313 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; | 313 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.data_to_send"·title="websockets.protocol.Protocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; |
314 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> | 314 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> |
315 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return | 315 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return |
316 | any·new·events.</p></li> | 316 | any·new·events.</p></li> |
317 | </ul> | 317 | </ul> |
318 | <dl·class="field-list·simple"> | 318 | <dl·class="field-list·simple"> |
319 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 319 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
320 | <dd·class="field-odd"><p>< | 320 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.protocol.Protocol.receive_eof"·title="websockets.protocol.Protocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
321 | </dd> | 321 | </dd> |
322 | </dl> | 322 | </dl> |
323 | </dd></dl> | 323 | </dd></dl> |
324 | <dl·class="py·method"> | 324 | <dl·class="py·method"> |
325 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_continuation"> | 325 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_continuation"> |
326 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_continuation"·title="Link·to·this·definition">#</a></dt> | 326 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_continuation"·title="Link·to·this·definition">#</a></dt> |
327 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> | 327 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> |
328 | <dl·class="field-list·simple"> | 328 | <dl·class="field-list·simple"> |
329 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 329 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
330 | <dd·class="field-odd"><ul·class="simple"> | 330 | <dd·class="field-odd"><ul·class="simple"> |
331 | <li><p><strong>data</strong>·(< | 331 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·the·same·kind·of·data |
332 | as·the·initial·frame.</p></li> | 332 | as·the·initial·frame.</p></li> |
333 | <li><p><strong>fin</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·FIN·bit;·set·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#True"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code></a>·if·this·is·the·last·frame | ||
334 | 333 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·if·this·is·the·last·frame | |
334 | of·a·fragmented·message·and·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·otherwise.</p></li> | ||
335 | </ul> | 335 | </ul> |
336 | </dd> | 336 | </dd> |
337 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 337 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
338 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> | 338 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> |
339 | </dd> | 339 | </dd> |
340 | </dl> | 340 | </dl> |
341 | </dd></dl> | 341 | </dd></dl> |
Offset 344, 16 lines modified | Offset 344, 16 lines modified | ||
344 | <dl·class="py·method"> | 344 | <dl·class="py·method"> |
345 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_text"> | 345 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_text"> |
346 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_text"·title="Link·to·this·definition">#</a></dt> | 346 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_text"·title="Link·to·this·definition">#</a></dt> |
347 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> | 347 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> |
348 | <dl·class="field-list·simple"> | 348 | <dl·class="field-list·simple"> |
349 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 349 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
350 | <dd·class="field-odd"><ul·class="simple"> | 350 | <dd·class="field-odd"><ul·class="simple"> |
351 | <li><p><strong>data</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><em>bytes</em></a>)·–·payload·containing·text·encoded·with·UTF-8.</p></li> | ||
352 | <li><p><strong> | 351 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·text·encoded·with·UTF-8.</p></li> |
352 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·if·this·is·the·first·frame·of | ||
353 | a·fragmented·message.</p></li> | 353 | a·fragmented·message.</p></li> |
354 | </ul> | 354 | </ul> |
355 | </dd> | 355 | </dd> |
356 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 356 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
357 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> | 357 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> |
358 | </dd> | 358 | </dd> |
359 | </dl> | 359 | </dl> |
Offset 362, 16 lines modified | Offset 362, 16 lines modified | ||
362 | <dl·class="py·method"> | 362 | <dl·class="py·method"> |
363 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_binary"> | 363 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_binary"> |
364 | <span·class="sig-name·descname"><span·class="pre">send_binary</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_binary"·title="Link·to·this·definition">#</a></dt> | 364 | <span·class="sig-name·descname"><span·class="pre">send_binary</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_binary"·title="Link·to·this·definition">#</a></dt> |
365 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Binary·frame</a>.</p> | 365 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Binary·frame</a>.</p> |
366 | <dl·class="field-list·simple"> | 366 | <dl·class="field-list·simple"> |
367 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 367 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
368 | <dd·class="field-odd"><ul·class="simple"> | 368 | <dd·class="field-odd"><ul·class="simple"> |
369 | <li><p><strong>data</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><em>bytes</em></a>)·–·payload·containing·arbitrary·binary·data.</p></li> | ||
370 | <li><p><strong> | 369 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·arbitrary·binary·data.</p></li> |
370 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·if·this·is·the·first·frame·of | ||
371 | a·fragmented·message.</p></li> | 371 | a·fragmented·message.</p></li> |
372 | </ul> | 372 | </ul> |
373 | </dd> | 373 | </dd> |
374 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 374 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
375 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> | 375 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·in·progress.</p> |
376 | </dd> | 376 | </dd> |
377 | </dl> | 377 | </dl> |
Offset 380, 16 lines modified | Offset 380, 16 lines modified | ||
380 | <dl·class="py·method"> | 380 | <dl·class="py·method"> |
381 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_close"> | 381 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_close"> |
382 | <span·class="sig-name·descname"><span·class="pre">send_close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">code</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">reason</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">''</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_close"·title="Link·to·this·definition">#</a></dt> | 382 | <span·class="sig-name·descname"><span·class="pre">send_close</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">code</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">reason</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">''</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_close"·title="Link·to·this·definition">#</a></dt> |
383 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1">Close·frame</a>.</p> | 383 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1">Close·frame</a>.</p> |
384 | <dl·class="field-list·simple"> | 384 | <dl·class="field-list·simple"> |
385 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 385 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
386 | <dd·class="field-odd"><ul·class="simple"> | 386 | <dd·class="field-odd"><ul·class="simple"> |
387 | <li><p><strong>code</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·close·code.</p></li> | ||
388 | <li><p><strong> | 387 | <li><p><strong>code</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·close·code.</p></li> |
388 | <li><p><strong>reason</strong>·(<em>str</em>)·–·close·reason.</p></li> | ||
389 | </ul> | 389 | </ul> |
390 | </dd> | 390 | </dd> |
391 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 391 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
392 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·being·sent,·if·the·code | 392 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·is·being·sent,·if·the·code |
393 | ····isn’t·valid,·or·if·a·reason·is·provided·without·a·code</p> | 393 | ····isn’t·valid,·or·if·a·reason·is·provided·without·a·code</p> |
394 | </dd> | 394 | </dd> |
395 | </dl> | 395 | </dl> |
Offset 397, 39 lines modified | Offset 397, 39 lines modified | ||
397 | <dl·class="py·method"> | 397 | <dl·class="py·method"> |
398 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_ping"> | 398 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Protocol.send_ping"> |
399 | <span·class="sig-name·descname"><span·class="pre">send_ping</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_ping"·title="Link·to·this·definition">#</a></dt> | 399 | <span·class="sig-name·descname"><span·class="pre">send_ping</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.protocol.Protocol.send_ping"·title="Link·to·this·definition">#</a></dt> |
400 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2">Ping·frame</a>.</p> | 400 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2">Ping·frame</a>.</p> |
401 | <dl·class="field-list·simple"> | 401 | <dl·class="field-list·simple"> |
402 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 402 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
Max diff block lines reached; 14267/31771 bytes (44.91%) of diff not shown. |
Offset 274, 29 lines modified | Offset 274, 29 lines modified | ||
274 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol"> | 274 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol"> |
275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">ServerProtocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">state</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">State.CONNECTING</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol"·title="Link·to·this·definition">#</a></dt> | 275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.server.</span></span><span·class="sig-name·descname"><span·class="pre">ServerProtocol</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">state</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">State.CONNECTING</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol"·title="Link·to·this·definition">#</a></dt> |
276 | <dd><p>Sans-I/O·implementation·of·a·WebSocket·server·connection.</p> | 276 | <dd><p>Sans-I/O·implementation·of·a·WebSocket·server·connection.</p> |
277 | <dl·class="field-list·simple"> | 277 | <dl·class="field-list·simple"> |
278 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 278 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
279 | <dd·class="field-odd"><ul·class="simple"> | 279 | <dd·class="field-odd"><ul·class="simple"> |
280 | <li><p><strong>origins</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em><em>]</em><em>]</em>)·–·acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header;·include | 280 | <li><p><strong>origins</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>]</em><em>]</em><em>]</em>)·–·acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header;·include |
281 | < | 281 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·in·the·list·if·the·lack·of·an·origin·is·acceptable. |
282 | This·is·useful·for·defending·against·Cross-Site·WebSocket | 282 | This·is·useful·for·defending·against·Cross-Site·WebSocket |
283 | Hijacking·attacks.</p></li> | 283 | Hijacking·attacks.</p></li> |
284 | <li><p><strong>extensions</strong>·(< | 284 | <li><p><strong>extensions</strong>·(<em>List</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.Extension"·title="websockets.extensions.base.Extension"><em>Extension</em></a><em>]</em>)·–·list·of·supported·extensions,·in·order·in·which·they |
285 | should·be·tried.</p></li> | 285 | should·be·tried.</p></li> |
286 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·list·of·supported·subprotocols,·in·order·of·decreasing | 286 | <li><p><strong>subprotocols</strong>·(<em>Optional</em><em>[</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em>)·–·list·of·supported·subprotocols,·in·order·of·decreasing |
287 | preference.</p></li> | 287 | preference.</p></li> |
288 | <li><p><strong>select_subprotocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><em>ServerProtocol</em></a><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>,·</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>]</em>)·–·Callback·for·selecting·a·subprotocol·among | 288 | <li><p><strong>select_subprotocol</strong>·(<em>Optional</em><em>[</em><em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><em>ServerProtocol</em></a><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>,·</em><em>Optional</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em><em>]</em><em>]</em>)·–·Callback·for·selecting·a·subprotocol·among |
289 | those·supported·by·the·client·and·the·server.·It·has·the·same | 289 | those·supported·by·the·client·and·the·server.·It·has·the·same |
290 | signature·as·the·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.select_subprotocol"·title="websockets.server.ServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">select_subprotocol()</span></code></a>·method,·including·a | 290 | signature·as·the·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.select_subprotocol"·title="websockets.server.ServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">select_subprotocol()</span></code></a>·method,·including·a |
291 | <a·class="reference·internal"·href="#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerProtocol</span></code></a>·instance·as·first·argument.</p></li> | 291 | <a·class="reference·internal"·href="#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerProtocol</span></code></a>·instance·as·first·argument.</p></li> |
292 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="../common/#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> | 292 | <li><p><strong>state</strong>·(<a·class="reference·internal"·href="../common/#websockets.protocol.State"·title="websockets.protocol.State"><em>State</em></a>)·–·initial·state·of·the·WebSocket·connection.</p></li> |
293 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; | ||
294 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·limit.</p></li> | ||
295 | <li><p><strong> | 293 | <li><p><strong>max_size</strong>·(<em>Optional</em><em>[</em><em>int</em><em>]</em>)·–·maximum·size·of·incoming·messages·in·bytes; |
294 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
295 | <li><p><strong>logger</strong>·(<em>Logger</em><em>·|·</em><em>LoggerAdapter</em>)·–·logger·for·this·connection; | ||
296 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>; | 296 | defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>; |
297 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 297 | see·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
298 | </ul> | 298 | </ul> |
299 | </dd> | 299 | </dd> |
300 | </dl> | 300 | </dl> |
301 | <dl·class="py·method"> | 301 | <dl·class="py·method"> |
302 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.receive_data"> | 302 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.receive_data"> |
Offset 305, 15 lines modified | Offset 305, 15 lines modified | ||
305 | <p>After·calling·this·method:</p> | 305 | <p>After·calling·this·method:</p> |
306 | <ul·class="simple"> | 306 | <ul·class="simple"> |
307 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.data_to_send"·title="websockets.server.ServerProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> | 307 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.data_to_send"·title="websockets.server.ServerProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network.</p></li> |
308 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.events_received"·title="websockets.server.ServerProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> | 308 | <li><p>You·should·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.events_received"·title="websockets.server.ServerProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·and·process·resulting·events.</p></li> |
309 | </ul> | 309 | </ul> |
310 | <dl·class="field-list·simple"> | 310 | <dl·class="field-list·simple"> |
311 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 311 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
312 | <dd·class="field-odd"><p>< | 312 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.receive_eof"·title="websockets.server.ServerProtocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
313 | </dd> | 313 | </dd> |
314 | </dl> | 314 | </dl> |
315 | </dd></dl> | 315 | </dd></dl> |
316 | <dl·class="py·method"> | 316 | <dl·class="py·method"> |
317 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.receive_eof"> | 317 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.receive_eof"> |
318 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.receive_eof"·title="Link·to·this·definition">#</a></dt> | 318 | <span·class="sig-name·descname"><span·class="pre">receive_eof</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.receive_eof"·title="Link·to·this·definition">#</a></dt> |
Offset 323, 15 lines modified | Offset 323, 15 lines modified | ||
323 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.data_to_send"·title="websockets.server.ServerProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; | 323 | <li><p>You·must·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.data_to_send"·title="websockets.server.ServerProtocol.data_to_send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">data_to_send()</span></code></a>·and·send·this·data·to·the·network; |
324 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> | 324 | it·will·return·<code·class="docutils·literal·notranslate"><span·class="pre">[b""]</span></code>,·signaling·the·end·of·the·stream,·or·<code·class="docutils·literal·notranslate"><span·class="pre">[]</span></code>.</p></li> |
325 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.events_received"·title="websockets.server.ServerProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return | 325 | <li><p>You·aren’t·expected·to·call·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.events_received"·title="websockets.server.ServerProtocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>;·it·won’t·return |
326 | any·new·events.</p></li> | 326 | any·new·events.</p></li> |
327 | </ul> | 327 | </ul> |
328 | <dl·class="field-list·simple"> | 328 | <dl·class="field-list·simple"> |
329 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> | 329 | <dt·class="field-odd">Raises<span·class="colon">:</span></dt> |
330 | <dd·class="field-odd"><p>< | 330 | <dd·class="field-odd"><p><strong>EOFError</strong>·–·if·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.receive_eof"·title="websockets.server.ServerProtocol.receive_eof"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">receive_eof()</span></code></a>·was·called·earlier.</p> |
331 | </dd> | 331 | </dd> |
332 | </dl> | 332 | </dl> |
333 | </dd></dl> | 333 | </dd></dl> |
334 | <dl·class="py·method"> | 334 | <dl·class="py·method"> |
335 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.accept"> | 335 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.accept"> |
336 | <span·class="sig-name·descname"><span·class="pre">accept</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">request</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.accept"·title="Link·to·this·definition">#</a></dt> | 336 | <span·class="sig-name·descname"><span·class="pre">accept</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">request</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.accept"·title="Link·to·this·definition">#</a></dt> |
Offset 371, 20 lines modified | Offset 371, 20 lines modified | ||
371 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">def</span>·<span·class="nf">select_subprotocol</span><span·class="p">(</span><span·class="n">protocol</span><span·class="p">,</span>·<span·class="n">subprotocols</span><span·class="p">):</span> | 371 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">def</span>·<span·class="nf">select_subprotocol</span><span·class="p">(</span><span·class="n">protocol</span><span·class="p">,</span>·<span·class="n">subprotocols</span><span·class="p">):</span> |
372 | ····<span·class="k">if</span>·<span·class="s2">"chat"</span>·<span·class="ow">in</span>·<span·class="n">subprotocols</span><span·class="p">:</span> | 372 | ····<span·class="k">if</span>·<span·class="s2">"chat"</span>·<span·class="ow">in</span>·<span·class="n">subprotocols</span><span·class="p">:</span> |
373 | ········<span·class="k">return</span>·<span·class="s2">"chat"</span> | 373 | ········<span·class="k">return</span>·<span·class="s2">"chat"</span> |
374 | </pre></div> | 374 | </pre></div> |
375 | </div> | 375 | </div> |
376 | <dl·class="field-list·simple"> | 376 | <dl·class="field-list·simple"> |
377 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 377 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
378 | <dd·class="field-odd"><p><strong>subprotocols</strong>·(< | 378 | <dd·class="field-odd"><p><strong>subprotocols</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]</em>)·–·list·of·subprotocols·offered·by·the·client.</p> |
379 | </dd> | 379 | </dd> |
380 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> | 380 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> |
381 | <dd·class="field-even"><p><p>Selected·subprotocol,·if·a·common·subprotocol | 381 | <dd·class="field-even"><p><p>Selected·subprotocol,·if·a·common·subprotocol |
382 | was·found.</p> | 382 | was·found.</p> |
383 | <p>< | 383 | <p><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·continue·without·a·subprotocol.</p> |
384 | </p> | 384 | </p> |
385 | </dd> | 385 | </dd> |
386 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> | 386 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> |
387 | <dd·class="field-odd"><p>Optional[<a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol">Subprotocol</a>]</p> | 387 | <dd·class="field-odd"><p>Optional[<a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol">Subprotocol</a>]</p> |
388 | </dd> | 388 | </dd> |
389 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 389 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
390 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.NegotiationError"·title="websockets.exceptions.NegotiationError"><strong>NegotiationError</strong></a>·–·custom·implementations·may·raise·this·exception | 390 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.NegotiationError"·title="websockets.exceptions.NegotiationError"><strong>NegotiationError</strong></a>·–·custom·implementations·may·raise·this·exception |
Offset 400, 16 lines modified | Offset 400, 16 lines modified | ||
400 | <p>A·short·plain·text·response·is·the·best·fallback·when·failing·to | 400 | <p>A·short·plain·text·response·is·the·best·fallback·when·failing·to |
401 | establish·a·WebSocket·connection.</p> | 401 | establish·a·WebSocket·connection.</p> |
402 | <p>You·must·send·the·handshake·response·with·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.send_response"·title="websockets.server.ServerProtocol.send_response"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send_response()</span></code></a>.</p> | 402 | <p>You·must·send·the·handshake·response·with·<a·class="reference·internal"·href="#websockets.server.ServerProtocol.send_response"·title="websockets.server.ServerProtocol.send_response"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send_response()</span></code></a>.</p> |
403 | <p>You·can·modify·it·before·sending·it,·for·example·to·alter·HTTP·headers.</p> | 403 | <p>You·can·modify·it·before·sending·it,·for·example·to·alter·HTTP·headers.</p> |
404 | <dl·class="field-list·simple"> | 404 | <dl·class="field-list·simple"> |
405 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 405 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
406 | <dd·class="field-odd"><ul·class="simple"> | 406 | <dd·class="field-odd"><ul·class="simple"> |
407 | <li><p><strong>status</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/http.html#http.HTTPStatus"·title="(in·Python·v3.12)"><em>HTTPStatus</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a>)·–·HTTP·status·code.</p></li> | ||
408 | <li><p><strong>t | 407 | <li><p><strong>status</strong>·(<em>HTTPStatus</em><em>·|·</em><em>int</em>)·–·HTTP·status·code.</p></li> |
408 | <li><p><strong>text</strong>·(<em>str</em>)·–·HTTP·response·body;·will·be·encoded·to·UTF-8.</p></li> | ||
409 | </ul> | 409 | </ul> |
410 | </dd> | 410 | </dd> |
411 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> | 411 | <dt·class="field-even">Returns<span·class="colon">:</span></dt> |
412 | <dd·class="field-even"><p>WebSocket·handshake·response·event·to·send·to·the·client.</p> | 412 | <dd·class="field-even"><p>WebSocket·handshake·response·event·to·send·to·the·client.</p> |
413 | </dd> | 413 | </dd> |
414 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> | 414 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> |
415 | <dd·class="field-odd"><p><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Response"·title="websockets.http11.Response">Response</a></p> | 415 | <dd·class="field-odd"><p><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Response"·title="websockets.http11.Response">Response</a></p> |
Offset 431, 18 lines modified | Offset 431, 18 lines modified | ||
431 | <dl·class="py·method"> | 431 | <dl·class="py·method"> |
432 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.send_continuation"> | 432 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.send_continuation"> |
433 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.send_continuation"·title="Link·to·this·definition">#</a></dt> | 433 | <span·class="sig-name·descname"><span·class="pre">send_continuation</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.send_continuation"·title="Link·to·this·definition">#</a></dt> |
434 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> | 434 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Continuation·frame</a>.</p> |
435 | <dl·class="field-list·simple"> | 435 | <dl·class="field-list·simple"> |
436 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 436 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
437 | <dd·class="field-odd"><ul·class="simple"> | 437 | <dd·class="field-odd"><ul·class="simple"> |
438 | <li><p><strong>data</strong>·(< | 438 | <li><p><strong>data</strong>·(<em>bytes</em>)·–·payload·containing·the·same·kind·of·data |
439 | as·the·initial·frame.</p></li> | 439 | as·the·initial·frame.</p></li> |
440 | <li><p><strong>fin</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#bool"·title="(in·Python·v3.12)"><em>bool</em></a>)·–·FIN·bit;·set·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#True"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code></a>·if·this·is·the·last·frame | ||
441 | 440 | <li><p><strong>fin</strong>·(<em>bool</em>)·–·FIN·bit;·set·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">True</span></code>·if·this·is·the·last·frame | |
441 | of·a·fragmented·message·and·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">False</span></code>·otherwise.</p></li> | ||
442 | </ul> | 442 | </ul> |
443 | </dd> | 443 | </dd> |
444 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 444 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
445 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> | 445 | <dd·class="field-even"><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ProtocolError"·title="websockets.exceptions.ProtocolError"><strong>ProtocolError</strong></a>·–·if·a·fragmented·message·isn’t·in·progress.</p> |
446 | </dd> | 446 | </dd> |
447 | </dl> | 447 | </dl> |
448 | </dd></dl> | 448 | </dd></dl> |
Offset 450, 16 lines modified | Offset 450, 16 lines modified | ||
450 | <dl·class="py·method"> | 450 | <dl·class="py·method"> |
451 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.send_text"> | 451 | <dt·class="sig·sig-object·py"·id="websockets.server.ServerProtocol.send_text"> |
452 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.send_text"·title="Link·to·this·definition">#</a></dt> | 452 | <span·class="sig-name·descname"><span·class="pre">send_text</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">data</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">fin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">True</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.server.ServerProtocol.send_text"·title="Link·to·this·definition">#</a></dt> |
453 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> | 453 | <dd><p>Send·a·<a·class="reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6455#section-5.6">Text·frame</a>.</p> |
Max diff block lines reached; 21947/40982 bytes (53.55%) of diff not shown. |
Offset 267, 15 lines modified | Offset 267, 15 lines modified | ||
267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
270 | ··········</label> | 270 | ··········</label> |
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="module-websockets.sync.client"> | 273 | ··········<section·id="module-websockets.sync.client"> |
274 | <span·id="client-threading"></span><h1>Client·(< | 274 | <span·id="client-threading"></span><h1>Client·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)<a·class="headerlink"·href="#module-websockets.sync.client"·title="Link·to·this·heading">#</a></h1> |
275 | <section·id="opening-a-connection"> | 275 | <section·id="opening-a-connection"> |
276 | <h2>Opening·a·connection<a·class="headerlink"·href="#opening-a-connection"·title="Link·to·this·heading">#</a></h2> | 276 | <h2>Opening·a·connection<a·class="headerlink"·href="#opening-a-connection"·title="Link·to·this·heading">#</a></h2> |
277 | <dl·class="py·function"> | 277 | <dl·class="py·function"> |
278 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.connect"> | 278 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.connect"> |
279 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.client.</span></span><span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">sock</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ssl_context</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_hostname</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">additional_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_connection</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.client.connect"·title="Link·to·this·definition">#</a></dt> | 279 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.client.</span></span><span·class="sig-name·descname"><span·class="pre">connect</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">uri</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">sock</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ssl_context</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_hostname</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origin</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">additional_headers</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">user_agent_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_connection</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.client.connect"·title="Link·to·this·definition">#</a></dt> |
280 | <dd><p>Connect·to·the·WebSocket·server·at·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p> | 280 | <dd><p>Connect·to·the·WebSocket·server·at·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p> |
281 | <p>This·function·returns·a·<a·class="reference·internal"·href="#websockets.sync.client.ClientConnection"·title="websockets.sync.client.ClientConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientConnection</span></code></a>·instance,·which·you·can | 281 | <p>This·function·returns·a·<a·class="reference·internal"·href="#websockets.sync.client.ClientConnection"·title="websockets.sync.client.ClientConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientConnection</span></code></a>·instance,·which·you·can |
Offset 285, 54 lines modified | Offset 285, 54 lines modified | ||
285 | ····<span·class="o">...</span> | 285 | ····<span·class="o">...</span> |
286 | </pre></div> | 286 | </pre></div> |
287 | </div> | 287 | </div> |
288 | <p>The·connection·is·closed·automatically·when·exiting·the·context.</p> | 288 | <p>The·connection·is·closed·automatically·when·exiting·the·context.</p> |
289 | <dl·class="field-list·simple"> | 289 | <dl·class="field-list·simple"> |
290 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 290 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
291 | <dd·class="field-odd"><ul·class="simple"> | 291 | <dd·class="field-odd"><ul·class="simple"> |
292 | <li><p><strong>uri</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a>)·–·URI·of·the·WebSocket·server.</p></li> | ||
293 | <li><p><strong>sock</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/socket.html#socket.socket"·title="(in·Python·v3.12)"><em>socket</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Preexisting·TCP·socket.·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·overrides·the·host·and·port | ||
294 | 292 | <li><p><strong>uri</strong>·(<em>str</em>)·–·URI·of·the·WebSocket·server.</p></li> | |
293 | <li><p><strong>sock</strong>·(<em>socket</em><em>·|·</em><em>None</em>)·–·Preexisting·TCP·socket.·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·overrides·the·host·and·port | ||
294 | from·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.·You·may·call·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">socket.create_connection()</span></code>·to | ||
295 | create·a·suitable·TCP·socket.</p></li> | 295 | create·a·suitable·TCP·socket.</p></li> |
296 | <li><p><strong>ssl_context</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/ssl.html#ssl.SSLContext"·title="(in·Python·v3.12)"><em>SSLContext</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Configuration·for·enabling·TLS·on·the·connection.</p></li> | ||
297 | <li><p><strong>s | 296 | <li><p><strong>ssl_context</strong>·(<em>SSLContext</em><em>·|·</em><em>None</em>)·–·Configuration·for·enabling·TLS·on·the·connection.</p></li> |
297 | <li><p><strong>server_hostname</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·Host·name·for·the·TLS·handshake.·<code·class="docutils·literal·notranslate"><span·class="pre">server_hostname</span></code> | ||
298 | overrides·the·host·name·from·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p></li> | 298 | overrides·the·host·name·from·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>.</p></li> |
299 | <li><p><strong>origin</strong>·(<a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>·|·</em>< | 299 | <li><p><strong>origin</strong>·(<a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>·|·</em><em>None</em>)·–·Value·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·servers·that·require·it.</p></li> |
300 | <li><p><strong>extensions</strong>·(< | 300 | <li><p><strong>extensions</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ClientExtensionFactory"·title="websockets.extensions.base.ClientExtensionFactory"><em>ClientExtensionFactory</em></a><em>]·</em><em>|·</em><em>None</em>)·–·List·of·supported·extensions,·in·order·in·which·they |
301 | should·be·negotiated·and·run.</p></li> | 301 | should·be·negotiated·and·run.</p></li> |
302 | <li><p><strong>subprotocols</strong>·(< | 302 | <li><p><strong>subprotocols</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]·</em><em>|·</em><em>None</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing |
303 | preference.</p></li> | 303 | preference.</p></li> |
304 | <li><p><strong>additional_headers</strong>·(<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>·|·</em>< | 304 | <li><p><strong>additional_headers</strong>·(<a·class="reference·internal"·href="../../types/#websockets.datastructures.HeadersLike"·title="websockets.datastructures.HeadersLike"><em>HeadersLike</em></a><em>·|·</em><em>None</em>)·–·Arbitrary·HTTP·headers·to·add |
305 | to·the·handshake·request.</p></li> | 305 | to·the·handshake·request.</p></li> |
306 | <li><p><strong>user_agent_header</strong>·(< | 306 | <li><p><strong>user_agent_header</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·Value·of··the·<code·class="docutils·literal·notranslate"><span·class="pre">User-Agent</span></code>·request·header. |
307 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. | 307 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>. |
308 | Setting·it·to·<a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·removes·the·header.</p></li> | ||
309 | 308 | Setting·it·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·removes·the·header.</p></li> | |
309 | <li><p><strong>compression</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·The·“permessage-deflate”·extension·is·enabled·by·default. | ||
310 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·< | 310 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·it.·See·the |
311 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> | 311 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> |
312 | <li><p><strong>open_timeout</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Timeout·for·opening·the·connection·in·seconds. | ||
313 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·timeout.</p></li> | ||
314 | <li><p><strong>close_timeout</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Timeout·for·closing·the·connection·in·seconds. | ||
315 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·timeout.</p></li> | ||
316 | <li><p><strong>max_size</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Maximum·size·of·incoming·messages·in·bytes. | ||
317 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·limit.</p></li> | ||
318 | <li><p><strong> | 312 | <li><p><strong>open_timeout</strong>·(<em>float</em><em>·|·</em><em>None</em>)·–·Timeout·for·opening·the·connection·in·seconds. |
313 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
314 | <li><p><strong>close_timeout</strong>·(<em>float</em><em>·|·</em><em>None</em>)·–·Timeout·for·closing·the·connection·in·seconds. | ||
315 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
316 | <li><p><strong>max_size</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·Maximum·size·of·incoming·messages·in·bytes. | ||
317 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
318 | <li><p><strong>logger</strong>·(<em>Logger</em><em>·|·</em><em>LoggerAdapter</em><em>·|·</em><em>None</em>)·–·Logger·for·this·client. | ||
319 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>. | 319 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.client")</span></code>. |
320 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 320 | See·the·<a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
321 | <li><p><strong>create_connection</strong>·(< | 321 | <li><p><strong>create_connection</strong>·(<em>Type</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.client.ClientConnection"·title="websockets.sync.client.ClientConnection"><em>ClientConnection</em></a><em>]·</em><em>|·</em><em>None</em>)·–·Factory·for·the·<a·class="reference·internal"·href="#websockets.sync.client.ClientConnection"·title="websockets.sync.client.ClientConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ClientConnection</span></code></a>·managing |
322 | the·connection.·Set·it·to·a·wrapper·or·a·subclass·to·customize | 322 | the·connection.·Set·it·to·a·wrapper·or·a·subclass·to·customize |
323 | connection·handling.</p></li> | 323 | connection·handling.</p></li> |
324 | </ul> | 324 | </ul> |
325 | </dd> | 325 | </dd> |
326 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 326 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
327 | <dd·class="field-even"><ul·class="simple"> | 327 | <dd·class="field-even"><ul·class="simple"> |
328 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidURI"·title="websockets.exceptions.InvalidURI"><strong>InvalidURI</strong></a>·–·If·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·isn’t·a·valid·WebSocket·URI.</p></li> | 328 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidURI"·title="websockets.exceptions.InvalidURI"><strong>InvalidURI</strong></a>·–·If·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·isn’t·a·valid·WebSocket·URI.</p></li> |
329 | <li><p>< | 329 | <li><p><strong>OSError</strong>·–·If·the·TCP·connection·fails.</p></li> |
330 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidHandshake"·title="websockets.exceptions.InvalidHandshake"><strong>InvalidHandshake</strong></a>·–·If·the·opening·handshake·fails.</p></li> | 330 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.InvalidHandshake"·title="websockets.exceptions.InvalidHandshake"><strong>InvalidHandshake</strong></a>·–·If·the·opening·handshake·fails.</p></li> |
331 | <li><p>< | 331 | <li><p><strong>TimeoutError</strong>·–·If·the·opening·handshake·times·out.</p></li> |
332 | </ul> | 332 | </ul> |
333 | </dd> | 333 | </dd> |
334 | </dl> | 334 | </dl> |
335 | </dd></dl> | 335 | </dd></dl> |
336 | <dl·class="py·function"> | 336 | <dl·class="py·function"> |
337 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.unix_connect"> | 337 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.unix_connect"> |
Offset 340, 16 lines modified | Offset 340, 16 lines modified | ||
340 | <dd><p>Connect·to·a·WebSocket·server·listening·on·a·Unix·socket.</p> | 340 | <dd><p>Connect·to·a·WebSocket·server·listening·on·a·Unix·socket.</p> |
341 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.sync.client.connect"·title="websockets.sync.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>,·except·for·the·additional | 341 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.sync.client.connect"·title="websockets.sync.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>,·except·for·the·additional |
342 | <code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>·argument.·It’s·only·available·on·Unix.</p> | 342 | <code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>·argument.·It’s·only·available·on·Unix.</p> |
343 | <p>It’s·mainly·useful·for·debugging·servers·listening·on·Unix·sockets.</p> | 343 | <p>It’s·mainly·useful·for·debugging·servers·listening·on·Unix·sockets.</p> |
344 | <dl·class="field-list·simple"> | 344 | <dl·class="field-list·simple"> |
345 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 345 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
346 | <dd·class="field-odd"><ul·class="simple"> | 346 | <dd·class="field-odd"><ul·class="simple"> |
347 | <li><p><strong>path</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·File·system·path·to·the·Unix·socket.</p></li> | ||
348 | <li><p><strong> | 347 | <li><p><strong>path</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·File·system·path·to·the·Unix·socket.</p></li> |
348 | <li><p><strong>uri</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·URI·of·the·WebSocket·server.·<code·class="docutils·literal·notranslate"><span·class="pre">uri</span></code>·defaults·to | ||
349 | <code·class="docutils·literal·notranslate"><span·class="pre">ws://localhost/</span></code>·or,·when·a·<code·class="docutils·literal·notranslate"><span·class="pre">ssl_context</span></code>·is·provided,·to | 349 | <code·class="docutils·literal·notranslate"><span·class="pre">ws://localhost/</span></code>·or,·when·a·<code·class="docutils·literal·notranslate"><span·class="pre">ssl_context</span></code>·is·provided,·to |
350 | <code·class="docutils·literal·notranslate"><span·class="pre">wss://localhost/</span></code>.</p></li> | 350 | <code·class="docutils·literal·notranslate"><span·class="pre">wss://localhost/</span></code>.</p></li> |
351 | </ul> | 351 | </ul> |
352 | </dd> | 352 | </dd> |
353 | </dl> | 353 | </dl> |
354 | </dd></dl> | 354 | </dd></dl> |
Offset 370, 17 lines modified | Offset 370, 17 lines modified | ||
370 | <p>The·iterator·exits·normally·when·the·connection·is·closed·with·close·code | 370 | <p>The·iterator·exits·normally·when·the·connection·is·closed·with·close·code |
371 | 1000·(OK)·or·1001·(going·away)·or·without·a·close·code.·It·raises·a | 371 | 1000·(OK)·or·1001·(going·away)·or·without·a·close·code.·It·raises·a |
372 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·when·the·connection·is | 372 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·when·the·connection·is |
373 | closed·with·any·other·code.</p> | 373 | closed·with·any·other·code.</p> |
374 | <dl·class="field-list·simple"> | 374 | <dl·class="field-list·simple"> |
375 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 375 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
376 | <dd·class="field-odd"><ul·class="simple"> | 376 | <dd·class="field-odd"><ul·class="simple"> |
377 | <li><p><strong>socket</strong>·(< | 377 | <li><p><strong>socket</strong>·(<em>socket.socket</em>)·–·Socket·connected·to·a·WebSocket·server.</p></li> |
378 | <li><p><strong>protocol</strong>·(<a·class="reference·internal"·href="../../sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><em>ClientProtocol</em></a>)·–·Sans-I/O·connection.</p></li> | 378 | <li><p><strong>protocol</strong>·(<a·class="reference·internal"·href="../../sansio/client/#websockets.client.ClientProtocol"·title="websockets.client.ClientProtocol"><em>ClientProtocol</em></a>)·–·Sans-I/O·connection.</p></li> |
379 | <li><p><strong>close_timeout</strong>·(<em>Optional</em><em>[</em>< | 379 | <li><p><strong>close_timeout</strong>·(<em>Optional</em><em>[</em><em>float</em><em>]</em>)·–·Timeout·for·closing·the·connection·in·seconds.</p></li> |
380 | </ul> | 380 | </ul> |
381 | </dd> | 381 | </dd> |
382 | </dl> | 382 | </dl> |
383 | <dl·class="py·method"> | 383 | <dl·class="py·method"> |
384 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.ClientConnection.__iter__"> | 384 | <dt·class="sig·sig-object·py"·id="websockets.sync.client.ClientConnection.__iter__"> |
385 | <em·class="property"><span·class="pre">for</span>·<span·class="pre">...</span>·<span·class="pre">in</span>·</em><span·class="sig-name·descname"><span·class="pre">__iter__</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.client.ClientConnection.__iter__"·title="Link·to·this·definition">#</a></dt> | 385 | <em·class="property"><span·class="pre">for</span>·<span·class="pre">...</span>·<span·class="pre">in</span>·</em><span·class="sig-name·descname"><span·class="pre">__iter__</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.client.ClientConnection.__iter__"·title="Link·to·this·definition">#</a></dt> |
386 | <dd><p>Iterate·on·incoming·messages.</p> | 386 | <dd><p>Iterate·on·incoming·messages.</p> |
Offset 398, 96 lines modified | Offset 398, 96 lines modified | ||
398 | <dd><p>Receive·the·next·message.</p> | 398 | <dd><p>Receive·the·next·message.</p> |
399 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.client.ClientConnection.recv"·title="websockets.sync.client.ClientConnection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·raises | 399 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.client.ClientConnection.recv"·title="websockets.sync.client.ClientConnection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·raises |
400 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it·raises | 400 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it·raises |
401 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal·closure | 401 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal·closure |
402 | and·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol | 402 | and·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol |
403 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the | 403 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the |
404 | message·stream.</p> | 404 | message·stream.</p> |
405 | <p>If·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·< | 405 | <p>If·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>,·block·until·a·message·is·received.·If |
406 | <code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·set·and·no·message·is·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code> | 406 | <code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·set·and·no·message·is·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code> |
407 | seconds,·raise·< | 407 | seconds,·raise·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">TimeoutError</span></code>.·Set·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·to·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·to·check·if |
Max diff block lines reached; 34197/61540 bytes (55.57%) of diff not shown. |
Offset 265, 15 lines modified | Offset 265, 15 lines modified | ||
265 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 265 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
266 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 266 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
267 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 267 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
268 | ··········</label> | 268 | ··········</label> |
269 | ········</div> | 269 | ········</div> |
270 | ········<article·role="main"> | 270 | ········<article·role="main"> |
271 | ··········<section·id="module-websockets.sync.connection"> | 271 | ··········<section·id="module-websockets.sync.connection"> |
272 | <span·id="both-sides-threading"></span><h1>Both·sides·(< | 272 | <span·id="both-sides-threading"></span><h1>Both·sides·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)<a·class="headerlink"·href="#module-websockets.sync.connection"·title="Link·to·this·heading">#</a></h1> |
273 | <dl·class="py·class"> | 273 | <dl·class="py·class"> |
274 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection"> | 274 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection"> |
275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.connection.</span></span><span·class="sig-name·descname"><span·class="pre">Connection</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">socket</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">protocol</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection"·title="Link·to·this·definition">#</a></dt> | 275 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.connection.</span></span><span·class="sig-name·descname"><span·class="pre">Connection</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">socket</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">protocol</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection"·title="Link·to·this·definition">#</a></dt> |
276 | <dd><p>Threaded·implementation·of·a·WebSocket·connection.</p> | 276 | <dd><p>Threaded·implementation·of·a·WebSocket·connection.</p> |
277 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection"·title="websockets.sync.connection.Connection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Connection</span></code></a>·provides·APIs·shared·between·WebSocket·servers·and | 277 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection"·title="websockets.sync.connection.Connection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Connection</span></code></a>·provides·APIs·shared·between·WebSocket·servers·and |
278 | clients.</p> | 278 | clients.</p> |
279 | <p>You·shouldn’t·use·it·directly.·Instead,·use | 279 | <p>You·shouldn’t·use·it·directly.·Instead,·use |
Offset 299, 96 lines modified | Offset 299, 96 lines modified | ||
299 | <dd><p>Receive·the·next·message.</p> | 299 | <dd><p>Receive·the·next·message.</p> |
300 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·raises | 300 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·raises |
301 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it·raises | 301 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it·raises |
302 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal·closure | 302 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal·closure |
303 | and·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol | 303 | and·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol |
304 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the | 304 | error·or·a·network·failure.·This·is·how·you·detect·the·end·of·the |
305 | message·stream.</p> | 305 | message·stream.</p> |
306 | <p>If·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·< | 306 | <p>If·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>,·block·until·a·message·is·received.·If |
307 | <code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·set·and·no·message·is·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code> | 307 | <code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·is·set·and·no·message·is·received·within·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code> |
308 | seconds,·raise·< | 308 | seconds,·raise·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">TimeoutError</span></code>.·Set·<code·class="docutils·literal·notranslate"><span·class="pre">timeout</span></code>·to·<code·class="docutils·literal·notranslate"><span·class="pre">0</span></code>·to·check·if |
309 | a·message·was·already·received.</p> | 309 | a·message·was·already·received.</p> |
310 | <p>If·the·message·is·fragmented,·wait·until·all·fragments·are·received, | 310 | <p>If·the·message·is·fragmented,·wait·until·all·fragments·are·received, |
311 | reassemble·them,·and·return·the·whole·message.</p> | 311 | reassemble·them,·and·return·the·whole·message.</p> |
312 | <dl·class="field-list·simple"> | 312 | <dl·class="field-list·simple"> |
313 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> | 313 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> |
314 | <dd·class="field-odd"><p><p>A·string·(< | 314 | <dd·class="field-odd"><p><p>A·string·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame·or·a·bytestring |
315 | (< | 315 | (<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>·frame.</p> |
316 | </p> | 316 | </p> |
317 | </dd> | 317 | </dd> |
318 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 318 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
319 | <dd·class="field-even"><ul·class="simple"> | 319 | <dd·class="field-even"><ul·class="simple"> |
320 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> | 320 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> |
321 | <li><p>< | 321 | <li><p><strong>RuntimeError</strong>·–·If·two·threads·call·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·or |
322 | ····<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·concurrently.</p></li> | 322 | ····<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·concurrently.</p></li> |
323 | </ul> | 323 | </ul> |
324 | </dd> | 324 | </dd> |
325 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> | 325 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> |
326 | <dd·class="field-odd"><p> | 326 | <dd·class="field-odd"><p>str·|·bytes</p> |
327 | </dd> | 327 | </dd> |
328 | </dl> | 328 | </dl> |
329 | </dd></dl> | 329 | </dd></dl> |
330 | <dl·class="py·method"> | 330 | <dl·class="py·method"> |
331 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.recv_streaming"> | 331 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.recv_streaming"> |
332 | <em·class="property"><span·class="pre">for</span>·<span·class="pre">...</span>·<span·class="pre">in</span>·</em><span·class="sig-name·descname"><span·class="pre">recv_streaming</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection.recv_streaming"·title="Link·to·this·definition">#</a></dt> | 332 | <em·class="property"><span·class="pre">for</span>·<span·class="pre">...</span>·<span·class="pre">in</span>·</em><span·class="sig-name·descname"><span·class="pre">recv_streaming</span></span><span·class="sig-paren">(</span><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection.recv_streaming"·title="Link·to·this·definition">#</a></dt> |
333 | <dd><p>Receive·the·next·message·frame·by·frame.</p> | 333 | <dd><p>Receive·the·next·message·frame·by·frame.</p> |
334 | <p>If·the·message·is·fragmented,·yield·each·fragment·as·it·is·received. | 334 | <p>If·the·message·is·fragmented,·yield·each·fragment·as·it·is·received. |
335 | The·iterator·must·be·fully·consumed,·or·else·the·connection·will·become | 335 | The·iterator·must·be·fully·consumed,·or·else·the·connection·will·become |
336 | unusable.</p> | 336 | unusable.</p> |
337 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·raises·the·same·exceptions·as·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>.</p> | 337 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·raises·the·same·exceptions·as·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>.</p> |
338 | <dl·class="field-list·simple"> | 338 | <dl·class="field-list·simple"> |
339 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> | 339 | <dt·class="field-odd">Returns<span·class="colon">:</span></dt> |
340 | <dd·class="field-odd"><p><p>An·iterator·of·strings·(< | 340 | <dd·class="field-odd"><p><p>An·iterator·of·strings·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame·or |
341 | bytestrings·(< | 341 | bytestrings·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>)·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>·frame.</p> |
342 | </p> | 342 | </p> |
343 | </dd> | 343 | </dd> |
344 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 344 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
345 | <dd·class="field-even"><ul·class="simple"> | 345 | <dd·class="field-even"><ul·class="simple"> |
346 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> | 346 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> |
347 | <li><p>< | 347 | <li><p><strong>RuntimeError</strong>·–·If·two·threads·call·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>·or |
348 | ····<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·concurrently.</p></li> | 348 | ····<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv_streaming"·title="websockets.sync.connection.Connection.recv_streaming"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv_streaming()</span></code></a>·concurrently.</p></li> |
349 | </ul> | 349 | </ul> |
350 | </dd> | 350 | </dd> |
351 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> | 351 | <dt·class="field-odd">Return·type<span·class="colon">:</span></dt> |
352 | <dd·class="field-odd"><p>< | 352 | <dd·class="field-odd"><p><em>Iterator</em>[str·|·bytes]</p> |
353 | </dd> | 353 | </dd> |
354 | </dl> | 354 | </dl> |
355 | </dd></dl> | 355 | </dd></dl> |
356 | <dl·class="py·method"> | 356 | <dl·class="py·method"> |
357 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.send"> | 357 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.send"> |
358 | <span·class="sig-name·descname"><span·class="pre">send</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">message</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection.send"·title="Link·to·this·definition">#</a></dt> | 358 | <span·class="sig-name·descname"><span·class="pre">send</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">message</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.connection.Connection.send"·title="Link·to·this·definition">#</a></dt> |
359 | <dd><p>Send·a·message.</p> | 359 | <dd><p>Send·a·message.</p> |
360 | <p>A·string·(< | 360 | <p>A·string·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>)·is·sent·as·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame.·A·bytestring·or |
361 | bytes-like·object·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code></a>,·<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytearray"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytearray</span></code></a>,·or | ||
362 | 361 | bytes-like·object·(<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytearray</span></code>,·or | |
362 | <code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">memoryview</span></code>)·is·sent·as·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>·frame.</p> | ||
363 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·also·accepts·an·iterable·of·strings,·bytestrings,·or | 363 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·also·accepts·an·iterable·of·strings,·bytestrings,·or |
364 | bytes-like·objects·to·enable·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.4">fragmentation</a>.·Each·item·is·treated·as·a | 364 | bytes-like·objects·to·enable·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.4">fragmentation</a>.·Each·item·is·treated·as·a |
365 | message·fragment·and·sent·in·its·own·frame.·All·items·must·be·of·the | 365 | message·fragment·and·sent·in·its·own·frame.·All·items·must·be·of·the |
366 | same·type,·or·else·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·will·raise·a·< | 366 | same·type,·or·else·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·will·raise·a·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">TypeError</span></code>·and·the |
367 | connection·will·be·closed.</p> | 367 | connection·will·be·closed.</p> |
368 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·rejects·dict-like·objects·because·this·is·often·an·error. | 368 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·rejects·dict-like·objects·because·this·is·often·an·error. |
369 | (If·you·really·want·to·send·the·keys·of·a·dict-like·object·as·fragments, | 369 | (If·you·really·want·to·send·the·keys·of·a·dict-like·object·as·fragments, |
370 | call·its·< | 370 | call·its·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">keys()</span></code>·method·and·pass·the·result·to·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>.)</p> |
371 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises | 371 | <p>When·the·connection·is·closed,·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.send"·title="websockets.sync.connection.Connection.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·raises |
372 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it | 372 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>.·Specifically,·it |
373 | raises·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal | 373 | raises·<a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·after·a·normal |
374 | connection·closure·and | 374 | connection·closure·and |
375 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol | 375 | <a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosedError"·title="websockets.exceptions.ConnectionClosedError"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedError</span></code></a>·after·a·protocol |
376 | error·or·a·network·failure.</p> | 376 | error·or·a·network·failure.</p> |
377 | <dl·class="field-list·simple"> | 377 | <dl·class="field-list·simple"> |
378 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 378 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
379 | <dd·class="field-odd"><p><strong>message</strong>·(< | 379 | <dd·class="field-odd"><p><strong>message</strong>·(<em>str</em><em>·|·</em><em>bytes</em><em>·|·</em><em>Iterable</em><em>[</em><em>str</em><em>·|·</em><em>bytes</em><em>]</em>)·–·Message·to·send.</p> |
380 | </dd> | 380 | </dd> |
381 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> | 381 | <dt·class="field-even">Raises<span·class="colon">:</span></dt> |
382 | <dd·class="field-even"><ul·class="simple"> | 382 | <dd·class="field-even"><ul·class="simple"> |
383 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> | 383 | <li><p><a·class="reference·internal"·href="../../exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><strong>ConnectionClosed</strong></a>·–·When·the·connection·is·closed.</p></li> |
384 | <li><p><a·class="reference·external"·href="https://docs.python.org/3/library/exceptions.html#RuntimeError"·title="(in·Python·v3.12)"><strong>RuntimeError</strong></a>·–·If·a·connection·is·busy·sending·a·fragmented·message.</p></li> | ||
385 | <li><p>< | 384 | <li><p><strong>RuntimeError</strong>·–·If·a·connection·is·busy·sending·a·fragmented·message.</p></li> |
385 | <li><p><strong>TypeError</strong>·–·If·<code·class="docutils·literal·notranslate"><span·class="pre">message</span></code>·doesn’t·have·a·supported·type.</p></li> | ||
386 | </ul> | 386 | </ul> |
387 | </dd> | 387 | </dd> |
388 | </dl> | 388 | </dl> |
389 | </dd></dl> | 389 | </dd></dl> |
390 | <dl·class="py·method"> | 390 | <dl·class="py·method"> |
391 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.close"> | 391 | <dt·class="sig·sig-object·py"·id="websockets.sync.connection.Connection.close"> |
Offset 398, 119 lines modified | Offset 398, 119 lines modified | ||
398 | TCP·connection·to·terminate,·and·for·all·incoming·messages·to·be·read | 398 | TCP·connection·to·terminate,·and·for·all·incoming·messages·to·be·read |
399 | with·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>.</p> | 399 | with·<a·class="reference·internal"·href="#websockets.sync.connection.Connection.recv"·title="websockets.sync.connection.Connection.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a>.</p> |
400 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.close"·title="websockets.sync.connection.Connection.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·is·idempotent:·it·doesn’t·do·anything·once·the | 400 | <p><a·class="reference·internal"·href="#websockets.sync.connection.Connection.close"·title="websockets.sync.connection.Connection.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·is·idempotent:·it·doesn’t·do·anything·once·the |
401 | connection·is·closed.</p> | 401 | connection·is·closed.</p> |
402 | <dl·class="field-list·simple"> | 402 | <dl·class="field-list·simple"> |
403 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 403 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
404 | <dd·class="field-odd"><ul·class="simple"> | 404 | <dd·class="field-odd"><ul·class="simple"> |
405 | <li><p><strong>code</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a>)·–·WebSocket·close·code.</p></li> | ||
406 | <li><p><strong> | 405 | <li><p><strong>code</strong>·(<em>int</em>)·–·WebSocket·close·code.</p></li> |
406 | <li><p><strong>reason</strong>·(<em>str</em>)·–·WebSocket·close·reason.</p></li> | ||
407 | </ul> | 407 | </ul> |
408 | </dd> | 408 | </dd> |
Max diff block lines reached; 17022/40029 bytes (42.52%) of diff not shown. |
Offset 267, 89 lines modified | Offset 267, 89 lines modified | ||
267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> | 267 | ··········<label·class="toc-overlay-icon·toc-content-icon"·for="__toc"> |
268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> | 268 | ············<div·class="visually-hidden">Toggle·table·of·contents·sidebar</div> |
269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> | 269 | ············<i·class="icon"><svg><use·href="#svg-toc"></use></svg></i> |
270 | ··········</label> | 270 | ··········</label> |
271 | ········</div> | 271 | ········</div> |
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="module-websockets.sync.server"> | 273 | ··········<section·id="module-websockets.sync.server"> |
274 | <span·id="server-threading"></span><h1>Server·(< | 274 | <span·id="server-threading"></span><h1>Server·(<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">threading</span></code>)<a·class="headerlink"·href="#module-websockets.sync.server"·title="Link·to·this·heading">#</a></h1> |
275 | <section·id="creating-a-server"> | 275 | <section·id="creating-a-server"> |
276 | <h2>Creating·a·server<a·class="headerlink"·href="#creating-a-server"·title="Link·to·this·heading">#</a></h2> | 276 | <h2>Creating·a·server<a·class="headerlink"·href="#creating-a-server"·title="Link·to·this·heading">#</a></h2> |
277 | <dl·class="py·function"> | 277 | <dl·class="py·function"> |
278 | <dt·class="sig·sig-object·py"·id="websockets.sync.server.serve"> | 278 | <dt·class="sig·sig-object·py"·id="websockets.sync.server.serve"> |
279 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.server.</span></span><span·class="sig-name·descname"><span·class="pre">serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">host</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">port</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">sock</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ssl_context</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_response</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_connection</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.server.serve"·title="Link·to·this·definition">#</a></dt> | 279 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.server.</span></span><span·class="sig-name·descname"><span·class="pre">serve</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">host</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">port</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="o"><span·class="pre">*</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">sock</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">ssl_context</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">origins</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">extensions</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">subprotocols</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">select_subprotocol</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_request</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">process_response</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">server_header</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'Python/x.y.z</span>·<span·class="pre">websockets/X.Y'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">compression</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">'deflate'</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">open_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">close_timeout</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">10</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">max_size</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">2**20</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">create_connection</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.server.serve"·title="Link·to·this·definition">#</a></dt> |
280 | <dd><p>Create·a·WebSocket·server·listening·on·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>.</p> | 280 | <dd><p>Create·a·WebSocket·server·listening·on·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>.</p> |
281 | <p>Whenever·a·client·connects,·the·server·creates·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>, | 281 | <p>Whenever·a·client·connects,·the·server·creates·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>, |
282 | performs·the·opening·handshake,·and·delegates·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">handler</span></code>.</p> | 282 | performs·the·opening·handshake,·and·delegates·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">handler</span></code>.</p> |
283 | <p>The·handler·receives·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>·instance,·which·you·can·use | 283 | <p>The·handler·receives·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>·instance,·which·you·can·use |
284 | to·send·and·receive·messages.</p> | 284 | to·send·and·receive·messages.</p> |
285 | <p>Once·the·handler·completes,·either·normally·or·with·an·exception,·the·server | 285 | <p>Once·the·handler·completes,·either·normally·or·with·an·exception,·the·server |
286 | performs·the·closing·handshake·and·closes·the·connection.</p> | 286 | performs·the·closing·handshake·and·closes·the·connection.</p> |
287 | <p><a·class="reference·internal"·href="#websockets.sync.server.WebSocketServer"·title="websockets.sync.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>·mirrors·the·API·of | 287 | <p><a·class="reference·internal"·href="#websockets.sync.server.WebSocketServer"·title="websockets.sync.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>·mirrors·the·API·of |
288 | < | 288 | <code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">BaseServer</span></code>.·Treat·it·as·a·context·manager·to·ensure |
289 | that·it·will·be·closed·and·call·the·<a·class="reference·internal"·href="#websockets.sync.server.WebSocketServer.serve_forever"·title="websockets.sync.server.WebSocketServer.serve_forever"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">serve_forever()</span></code></a> | 289 | that·it·will·be·closed·and·call·the·<a·class="reference·internal"·href="#websockets.sync.server.WebSocketServer.serve_forever"·title="websockets.sync.server.WebSocketServer.serve_forever"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">serve_forever()</span></code></a> |
290 | method·to·serve·requests:</p> | 290 | method·to·serve·requests:</p> |
291 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> | 291 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">def</span>·<span·class="nf">handler</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">):</span> |
292 | ····<span·class="o">...</span> | 292 | ····<span·class="o">...</span> |
293 | <span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">sync</span><span·class="o">.</span><span·class="n">server</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="o">...</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">server</span><span·class="p">:</span> | 293 | <span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">sync</span><span·class="o">.</span><span·class="n">server</span><span·class="o">.</span><span·class="n">serve</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">,</span>·<span·class="o">...</span><span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">server</span><span·class="p">:</span> |
294 | ····<span·class="n">server</span><span·class="o">.</span><span·class="n">serve_forever</span><span·class="p">()</span> | 294 | ····<span·class="n">server</span><span·class="o">.</span><span·class="n">serve_forever</span><span·class="p">()</span> |
295 | </pre></div> | 295 | </pre></div> |
296 | </div> | 296 | </div> |
297 | <dl·class="field-list·simple"> | 297 | <dl·class="field-list·simple"> |
298 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 298 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
299 | <dd·class="field-odd"><ul·class="simple"> | 299 | <dd·class="field-odd"><ul·class="simple"> |
300 | <li><p><strong>handler</strong>·(< | 300 | <li><p><strong>handler</strong>·(<em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>]</em><em>,·</em><em>None</em><em>]</em>)·–·Connection·handler.·It·receives·the·WebSocket·connection, |
301 | which·is·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>,·in·argument.</p></li> | 301 | which·is·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>,·in·argument.</p></li> |
302 | <li><p><strong>host</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><em>str</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Network·interfaces·the·server·binds·to. | ||
303 | See·<a·class="reference·external"·href="https://docs.python.org/3/library/socket.html#socket.create_server"·title="(in·Python·v3.12)"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">create_server()</span></code></a>·for·details.</p></li> | ||
304 | <li><p><strong>port</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·TCP·port·the·server·listens·on. | ||
305 | See·<a·class="reference·external"·href="https://docs.python.org/3/library/socket.html#socket.create_server"·title="(in·Python·v3.12)"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">create_server()</span></code></a>·for·details.</p></li> | ||
306 | <li><p><strong>sock</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/socket.html#socket.socket"·title="(in·Python·v3.12)"><em>socket</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Preexisting·TCP·socket.·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·replaces·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>. | ||
307 | 302 | <li><p><strong>host</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·Network·interfaces·the·server·binds·to. | |
303 | See·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·for·details.</p></li> | ||
304 | <li><p><strong>port</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·TCP·port·the·server·listens·on. | ||
305 | See·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">create_server()</span></code>·for·details.</p></li> | ||
306 | <li><p><strong>sock</strong>·(<em>socket</em><em>·|·</em><em>None</em>)·–·Preexisting·TCP·socket.·<code·class="docutils·literal·notranslate"><span·class="pre">sock</span></code>·replaces·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>. | ||
307 | You·may·call·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">socket.create_server()</span></code>·to·create·a·suitable·TCP | ||
308 | socket.</p></li> | 308 | socket.</p></li> |
309 | <li><p><strong>ssl_context</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/ssl.html#ssl.SSLContext"·title="(in·Python·v3.12)"><em>SSLContext</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Configuration·for·enabling·TLS·on·the·connection.</p></li> | ||
310 | <li><p><strong>origins</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/typing.html#typing.Sequence"·title="(in·Python·v3.12)"><em>Sequence</em></a><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a><em>]·</em><em>|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·defending | ||
311 | 309 | <li><p><strong>ssl_context</strong>·(<em>SSLContext</em><em>·|·</em><em>None</em>)·–·Configuration·for·enabling·TLS·on·the·connection.</p></li> | |
310 | <li><p><strong>origins</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Origin"·title="websockets.typing.Origin"><em>Origin</em></a><em>·|·</em><em>None</em><em>]·</em><em>|·</em><em>None</em>)·–·Acceptable·values·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header,·for·defending | ||
311 | against·Cross-Site·WebSocket·Hijacking·attacks.·Include·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code> | ||
312 | in·the·list·if·the·lack·of·an·origin·is·acceptable.</p></li> | 312 | in·the·list·if·the·lack·of·an·origin·is·acceptable.</p></li> |
313 | <li><p><strong>extensions</strong>·(< | 313 | <li><p><strong>extensions</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../extensions/#websockets.extensions.ServerExtensionFactory"·title="websockets.extensions.base.ServerExtensionFactory"><em>ServerExtensionFactory</em></a><em>]·</em><em>|·</em><em>None</em>)·–·List·of·supported·extensions,·in·order·in·which·they |
314 | should·be·negotiated·and·run.</p></li> | 314 | should·be·negotiated·and·run.</p></li> |
315 | <li><p><strong>subprotocols</strong>·(< | 315 | <li><p><strong>subprotocols</strong>·(<em>Sequence</em><em>[</em><a·class="reference·internal"·href="../../types/#websockets.typing.Subprotocol"·title="websockets.typing.Subprotocol"><em>Subprotocol</em></a><em>]·</em><em>|·</em><em>None</em>)·–·List·of·supported·subprotocols,·in·order·of·decreasing |
316 | preference.</p></li> | 316 | preference.</p></li> |
317 | <li><p><strong>select_subprotocol</strong>·(<a·class="reference· | 317 | <li><p><strong>select_subprotocol</strong>·(<em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>,·</em><em>Sequence</em><em>[</em><a·class="reference·interna[·...·truncated·by·diffoscope;·len:·347,·SHA:·a2ea899b69db09f11987aa08b53a33a7d1691e9889a5937de19e4607c706295b·...·]>)·–·Callback·for·selecting·a·subprotocol·among |
318 | those·supported·by·the·client·and·the·server.·It·receives·a | 318 | those·supported·by·the·client·and·the·server.·It·receives·a |
319 | <a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>·(not·a | 319 | <a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>·(not·a |
320 | <a·class="reference·internal"·href="../../sansio/server/#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerProtocol</span></code></a>!)·instance·and·a·list·of | 320 | <a·class="reference·internal"·href="../../sansio/server/#websockets.server.ServerProtocol"·title="websockets.server.ServerProtocol"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerProtocol</span></code></a>!)·instance·and·a·list·of |
321 | subprotocols·offered·by·the·client.·Other·than·the·first·argument, | 321 | subprotocols·offered·by·the·client.·Other·than·the·first·argument, |
322 | it·has·the·same·behavior·as·the | 322 | it·has·the·same·behavior·as·the |
323 | <a·class="reference·internal"·href="../../sansio/server/#websockets.server.ServerProtocol.select_subprotocol"·title="websockets.server.ServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ServerProtocol.select_subprotocol</span></code></a>·method.</p></li> | 323 | <a·class="reference·internal"·href="../../sansio/server/#websockets.server.ServerProtocol.select_subprotocol"·title="websockets.server.ServerProtocol.select_subprotocol"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ServerProtocol.select_subprotocol</span></code></a>·method.</p></li> |
324 | <li><p><strong>process_request</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/typing.html#typing.Callable"·title="(in·Python·v3.12)"><em>Callable</em></a><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Request"·title="websockets.http11.Request"><em>Request</em></a><em>]</em><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Response"·title="websockets.http11.Response"><em>Response</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a><em>]·</em><em>|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Intercept·the·request·during·the·opening·handshake. | ||
325 | 324 | <li><p><strong>process_request</strong>·(<em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>,·</em><a·class="re[·...·truncated·by·diffoscope;·len:·405,·SHA:·707a0305907ec2abfdc6737b10a5ff40f9b539cfa006d67aa2e427125c214df4·...·] | |
325 | Return·an·HTTP·response·to·force·the·response·or·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to | ||
326 | continue·normally.·When·you·force·an·HTTP·101·Continue·response, | 326 | continue·normally.·When·you·force·an·HTTP·101·Continue·response, |
327 | the·handshake·is·successful.·Else,·the·connection·is·aborted.</p></li> | 327 | the·handshake·is·successful.·Else,·the·connection·is·aborted.</p></li> |
328 | <li><p><strong>process_response</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/typing.html#typing.Callable"·title="(in·Python·v3.12)"><em>Callable</em></a><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Request"·title="websockets.http11.Request"><em>Request</em></a><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Response"·title="websockets.http11.Response"><em>Response</em></a><em>]</em><em>,·</em><a·class="reference·internal"·href="../../datastructures/#websockets.http11.Response"·title="websockets.http11.Response"><em>Response</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a><em>]·</em><em>|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Intercept·the·response·during·the·opening·handshake. | ||
329 | 328 | <li><p><strong>process_response</strong>·(<em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>,·</em><a·class="r[·...·truncated·by·diffoscope;·len:·560,·SHA:·2f04be3e93df7e6d4bedd20c2781993592eab004f7f980319d9e1b0c7f3b55d2·...·] | |
329 | Return·an·HTTP·response·to·force·the·response·or·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to | ||
330 | continue·normally.·When·you·force·an·HTTP·101·Continue·response, | 330 | continue·normally.·When·you·force·an·HTTP·101·Continue·response, |
331 | the·handshake·is·successful.·Else,·the·connection·is·aborted.</p></li> | 331 | the·handshake·is·successful.·Else,·the·connection·is·aborted.</p></li> |
332 | <li><p><strong>server_header</strong>·(< | 332 | <li><p><strong>server_header</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·Value·of··the·<code·class="docutils·literal·notranslate"><span·class="pre">Server</span></code>·response·header. |
333 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>.·Setting·it·to | 333 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">"Python/x.y.z</span>·<span·class="pre">websockets/X.Y"</span></code>.·Setting·it·to |
334 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·removes·the·header.</p></li> | ||
335 | < | 334 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·removes·the·header.</p></li> |
335 | <li><p><strong>compression</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·The·“permessage-deflate”·extension·is·enabled·by·default. | ||
336 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·< | 336 | Set·<code·class="docutils·literal·notranslate"><span·class="pre">compression</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·it.·See·the |
337 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> | 337 | <a·class="reference·internal"·href="../../../topics/compression/"><span·class="doc">compression·guide</span></a>·for·details.</p></li> |
338 | <li><p><strong>open_timeout</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Timeout·for·opening·connections·in·seconds. | ||
339 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·timeout.</p></li> | ||
340 | <li><p><strong>close_timeout</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#float"·title="(in·Python·v3.12)"><em>float</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Timeout·for·closing·connections·in·seconds. | ||
341 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·timeout.</p></li> | ||
342 | <li><p><strong>max_size</strong>·(<a·class="reference·external"·href="https://docs.python.org/3/library/functions.html#int"·title="(in·Python·v3.12)"><em>int</em></a><em>·|·</em><a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><em>None</em></a>)·–·Maximum·size·of·incoming·messages·in·bytes. | ||
343 | <a·class="reference·external"·href="https://docs.python.org/3/library/constants.html#None"·title="(in·Python·v3.12)"><code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code></a>·disables·the·limit.</p></li> | ||
344 | <li><p><strong> | 338 | <li><p><strong>open_timeout</strong>·(<em>float</em><em>·|·</em><em>None</em>)·–·Timeout·for·opening·connections·in·seconds. |
339 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
340 | <li><p><strong>close_timeout</strong>·(<em>float</em><em>·|·</em><em>None</em>)·–·Timeout·for·closing·connections·in·seconds. | ||
341 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·timeout.</p></li> | ||
342 | <li><p><strong>max_size</strong>·(<em>int</em><em>·|·</em><em>None</em>)·–·Maximum·size·of·incoming·messages·in·bytes. | ||
343 | <code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·limit.</p></li> | ||
344 | <li><p><strong>logger</strong>·(<em>Logger</em><em>·|·</em><em>LoggerAdapter</em><em>·|·</em><em>None</em>)·–·Logger·for·this·server. | ||
345 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>.·See·the | 345 | It·defaults·to·<code·class="docutils·literal·notranslate"><span·class="pre">logging.getLogger("websockets.server")</span></code>.·See·the |
346 | <a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> | 346 | <a·class="reference·internal"·href="../../../topics/logging/"><span·class="doc">logging·guide</span></a>·for·details.</p></li> |
347 | <li><p><strong>create_connection</strong>·(< | 347 | <li><p><strong>create_connection</strong>·(<em>Type</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>]·</em><em>|·</em><em>None</em>)·–·Factory·for·the·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>·managing |
348 | the·connection.·Set·it·to·a·wrapper·or·a·subclass·to·customize | 348 | the·connection.·Set·it·to·a·wrapper·or·a·subclass·to·customize |
349 | connection·handling.</p></li> | 349 | connection·handling.</p></li> |
350 | </ul> | 350 | </ul> |
351 | </dd> | 351 | </dd> |
352 | </dl> | 352 | </dl> |
353 | </dd></dl> | 353 | </dd></dl> |
Offset 359, 70 lines modified | Offset 359, 70 lines modified | ||
359 | <dd><p>Create·a·WebSocket·server·listening·on·a·Unix·socket.</p> | 359 | <dd><p>Create·a·WebSocket·server·listening·on·a·Unix·socket.</p> |
360 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.sync.server.serve"·title="websockets.sync.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>,·except·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and | 360 | <p>This·function·is·identical·to·<a·class="reference·internal"·href="#websockets.sync.server.serve"·title="websockets.sync.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>,·except·the·<code·class="docutils·literal·notranslate"><span·class="pre">host</span></code>·and |
361 | <code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·arguments·are·replaced·by·<code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>.·It’s·only·available·on·Unix.</p> | 361 | <code·class="docutils·literal·notranslate"><span·class="pre">port</span></code>·arguments·are·replaced·by·<code·class="docutils·literal·notranslate"><span·class="pre">path</span></code>.·It’s·only·available·on·Unix.</p> |
362 | <p>It’s·useful·for·deploying·a·server·behind·a·reverse·proxy·such·as·nginx.</p> | 362 | <p>It’s·useful·for·deploying·a·server·behind·a·reverse·proxy·such·as·nginx.</p> |
363 | <dl·class="field-list·simple"> | 363 | <dl·class="field-list·simple"> |
364 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> | 364 | <dt·class="field-odd">Parameters<span·class="colon">:</span></dt> |
365 | <dd·class="field-odd"><ul·class="simple"> | 365 | <dd·class="field-odd"><ul·class="simple"> |
366 | <li><p><strong>handler</strong>·(< | 366 | <li><p><strong>handler</strong>·(<em>Callable</em><em>[</em><em>[</em><a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><em>ServerConnection</em></a><em>]</em><em>,·</em><em>Any</em><em>]</em>)·–·Connection·handler.·It·receives·the·WebSocket·connection, |
367 | which·is·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>,·in·argument.</p></li> | 367 | which·is·a·<a·class="reference·internal"·href="#websockets.sync.server.ServerConnection"·title="websockets.sync.server.ServerConnection"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">ServerConnection</span></code></a>,·in·argument.</p></li> |
368 | <li><p><strong>path</strong>·(< | 368 | <li><p><strong>path</strong>·(<em>str</em><em>·|·</em><em>None</em>)·–·File·system·path·to·the·Unix·socket.</p></li> |
369 | </ul> | 369 | </ul> |
370 | </dd> | 370 | </dd> |
371 | </dl> | 371 | </dl> |
372 | </dd></dl> | 372 | </dd></dl> |
373 | </section> | 373 | </section> |
374 | <section·id="running-a-server"> | 374 | <section·id="running-a-server"> |
375 | <h2>Running·a·server<a·class="headerlink"·href="#running-a-server"·title="Link·to·this·heading">#</a></h2> | 375 | <h2>Running·a·server<a·class="headerlink"·href="#running-a-server"·title="Link·to·this·heading">#</a></h2> |
376 | <dl·class="py·class"> | 376 | <dl·class="py·class"> |
377 | <dt·class="sig·sig-object·py"·id="websockets.sync.server.WebSocketServer"> | 377 | <dt·class="sig·sig-object·py"·id="websockets.sync.server.WebSocketServer"> |
378 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.server.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketServer</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">socket</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.server.WebSocketServer"·title="Link·to·this·definition">#</a></dt> | 378 | <em·class="property"><span·class="pre">class</span><span·class="w">·</span></em><span·class="sig-prename·descclassname"><span·class="pre">websockets.sync.server.</span></span><span·class="sig-name·descname"><span·class="pre">WebSocketServer</span></span><span·class="sig-paren">(</span><em·class="sig-param"><span·class="n"><span·class="pre">socket</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">handler</span></span></em>,·<em·class="sig-param"><span·class="n"><span·class="pre">logger</span></span><span·class="o"><span·class="pre">=</span></span><span·class="default_value"><span·class="pre">None</span></span></em><span·class="sig-paren">)</span><a·class="headerlink"·href="#websockets.sync.server.WebSocketServer"·title="Link·to·this·definition">#</a></dt> |
Max diff block lines reached; 45711/81241 bytes (56.27%) of diff not shown. |
Offset 270, 30 lines modified | Offset 270, 30 lines modified | ||
270 | ········<article·role="main"> | 270 | ········<article·role="main"> |
271 | ··········<section·id="module-websockets.typing"> | 271 | ··········<section·id="module-websockets.typing"> |
272 | <span·id="types"></span><h1>Types<a·class="headerlink"·href="#module-websockets.typing"·title="Link·to·this·heading">#</a></h1> | 272 | <span·id="types"></span><h1>Types<a·class="headerlink"·href="#module-websockets.typing"·title="Link·to·this·heading">#</a></h1> |
273 | <dl·class="py·data"> | 273 | <dl·class="py·data"> |
274 | <dt·class="sig·sig-object·py"·id="websockets.typing.Data"> | 274 | <dt·class="sig·sig-object·py"·id="websockets.typing.Data"> |
275 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">Data</span></span><a·class="headerlink"·href="#websockets.typing.Data"·title="Link·to·this·definition">#</a></dt> | 275 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">Data</span></span><a·class="headerlink"·href="#websockets.typing.Data"·title="Link·to·this·definition">#</a></dt> |
276 | <dd><p>Types·supported·in·a·WebSocket·message: | 276 | <dd><p>Types·supported·in·a·WebSocket·message: |
277 | <a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code></a>·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame,·<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#bytes"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code></a>·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Binary</a>.</p> | ||
278 | < | 277 | <code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>·for·a·<a·class="reference·external"·href="https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6">Text</a>·frame,·<code·class="xref·py·py-class·docutils·literal[·...·truncated·by·diffoscope;·len:·162,·SHA:·ac6b37f6af44c54596c0ed3e72a04ecb849534ff338265e19347016d0618aaa9·...·]</p> |
278 | <p>alias·of·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">Union</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">bytes</span></code>]</p> | ||
279 | </dd></dl> | 279 | </dd></dl> |
280 | <dl·class="py·data"> | 280 | <dl·class="py·data"> |
281 | <dt·class="sig·sig-object·py"·id="websockets.typing.LoggerLike"> | 281 | <dt·class="sig·sig-object·py"·id="websockets.typing.LoggerLike"> |
282 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">LoggerLike</span></span><a·class="headerlink"·href="#websockets.typing.LoggerLike"·title="Link·to·this·definition">#</a></dt> | 282 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">LoggerLike</span></span><a·class="headerlink"·href="#websockets.typing.LoggerLike"·title="Link·to·this·definition">#</a></dt> |
283 | <dd><p>Types·accepted·where·a·<a·class="reference·external"·href="https://docs.python.org/3/library/logging.html#logging.Logger"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Logger</span></code></a>·is·expected.</p> | ||
284 | < | 283 | <dd><p>Types·accepted·where·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Logger</span></code>·is·expected.</p> |
284 | <p>alias·of·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">Union</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Logger</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">LoggerAdapter</span></code>]</p> | ||
285 | </dd></dl> | 285 | </dd></dl> |
286 | <dl·class="py·data"> | 286 | <dl·class="py·data"> |
287 | <dt·class="sig·sig-object·py"·id="websockets.typing.StatusLike"> | 287 | <dt·class="sig·sig-object·py"·id="websockets.typing.StatusLike"> |
288 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">StatusLike</span></span><a·class="headerlink"·href="#websockets.typing.StatusLike"·title="Link·to·this·definition">#</a></dt> | 288 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">StatusLike</span></span><a·class="headerlink"·href="#websockets.typing.StatusLike"·title="Link·to·this·definition">#</a></dt> |
289 | <dd><p>Types·accepted·where·an·<a·class="reference·external"·href="https://docs.python.org/3/library/http.html#http.HTTPStatus"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">HTTPStatus</span></code></a>·is·expected.</p> | ||
290 | < | 289 | <dd><p>Types·accepted·where·an·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">HTTPStatus</span></code>·is·expected.</p> |
290 | <p>alias·of·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">Union</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">HTTPStatus</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">int</span></code>]</p> | ||
291 | </dd></dl> | 291 | </dd></dl> |
292 | <dl·class="py·data"> | 292 | <dl·class="py·data"> |
293 | <dt·class="sig·sig-object·py"·id="websockets.typing.Origin"> | 293 | <dt·class="sig·sig-object·py"·id="websockets.typing.Origin"> |
294 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">Origin</span></span><em·class="property"><span·class="w">·</span><span·class="p"><span·class="pre">=</span></span><span·class="w">·</span><span·class="pre">websockets.typing.Origin</span></em><a·class="headerlink"·href="#websockets.typing.Origin"·title="Link·to·this·definition">#</a></dt> | 294 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">Origin</span></span><em·class="property"><span·class="w">·</span><span·class="p"><span·class="pre">=</span></span><span·class="w">·</span><span·class="pre">websockets.typing.Origin</span></em><a·class="headerlink"·href="#websockets.typing.Origin"·title="Link·to·this·definition">#</a></dt> |
295 | <dd><p>Value·of·a·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header.</p> | 295 | <dd><p>Value·of·a·<code·class="docutils·literal·notranslate"><span·class="pre">Origin</span></code>·header.</p> |
296 | </dd></dl> | 296 | </dd></dl> |
Offset 310, 31 lines modified | Offset 310, 31 lines modified | ||
310 | <dd><p>Name·of·a·WebSocket·extension.</p> | 310 | <dd><p>Name·of·a·WebSocket·extension.</p> |
311 | </dd></dl> | 311 | </dd></dl> |
312 | <dl·class="py·data"> | 312 | <dl·class="py·data"> |
313 | <dt·class="sig·sig-object·py"·id="websockets.typing.ExtensionParameter"> | 313 | <dt·class="sig·sig-object·py"·id="websockets.typing.ExtensionParameter"> |
314 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">ExtensionParameter</span></span><a·class="headerlink"·href="#websockets.typing.ExtensionParameter"·title="Link·to·this·definition">#</a></dt> | 314 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.typing.</span></span><span·class="sig-name·descname"><span·class="pre">ExtensionParameter</span></span><a·class="headerlink"·href="#websockets.typing.ExtensionParameter"·title="Link·to·this·definition">#</a></dt> |
315 | <dd><p>Parameter·of·a·WebSocket·extension.</p> | 315 | <dd><p>Parameter·of·a·WebSocket·extension.</p> |
316 | <p>alias·of·< | 316 | <p>alias·of·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Tuple</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>,·<code·class="xref·py·py-obj·docutils·literal·notranslate"><spa[·...·truncated·by·diffoscope;·len:·131,·SHA:·ba731bccd5edd35ca8925015ca291703e25ddbb439fa1e6b49ba057ed5f6a540·...·]>]]</p> |
317 | </dd></dl> | 317 | </dd></dl> |
318 | <dl·class="py·data"> | 318 | <dl·class="py·data"> |
319 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Event"> | 319 | <dt·class="sig·sig-object·py"·id="websockets.protocol.Event"> |
320 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">Event</span></span><a·class="headerlink"·href="#websockets.protocol.Event"·title="Link·to·this·definition">#</a></dt> | 320 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.protocol.</span></span><span·class="sig-name·descname"><span·class="pre">Event</span></span><a·class="headerlink"·href="#websockets.protocol.Event"·title="Link·to·this·definition">#</a></dt> |
321 | <dd><p>Events·that·<a·class="reference·internal"·href="../sansio/common/#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·may·return.</p> | 321 | <dd><p>Events·that·<a·class="reference·internal"·href="../sansio/common/#websockets.protocol.Protocol.events_received"·title="websockets.protocol.Protocol.events_received"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">events_received()</span></code></a>·may·return.</p> |
322 | <p>alias·of·< | 322 | <p>alias·of·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">Union</span></code>[<a·class="reference·internal"·href="../datastructures/#websockets.http11.Request"·title="websockets.http11.Request"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Request</span></code></a>,·<a·class="reference·internal"·href="../datastructures/#websockets.http11.Response"·title="websockets.http11.Response"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Response</span></code></a>,·<a·class="reference·internal"·href="../datastructures/#websockets.frames.Frame"·title="websockets.frames.Frame"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Frame</span></code></a>]</p> |
323 | </dd></dl> | 323 | </dd></dl> |
324 | <dl·class="py·data"> | 324 | <dl·class="py·data"> |
325 | <dt·class="sig·sig-object·py"·id="websockets.datastructures.HeadersLike"> | 325 | <dt·class="sig·sig-object·py"·id="websockets.datastructures.HeadersLike"> |
326 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.datastructures.</span></span><span·class="sig-name·descname"><span·class="pre">HeadersLike</span></span><a·class="headerlink"·href="#websockets.datastructures.HeadersLike"·title="Link·to·this·definition">#</a></dt> | 326 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.datastructures.</span></span><span·class="sig-name·descname"><span·class="pre">HeadersLike</span></span><a·class="headerlink"·href="#websockets.datastructures.HeadersLike"·title="Link·to·this·definition">#</a></dt> |
327 | <dd><p>Types·accepted·where·<a·class="reference·internal"·href="../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Headers</span></code></a>·is·expected.</p> | 327 | <dd><p>Types·accepted·where·<a·class="reference·internal"·href="../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Headers</span></code></a>·is·expected.</p> |
328 | <p>In·addition·to·<a·class="reference·internal"·href="../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Headers</span></code></a>·itself,·this·includes·dict-like·types·where·both | 328 | <p>In·addition·to·<a·class="reference·internal"·href="../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Headers</span></code></a>·itself,·this·includes·dict-like·types·where·both |
329 | keys·and·values·are·<a·class="reference·external"·href="https://docs.python.org/3/library/stdtypes.html#str"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code></a>.</p> | ||
330 | 329 | keys·and·values·are·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>.</p> | |
330 | <p>alias·of·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">Union</span></code>[<a·class="reference·internal"·href="../datastructures/#websockets.datastructures.Headers"·title="websockets.datastructures.Headers"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Headers</span></code></a>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Mapping</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>],·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Iterable</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Tuple</span></code>[<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">str</span></code>]],·<a·class="reference·internal"·href="#websockets.datastructures.SupportsKeysAndGetItem"·title="websockets.datastructures.SupportsKeysAndGetItem"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">SupportsKeysAndGetItem</span></code></a>]</p> | ||
331 | </dd></dl> | 331 | </dd></dl> |
332 | <dl·class="py·data"> | 332 | <dl·class="py·data"> |
333 | <dt·class="sig·sig-object·py"·id="websockets.datastructures.SupportsKeysAndGetItem"> | 333 | <dt·class="sig·sig-object·py"·id="websockets.datastructures.SupportsKeysAndGetItem"> |
334 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.datastructures.</span></span><span·class="sig-name·descname"><span·class="pre">SupportsKeysAndGetItem</span></span><em·class="property"><span·class="w">·</span><span·class="p"><span·class="pre">=</span></span><span·class="w">·</span><span·class="pre"><class</span>·<span·class="pre">'websockets.datastructures.SupportsKeysAndGetItem'></span></em><a·class="headerlink"·href="#websockets.datastructures.SupportsKeysAndGetItem"·title="Link·to·this·definition">#</a></dt> | 334 | <span·class="sig-prename·descclassname"><span·class="pre">websockets.datastructures.</span></span><span·class="sig-name·descname"><span·class="pre">SupportsKeysAndGetItem</span></span><em·class="property"><span·class="w">·</span><span·class="p"><span·class="pre">=</span></span><span·class="w">·</span><span·class="pre"><class</span>·<span·class="pre">'websockets.datastructures.SupportsKeysAndGetItem'></span></em><a·class="headerlink"·href="#websockets.datastructures.SupportsKeysAndGetItem"·title="Link·to·this·definition">#</a></dt> |
335 | <dd><p>Dict-like·types·with·<code·class="docutils·literal·notranslate"><span·class="pre">keys()</span>·<span·class="pre">-></span>·<span·class="pre">str</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">__getitem__(key:</span>·<span·class="pre">str)</span>·<span·class="pre">-></span>·<span·class="pre">str</span></code>·methods.</p> | 335 | <dd><p>Dict-like·types·with·<code·class="docutils·literal·notranslate"><span·class="pre">keys()</span>·<span·class="pre">-></span>·<span·class="pre">str</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">__getitem__(key:</span>·<span·class="pre">str)</span>·<span·class="pre">-></span>·<span·class="pre">str</span></code>·methods.</p> |
336 | </dd></dl> | 336 | </dd></dl> |
Offset 542, 15 lines modified | Offset 542, 15 lines modified | ||
542 | (<span·class="target"·id="index-1"></span><a·class="rfc·reference·external"·href="https://datatracker.ietf.org/doc/html/rfc7617.html"><strong>RFC·7617</strong></a>),·include·the·credentials·in·the·URI:</p> | 542 | (<span·class="target"·id="index-1"></span><a·class="rfc·reference·external"·href="https://datatracker.ietf.org/doc/html/rfc7617.html"><strong>RFC·7617</strong></a>),·include·the·credentials·in·the·URI:</p> |
543 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span> | 543 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span> |
544 | ····<span·class="sa">f</span><span·class="s2">"wss://</span><span·class="si">{</span><span·class="n">username</span><span·class="si">}</span><span·class="s2">:</span><span·class="si">{</span><span·class="n">password</span><span·class="si">}</span><span·class="s2">@example.com"</span><span·class="p">,</span> | 544 | ····<span·class="sa">f</span><span·class="s2">"wss://</span><span·class="si">{</span><span·class="n">username</span><span·class="si">}</span><span·class="s2">:</span><span·class="si">{</span><span·class="n">password</span><span·class="si">}</span><span·class="s2">@example.com"</span><span·class="p">,</span> |
545 | <span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 545 | <span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
546 | ····<span·class="o">...</span> | 546 | ····<span·class="o">...</span> |
547 | </pre></div> | 547 | </pre></div> |
548 | </div> | 548 | </div> |
549 | <p>(You·must·< | 549 | <p>(You·must·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">quote()</span></code>·<code·class="docutils·literal·notranslate"><span·class="pre">username</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">password</span></code>·if·they |
550 | contain·unsafe·characters.)</p> | 550 | contain·unsafe·characters.)</p> |
551 | <p>To·authenticate·a·websockets·client·with·HTTP·Bearer·Authentication | 551 | <p>To·authenticate·a·websockets·client·with·HTTP·Bearer·Authentication |
552 | (<span·class="target"·id="index-2"></span><a·class="rfc·reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6750.html"><strong>RFC·6750</strong></a>),·add·a·suitable·<code·class="docutils·literal·notranslate"><span·class="pre">Authorization</span></code>·header:</p> | 552 | (<span·class="target"·id="index-2"></span><a·class="rfc·reference·external"·href="https://datatracker.ietf.org/doc/html/rfc6750.html"><strong>RFC·6750</strong></a>),·add·a·suitable·<code·class="docutils·literal·notranslate"><span·class="pre">Authorization</span></code>·header:</p> |
553 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span> | 553 | <div·class="highlight-python·notranslate"><div·class="highlight"><pre><span></span><span·class="k">async</span>·<span·class="k">with</span>·<span·class="n">websockets</span><span·class="o">.</span><span·class="n">connect</span><span·class="p">(</span> |
554 | ····<span·class="s2">"wss://example.com"</span><span·class="p">,</span> | 554 | ····<span·class="s2">"wss://example.com"</span><span·class="p">,</span> |
555 | ····<span·class="n">extra_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="sa">f</span><span·class="s2">"Bearer·</span><span·class="si">{</span><span·class="n">token</span><span·class="si">}</span><span·class="s2">"</span><span·class="p">}</span> | 555 | ····<span·class="n">extra_headers</span><span·class="o">=</span><span·class="p">{</span><span·class="s2">"Authorization"</span><span·class="p">:</span>·<span·class="sa">f</span><span·class="s2">"Bearer·</span><span·class="si">{</span><span·class="n">token</span><span·class="si">}</span><span·class="s2">"</span><span·class="p">}</span> |
556 | <span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> | 556 | <span·class="p">)</span>·<span·class="k">as</span>·<span·class="n">websocket</span><span·class="p">:</span> |
Offset 388, 15 lines modified | Offset 388, 15 lines modified | ||
388 | <span·class="k">def</span>·<span·class="nf">broadcast</span><span·class="p">(</span><span·class="n">message</span><span·class="p">):</span> | 388 | <span·class="k">def</span>·<span·class="nf">broadcast</span><span·class="p">(</span><span·class="n">message</span><span·class="p">):</span> |
389 | ····<span·class="k">for</span>·<span·class="n">websocket</span>·<span·class="ow">in</span>·<span·class="n">CLIENTS</span><span·class="p">:</span> | 389 | ····<span·class="k">for</span>·<span·class="n">websocket</span>·<span·class="ow">in</span>·<span·class="n">CLIENTS</span><span·class="p">:</span> |
390 | ········<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">send</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">,</span>·<span·class="n">message</span><span·class="p">))</span> | 390 | ········<span·class="n">asyncio</span><span·class="o">.</span><span·class="n">create_task</span><span·class="p">(</span><span·class="n">send</span><span·class="p">(</span><span·class="n">websocket</span><span·class="p">,</span>·<span·class="n">message</span><span·class="p">))</span> |
391 | </pre></div> | 391 | </pre></div> |
392 | </div> | 392 | </div> |
393 | <p>We·move·the·error·handling·logic·in·a·new·coroutine·and·we·schedule | 393 | <p>We·move·the·error·handling·logic·in·a·new·coroutine·and·we·schedule |
394 | a·< | 394 | a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Task</span></code>·to·run·it·instead·of·executing·it·immediately.</p> |
395 | <p>Since·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·no·longer·awaits·coroutines,·we·can·make·it·a·function | 395 | <p>Since·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·no·longer·awaits·coroutines,·we·can·make·it·a·function |
396 | rather·than·a·coroutine·and·do·away·with·the·copy·of·<code·class="docutils·literal·notranslate"><span·class="pre">CLIENTS</span></code>.</p> | 396 | rather·than·a·coroutine·and·do·away·with·the·copy·of·<code·class="docutils·literal·notranslate"><span·class="pre">CLIENTS</span></code>.</p> |
397 | <p>This·version·of·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·makes·clients·independent·from·one·another:·a | 397 | <p>This·version·of·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·makes·clients·independent·from·one·another:·a |
398 | slow·client·won’t·block·others.·As·a·side·effect,·it·makes·messages | 398 | slow·client·won’t·block·others.·As·a·side·effect,·it·makes·messages |
399 | independent·from·one·another.</p> | 399 | independent·from·one·another.</p> |
400 | <p>If·you·broadcast·several·messages,·there·is·no·strong·guarantee·that·they·will | 400 | <p>If·you·broadcast·several·messages,·there·is·no·strong·guarantee·that·they·will |
401 | be·sent·in·the·expected·order.·Fortunately,·the·event·loop·runs·tasks·in·the | 401 | be·sent·in·the·expected·order.·Fortunately,·the·event·loop·runs·tasks·in·the |
Offset 426, 17 lines modified | Offset 426, 17 lines modified | ||
426 | is·full·and,·if·it·is,·waits·until·it·drain,·giving·the·network·and·the | 426 | is·full·and,·if·it·is,·waits·until·it·drain,·giving·the·network·and·the |
427 | client·time·to·catch·up.·This·provides·backpressure.</p> | 427 | client·time·to·catch·up.·This·provides·backpressure.</p> |
428 | <p>Without·backpressure,·you·could·pile·up·data·in·the·write·buffer·until·the | 428 | <p>Without·backpressure,·you·could·pile·up·data·in·the·write·buffer·until·the |
429 | server·process·runs·out·of·memory·and·the·operating·system·kills·it.</p> | 429 | server·process·runs·out·of·memory·and·the·operating·system·kills·it.</p> |
430 | <p>The·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.send"·title="websockets.server.WebSocketServerProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·API·is·designed·to·enforce | 430 | <p>The·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.send"·title="websockets.server.WebSocketServerProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·API·is·designed·to·enforce |
431 | backpressure·by·default.·This·helps·users·of·websockets·write·robust·programs | 431 | backpressure·by·default.·This·helps·users·of·websockets·write·robust·programs |
432 | even·if·they·never·heard·about·backpressure.</p> | 432 | even·if·they·never·heard·about·backpressure.</p> |
433 | <p>For·comparison,·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-stream.html#asyncio.StreamWriter"·title="(in·Python·v3.12)"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.StreamWriter</span></code></a>·requires·users·to·understand | ||
434 | backpressure·and·to·await·<a·class="reference·external"·href="https://docs.python.org/3/library/asyncio-stream.html#asyncio.StreamWriter.drain"·title="(in·Python·v3.12)"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">drain()</span></code></a>·explicitly | ||
435 | 433 | <p>For·comparison,·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.StreamWriter</span></code>·requires·users·to·understand | |
434 | backpressure·and·to·await·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">drain()</span></code>·explicitly | ||
435 | after·each·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">write()</span></code>.</p> | ||
436 | <p>When·broadcasting·messages,·backpressure·consists·in·slowing·down·all·clients | 436 | <p>When·broadcasting·messages,·backpressure·consists·in·slowing·down·all·clients |
437 | in·an·attempt·to·let·the·slowest·client·catch·up.·With·thousands·of·clients, | 437 | in·an·attempt·to·let·the·slowest·client·catch·up.·With·thousands·of·clients, |
438 | the·slowest·one·is·probably·timing·out·and·isn’t·going·to·receive·the·message | 438 | the·slowest·one·is·probably·timing·out·and·isn’t·going·to·receive·the·message |
439 | anyway.·So·it·doesn’t·make·sense·to·synchronize·with·the·slowest·client.</p> | 439 | anyway.·So·it·doesn’t·make·sense·to·synchronize·with·the·slowest·client.</p> |
440 | <p>How·do·we·avoid·running·out·of·memory·when·slow·clients·can’t·keep·up·with·the | 440 | <p>How·do·we·avoid·running·out·of·memory·when·slow·clients·can’t·keep·up·with·the |
441 | broadcast·rate,·then?·The·most·straightforward·option·is·to·disconnect·them.</p> | 441 | broadcast·rate,·then?·The·most·straightforward·option·is·to·disconnect·them.</p> |
442 | <p>If·a·client·gets·too·far·behind,·eventually·it·reaches·the·limit·defined·by | 442 | <p>If·a·client·gets·too·far·behind,·eventually·it·reaches·the·limit·defined·by |
Offset 534, 16 lines modified | Offset 534, 16 lines modified | ||
534 | </div> | 534 | </div> |
535 | <p>Like·per-client·queues,·this·version·supports·slow·clients·with·limited·memory | 535 | <p>Like·per-client·queues,·this·version·supports·slow·clients·with·limited·memory |
536 | usage.·Unlike·per-client·queues,·it·makes·it·difficult·to·tell·how·far·behind | 536 | usage.·Unlike·per-client·queues,·it·makes·it·difficult·to·tell·how·far·behind |
537 | a·client·is.·The·<code·class="docutils·literal·notranslate"><span·class="pre">PubSub</span></code>·class·could·be·extended·or·refactored·to·provide | 537 | a·client·is.·The·<code·class="docutils·literal·notranslate"><span·class="pre">PubSub</span></code>·class·could·be·extended·or·refactored·to·provide |
538 | this·information.</p> | 538 | this·information.</p> |
539 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">for</span></code>·loop·is·gone·from·this·version·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·function. | 539 | <p>The·<code·class="docutils·literal·notranslate"><span·class="pre">for</span></code>·loop·is·gone·from·this·version·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">broadcast()</span></code>·function. |
540 | However,·there’s·still·a·<code·class="docutils·literal·notranslate"><span·class="pre">for</span></code>·loop·iterating·on·all·clients·hidden·deep | 540 | However,·there’s·still·a·<code·class="docutils·literal·notranslate"><span·class="pre">for</span></code>·loop·iterating·on·all·clients·hidden·deep |
541 | inside·< | 541 | inside·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.·When·<code·class="docutils·literal·notranslate"><span·class="pre">publish()</span></code>·sets·the·result·of·the·<code·class="docutils·literal·notranslate"><span·class="pre">waiter</span></code> |
542 | future,·< | 542 | future,·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·loops·on·callbacks·registered·with·this·future·and |
543 | schedules·them.·This·is·how·connection·handlers·receive·the·next·value·from | 543 | schedules·them.·This·is·how·connection·handlers·receive·the·next·value·from |
544 | the·asynchronous·iterator·returned·by·<code·class="docutils·literal·notranslate"><span·class="pre">subscribe()</span></code>.</p> | 544 | the·asynchronous·iterator·returned·by·<code·class="docutils·literal·notranslate"><span·class="pre">subscribe()</span></code>.</p> |
545 | </section> | 545 | </section> |
546 | <section·id="performance-considerations"> | 546 | <section·id="performance-considerations"> |
547 | <h2>Performance·considerations<a·class="headerlink"·href="#performance-considerations"·title="Link·to·this·heading">#</a></h2> | 547 | <h2>Performance·considerations<a·class="headerlink"·href="#performance-considerations"·title="Link·to·this·heading">#</a></h2> |
548 | <p>The·built-in·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.broadcast"·title="websockets.broadcast"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">broadcast()</span></code></a>·function·sends·all·messages·without·yielding | 548 | <p>The·built-in·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.broadcast"·title="websockets.broadcast"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">broadcast()</span></code></a>·function·sends·all·messages·without·yielding |
549 | control·to·the·event·loop.·So·does·the·naive·way·when·the·network·and·clients | 549 | control·to·the·event·loop.·So·does·the·naive·way·when·the·network·and·clients |
Offset 347, 18 lines modified | Offset 347, 18 lines modified | ||
347 | window·size·(server·to·client)·is·always·12·while·the·decompression·window | 347 | window·size·(server·to·client)·is·always·12·while·the·decompression·window |
348 | (client·to·server)·size·may·be·12·or·15·depending·on·whether·the·client | 348 | (client·to·server)·size·may·be·12·or·15·depending·on·whether·the·client |
349 | supports·configuring·it.</p> | 349 | supports·configuring·it.</p> |
350 | <p>On·the·client·side,·websockets·lets·the·server·pick·a·suitable·value,·which | 350 | <p>On·the·client·side,·websockets·lets·the·server·pick·a·suitable·value,·which |
351 | has·the·same·effect·as·defaulting·to·15.</p> | 351 | has·the·same·effect·as·defaulting·to·15.</p> |
352 | </li> | 352 | </li> |
353 | </ul> | 353 | </ul> |
354 | <p>< | 354 | <p><code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">zlib</span></code>·offers·additional·parameters·for·tuning·compression.·They·control |
355 | the·trade-off·between·compression·rate,·memory·usage,·and·CPU·usage·only·for | 355 | the·trade-off·between·compression·rate,·memory·usage,·and·CPU·usage·only·for |
356 | compressing.·They’re·transparent·for·decompressing.·Unless·mentioned | 356 | compressing.·They’re·transparent·for·decompressing.·Unless·mentioned |
357 | otherwise,·websockets·inherits·defaults·of·< | 357 | otherwise,·websockets·inherits·defaults·of·<code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">compressobj()</span></code>.</p> |
358 | <ul> | 358 | <ul> |
359 | <li><p><strong>Memory·Level</strong>·controls·the·size·of·the·compression·state.·It·must·be·an | 359 | <li><p><strong>Memory·Level</strong>·controls·the·size·of·the·compression·state.·It·must·be·an |
360 | integer·between·1·(lowest·memory·usage)·and·9·(best·compression).</p> | 360 | integer·between·1·(lowest·memory·usage)·and·9·(best·compression).</p> |
361 | <p>websockets·defaults·to·5.·This·is·lower·than·zlib’s·default·of·8.·Not·only | 361 | <p>websockets·defaults·to·5.·This·is·lower·than·zlib’s·default·of·8.·Not·only |
362 | does·a·lower·memory·level·reduce·memory·usage,·but·it·can·also·increase | 362 | does·a·lower·memory·level·reduce·memory·usage,·but·it·can·also·increase |
363 | speed·thanks·to·memory·locality.</p> | 363 | speed·thanks·to·memory·locality.</p> |
364 | </li> | 364 | </li> |
Offset 297, 15 lines modified | Offset 297, 15 lines modified | ||
297 | <p>Often·CPU·is·the·limiting·factor.·If·a·server·process·goes·to·100%·CPU,·then | 297 | <p>Often·CPU·is·the·limiting·factor.·If·a·server·process·goes·to·100%·CPU,·then |
298 | you·reached·the·limit.·How·much·headroom·you·want·to·keep·is·up·to·you.</p> | 298 | you·reached·the·limit.·How·much·headroom·you·want·to·keep·is·up·to·you.</p> |
299 | <p>Once·you·know·how·many·connections·a·server·process·can·manage·and·how·many | 299 | <p>Once·you·know·how·many·connections·a·server·process·can·manage·and·how·many |
300 | connections·you·need·to·handle,·you·can·calculate·how·many·processes·to·run.</p> | 300 | connections·you·need·to·handle,·you·can·calculate·how·many·processes·to·run.</p> |
301 | <p>You·can·also·automate·this·calculation·by·configuring·an·autoscaler·to·keep | 301 | <p>You·can·also·automate·this·calculation·by·configuring·an·autoscaler·to·keep |
302 | CPU·usage·or·connection·count·within·acceptable·limits.</p> | 302 | CPU·usage·or·connection·count·within·acceptable·limits.</p> |
303 | <p>Don’t·scale·with·threads.·Threads·doesn’t·make·sense·for·a·server·built·with | 303 | <p>Don’t·scale·with·threads.·Threads·doesn’t·make·sense·for·a·server·built·with |
304 | < | 304 | <code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>.</p> |
305 | </section> | 305 | </section> |
306 | <section·id="how-do-i-run-processes"> | 306 | <section·id="how-do-i-run-processes"> |
307 | <h3>How·do·I·run·processes?<a·class="headerlink"·href="#how-do-i-run-processes"·title="Link·to·this·heading">#</a></h3> | 307 | <h3>How·do·I·run·processes?<a·class="headerlink"·href="#how-do-i-run-processes"·title="Link·to·this·heading">#</a></h3> |
308 | <p>Most·solutions·for·running·multiple·instances·of·a·server·process·fall·into | 308 | <p>Most·solutions·for·running·multiple·instances·of·a·server·process·fall·into |
309 | one·of·these·three·buckets:</p> | 309 | one·of·these·three·buckets:</p> |
310 | <ol·class="arabic·simple"> | 310 | <ol·class="arabic·simple"> |
311 | <li><p>Running·N·processes·on·a·platform:</p> | 311 | <li><p>Running·N·processes·on·a·platform:</p> |
Offset 375, 15 lines modified | Offset 375, 15 lines modified | ||
375 | and·clean·up·before·exiting.</p></li> | 375 | and·clean·up·before·exiting.</p></li> |
376 | <li><p>Otherwise,·it·should·be·waiting·on | 376 | <li><p>Otherwise,·it·should·be·waiting·on |
377 | <a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.wait_closed"·title="websockets.server.WebSocketServerProtocol.wait_closed"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">wait_closed()</span></code></a>,·so·it·can·receive·the | 377 | <a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServerProtocol.wait_closed"·title="websockets.server.WebSocketServerProtocol.wait_closed"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">wait_closed()</span></code></a>,·so·it·can·receive·the |
378 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·exception·and·exit.</p></li> | 378 | <a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosedOK"·title="websockets.exceptions.ConnectionClosedOK"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosedOK</span></code></a>·exception·and·exit.</p></li> |
379 | </ul> | 379 | </ul> |
380 | <p>This·example·is·easily·adapted·to·handle·other·signals.</p> | 380 | <p>This·example·is·easily·adapted·to·handle·other·signals.</p> |
381 | <p>If·you·override·the·default·signal·handler·for·SIGINT,·which·raises | 381 | <p>If·you·override·the·default·signal·handler·for·SIGINT,·which·raises |
382 | < | 382 | <code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">KeyboardInterrupt</span></code>,·be·aware·that·you·won’t·be·able·to·interrupt·a |
383 | program·with·Ctrl-C·anymore·when·it’s·stuck·in·a·loop.</p> | 383 | program·with·Ctrl-C·anymore·when·it’s·stuck·in·a·loop.</p> |
384 | </section> | 384 | </section> |
385 | </section> | 385 | </section> |
386 | <section·id="routing-connections"> | 386 | <section·id="routing-connections"> |
387 | <h2>Routing·connections<a·class="headerlink"·href="#routing-connections"·title="Link·to·this·heading">#</a></h2> | 387 | <h2>Routing·connections<a·class="headerlink"·href="#routing-connections"·title="Link·to·this·heading">#</a></h2> |
388 | <section·id="what-does-routing-involve"> | 388 | <section·id="what-does-routing-involve"> |
389 | <h3>What·does·routing·involve?<a·class="headerlink"·href="#what-does-routing-involve"·title="Link·to·this·heading">#</a></h3> | 389 | <h3>What·does·routing·involve?<a·class="headerlink"·href="#what-does-routing-involve"·title="Link·to·this·heading">#</a></h3> |
Offset 294, 15 lines modified | Offset 294, 15 lines modified | ||
294 | </ul> | 294 | </ul> |
295 | <p>Transitions·happen·in·the·following·places:</p> | 295 | <p>Transitions·happen·in·the·following·places:</p> |
296 | <ul·class="simple"> | 296 | <ul·class="simple"> |
297 | <li><p><code·class="docutils·literal·notranslate"><span·class="pre">CONNECTING</span>·<span·class="pre">-></span>·<span·class="pre">OPEN</span></code>:·in | 297 | <li><p><code·class="docutils·literal·notranslate"><span·class="pre">CONNECTING</span>·<span·class="pre">-></span>·<span·class="pre">OPEN</span></code>:·in |
298 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">connection_open()</span></code>·which·runs·when | 298 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">connection_open()</span></code>·which·runs·when |
299 | the·<a·class="reference·internal"·href="#opening-handshake"><span·class="std·std-ref">opening·handshake</span></a>·completes·and·the·WebSocket | 299 | the·<a·class="reference·internal"·href="#opening-handshake"><span·class="std·std-ref">opening·handshake</span></a>·completes·and·the·WebSocket |
300 | connection·is·established·—·not·to·be·confused·with | 300 | connection·is·established·—·not·to·be·confused·with |
301 | < | 301 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">connection_made()</span></code>·which·runs·when·the·TCP·connection |
302 | is·established;</p></li> | 302 | is·established;</p></li> |
303 | <li><p><code·class="docutils·literal·notranslate"><span·class="pre">OPEN</span>·<span·class="pre">-></span>·<span·class="pre">CLOSING</span></code>:·in | 303 | <li><p><code·class="docutils·literal·notranslate"><span·class="pre">OPEN</span>·<span·class="pre">-></span>·<span·class="pre">CLOSING</span></code>:·in |
304 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">write_frame()</span></code>·immediately·before | 304 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">write_frame()</span></code>·immediately·before |
305 | sending·a·close·frame;·since·receiving·a·close·frame·triggers·sending·a | 305 | sending·a·close·frame;·since·receiving·a·close·frame·triggers·sending·a |
306 | close·frame,·this·does·the·right·thing·regardless·of·which·side·started·the | 306 | close·frame,·this·does·the·right·thing·regardless·of·which·side·started·the |
307 | <a·class="reference·internal"·href="#closing-handshake"><span·class="std·std-ref">closing·handshake</span></a>;·also·in | 307 | <a·class="reference·internal"·href="#closing-handshake"><span·class="std·std-ref">closing·handshake</span></a>;·also·in |
308 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">fail_connection()</span></code>·which·duplicates | 308 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">fail_connection()</span></code>·which·duplicates |
Offset 325, 21 lines modified | Offset 325, 21 lines modified | ||
325 | succeeds,·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">connection_open()</span></code>·starts | 325 | succeeds,·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">connection_open()</span></code>·starts |
326 | two·tasks:</p> | 326 | two·tasks:</p> |
327 | <ul·class="simple"> | 327 | <ul·class="simple"> |
328 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·runs | 328 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·runs |
329 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">transfer_data()</span></code>·which·handles | 329 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">transfer_data()</span></code>·which·handles |
330 | incoming·data·and·lets·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a> | 330 | incoming·data·and·lets·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.recv"·title="websockets.legacy.protocol.WebSocketCommonProtocol.recv"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">recv()</span></code></a> |
331 | consume·it.·It·may·be·canceled·to·terminate·the·connection.·It·never·exits | 331 | consume·it.·It·may·be·canceled·to·terminate·the·connection.·It·never·exits |
332 | with·an·exception·other·than·< | 332 | with·an·exception·other·than·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">CancelledError</span></code>.·See·<a·class="reference·internal"·href="#data-transfer"><span·class="std·std-ref">data |
333 | transfer</span></a>·below.</p></li> | 333 | transfer</span></a>·below.</p></li> |
334 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">keepalive_ping_task</span></code>·runs | 334 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">keepalive_ping_task</span></code>·runs |
335 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">keepalive_ping()</span></code>·which·sends·Ping | 335 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">keepalive_ping()</span></code>·which·sends·Ping |
336 | frames·at·regular·intervals·and·ensures·that·corresponding·Pong·frames·are | 336 | frames·at·regular·intervals·and·ensures·that·corresponding·Pong·frames·are |
337 | received.·It·is·canceled·when·the·connection·terminates.·It·never·exits | 337 | received.·It·is·canceled·when·the·connection·terminates.·It·never·exits |
338 | with·an·exception·other·than·< | 338 | with·an·exception·other·than·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">CancelledError</span></code>.</p></li> |
339 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">close_connection_task</span></code>·runs | 339 | <li><p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">close_connection_task</span></code>·runs |
340 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_connection()</span></code>·which·waits·for | 340 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close_connection()</span></code>·which·waits·for |
341 | the·data·transfer·to·terminate,·then·takes·care·of·closing·the·TCP | 341 | the·data·transfer·to·terminate,·then·takes·care·of·closing·the·TCP |
342 | connection.·It·must·not·be·canceled.·It·never·exits·with·an·exception.·See | 342 | connection.·It·must·not·be·canceled.·It·never·exits·with·an·exception.·See |
343 | <a·class="reference·internal"·href="#connection-termination"><span·class="std·std-ref">connection·termination</span></a>·below.</p></li> | 343 | <a·class="reference·internal"·href="#connection-termination"><span·class="std·std-ref">connection·termination</span></a>·below.</p></li> |
344 | </ul> | 344 | </ul> |
345 | <p>Besides,·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">fail_connection()</span></code>·starts | 345 | <p>Besides,·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">fail_connection()</span></code>·starts |
Offset 432, 15 lines modified | Offset 432, 15 lines modified | ||
432 | <p>Public·methods·are·shown·in·green,·private·methods·in·yellow,·and·buffers·in | 432 | <p>Public·methods·are·shown·in·green,·private·methods·in·yellow,·and·buffers·in |
433 | orange.·Methods·related·to·connection·termination·are·omitted;·connection | 433 | orange.·Methods·related·to·connection·termination·are·omitted;·connection |
434 | termination·is·discussed·in·another·section·below.</p> | 434 | termination·is·discussed·in·another·section·below.</p> |
435 | </section> | 435 | </section> |
436 | <section·id="receiving-data"> | 436 | <section·id="receiving-data"> |
437 | <h3>Receiving·data<a·class="headerlink"·href="#receiving-data"·title="Link·to·this·heading">#</a></h3> | 437 | <h3>Receiving·data<a·class="headerlink"·href="#receiving-data"·title="Link·to·this·heading">#</a></h3> |
438 | <p>The·left·side·of·the·diagram·shows·how·websockets·receives·data.</p> | 438 | <p>The·left·side·of·the·diagram·shows·how·websockets·receives·data.</p> |
439 | <p>Incoming·data·is·written·to·a·< | 439 | <p>Incoming·data·is·written·to·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">StreamReader</span></code>·in·order·to |
440 | implement·flow·control·and·provide·backpressure·on·the·TCP·connection.</p> | 440 | implement·flow·control·and·provide·backpressure·on·the·TCP·connection.</p> |
441 | <p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>,·which·is·started | 441 | <p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>,·which·is·started |
442 | when·the·WebSocket·connection·is·established,·processes·this·data.</p> | 442 | when·the·WebSocket·connection·is·established,·processes·this·data.</p> |
443 | <p>When·it·receives·data·frames,·it·reassembles·fragments·and·puts·the·resulting | 443 | <p>When·it·receives·data·frames,·it·reassembles·fragments·and·puts·the·resulting |
444 | messages·in·the·<code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">messages</span></code>·queue.</p> | 444 | messages·in·the·<code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">messages</span></code>·queue.</p> |
445 | <p>When·it·encounters·a·control·frame:</p> | 445 | <p>When·it·encounters·a·control·frame:</p> |
446 | <ul·class="simple"> | 446 | <ul·class="simple"> |
Offset 462, 34 lines modified | Offset 462, 34 lines modified | ||
462 | <h3>Sending·data<a·class="headerlink"·href="#sending-data"·title="Link·to·this·heading">#</a></h3> | 462 | <h3>Sending·data<a·class="headerlink"·href="#sending-data"·title="Link·to·this·heading">#</a></h3> |
463 | <p>The·right·side·of·the·diagram·shows·how·websockets·sends·data.</p> | 463 | <p>The·right·side·of·the·diagram·shows·how·websockets·sends·data.</p> |
464 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·writes·one·or·several·data | 464 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·writes·one·or·several·data |
465 | frames·containing·the·message.·While·sending·a·fragmented·message,·concurrent | 465 | frames·containing·the·message.·While·sending·a·fragmented·message,·concurrent |
466 | calls·to·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·are·put·on·hold·until | 466 | calls·to·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.send"·title="websockets.legacy.protocol.WebSocketCommonProtocol.send"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">send()</span></code></a>·are·put·on·hold·until |
467 | all·fragments·are·sent.·This·makes·concurrent·calls·safe.</p> | 467 | all·fragments·are·sent.·This·makes·concurrent·calls·safe.</p> |
468 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.ping"·title="websockets.legacy.protocol.WebSocketCommonProtocol.ping"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ping()</span></code></a>·writes·a·ping·frame·and | 468 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.ping"·title="websockets.legacy.protocol.WebSocketCommonProtocol.ping"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">ping()</span></code></a>·writes·a·ping·frame·and |
469 | yields·a·< | 469 | yields·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Future</span></code>·which·will·be·completed·when·a·matching·pong |
470 | frame·is·received.</p> | 470 | frame·is·received.</p> |
471 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.pong"·title="websockets.legacy.protocol.WebSocketCommonProtocol.pong"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">pong()</span></code></a>·writes·a·pong·frame.</p> | 471 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.pong"·title="websockets.legacy.protocol.WebSocketCommonProtocol.pong"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">pong()</span></code></a>·writes·a·pong·frame.</p> |
472 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·writes·a·close·frame·and | 472 | <p><a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>·writes·a·close·frame·and |
473 | waits·for·the·TCP·connection·to·terminate.</p> | 473 | waits·for·the·TCP·connection·to·terminate.</p> |
474 | <p>Outgoing·data·is·written·to·a·< | 474 | <p>Outgoing·data·is·written·to·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">StreamWriter</span></code>·in·order·to |
475 | implement·flow·control·and·provide·backpressure·from·the·TCP·connection.</p> | 475 | implement·flow·control·and·provide·backpressure·from·the·TCP·connection.</p> |
476 | </section> | 476 | </section> |
477 | <section·id="closing-handshake"> | 477 | <section·id="closing-handshake"> |
478 | <span·id="id3"></span><h3>Closing·handshake<a·class="headerlink"·href="#closing-handshake"·title="Link·to·this·heading">#</a></h3> | 478 | <span·id="id3"></span><h3>Closing·handshake<a·class="headerlink"·href="#closing-handshake"·title="Link·to·this·heading">#</a></h3> |
479 | <p>When·the·other·side·of·the·connection·initiates·the·closing·handshake, | 479 | <p>When·the·other·side·of·the·connection·initiates·the·closing·handshake, |
480 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">read_message()</span></code>·receives·a·close | 480 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">read_message()</span></code>·receives·a·close |
481 | frame·while·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">OPEN</span></code>·state.·It·moves·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code>·state,·sends·a | 481 | frame·while·in·the·<code·class="docutils·literal·notranslate"><span·class="pre">OPEN</span></code>·state.·It·moves·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code>·state,·sends·a |
482 | close·frame,·and·returns·< | 482 | close·frame,·and·returns·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>,·causing |
483 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·to·terminate.</p> | 483 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·to·terminate.</p> |
484 | <p>When·this·side·of·the·connection·initiates·the·closing·handshake·with | 484 | <p>When·this·side·of·the·connection·initiates·the·closing·handshake·with |
485 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>,·it·moves·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code> | 485 | <a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.close"·title="websockets.legacy.protocol.WebSocketCommonProtocol.close"><code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">close()</span></code></a>,·it·moves·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code> |
486 | state·and·sends·a·close·frame.·When·the·other·side·sends·a·close·frame, | 486 | state·and·sends·a·close·frame.·When·the·other·side·sends·a·close·frame, |
487 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">read_message()</span></code>·receives·it·in·the | 487 | <code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">read_message()</span></code>·receives·it·in·the |
488 | <code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code>·state·and·returns·< | 488 | <code·class="docutils·literal·notranslate"><span·class="pre">CLOSING</span></code>·state·and·returns·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>,·also·causing |
489 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·to·terminate.</p> | 489 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·to·terminate.</p> |
490 | <p>If·the·other·side·doesn’t·send·a·close·frame·within·the·connection’s·close | 490 | <p>If·the·other·side·doesn’t·send·a·close·frame·within·the·connection’s·close |
491 | timeout,·websockets·<a·class="reference·internal"·href="#connection-failure"><span·class="std·std-ref">fails·the·connection</span></a>.</p> | 491 | timeout,·websockets·<a·class="reference·internal"·href="#connection-failure"><span·class="std·std-ref">fails·the·connection</span></a>.</p> |
492 | <p>The·closing·handshake·can·take·up·to·<code·class="docutils·literal·notranslate"><span·class="pre">2</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>:·one | 492 | <p>The·closing·handshake·can·take·up·to·<code·class="docutils·literal·notranslate"><span·class="pre">2</span>·<span·class="pre">*</span>·<span·class="pre">close_timeout</span></code>:·one |
493 | <code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·to·write·a·close·frame·and·one·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·to·receive | 493 | <code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·to·write·a·close·frame·and·one·<code·class="docutils·literal·notranslate"><span·class="pre">close_timeout</span></code>·to·receive |
494 | a·close·frame.</p> | 494 | a·close·frame.</p> |
495 | <p>Then·websockets·terminates·the·TCP·connection.</p> | 495 | <p>Then·websockets·terminates·the·TCP·connection.</p> |
Offset 540, 15 lines modified | Offset 540, 15 lines modified | ||
540 | <p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·exits,·unblocking | 540 | <p><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·exits,·unblocking |
541 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">close_connection_task</span></code>,·which·closes | 541 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">close_connection_task</span></code>,·which·closes |
542 | the·TCP·connection.</p> | 542 | the·TCP·connection.</p> |
543 | </section> | 543 | </section> |
544 | <section·id="server-shutdown"> | 544 | <section·id="server-shutdown"> |
545 | <span·id="id6"></span><h2>Server·shutdown<a·class="headerlink"·href="#server-shutdown"·title="Link·to·this·heading">#</a></h2> | 545 | <span·id="id6"></span><h2>Server·shutdown<a·class="headerlink"·href="#server-shutdown"·title="Link·to·this·heading">#</a></h2> |
546 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>·closes·asynchronously·like | 546 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer"·title="websockets.server.WebSocketServer"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">WebSocketServer</span></code></a>·closes·asynchronously·like |
547 | < | 547 | <code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">asyncio.Server</span></code>.·The·shutdown·happen·in·two·steps:</p> |
548 | <ol·class="arabic·simple"> | 548 | <ol·class="arabic·simple"> |
549 | <li><p>Stop·listening·and·accepting·new·connections;</p></li> | 549 | <li><p>Stop·listening·and·accepting·new·connections;</p></li> |
550 | <li><p>Close·established·connections·with·close·code·1001·(going·away)·or,·if | 550 | <li><p>Close·established·connections·with·close·code·1001·(going·away)·or,·if |
551 | the·opening·handshake·is·still·in·progress,·with·HTTP·status·code·503 | 551 | the·opening·handshake·is·still·in·progress,·with·HTTP·status·code·503 |
552 | (Service·Unavailable).</p></li> | 552 | (Service·Unavailable).</p></li> |
553 | </ol> | 553 | </ol> |
554 | <p>The·first·call·to·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer.close"·title="websockets.server.WebSocketServer.close"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">close</span></code></a>·starts·a | 554 | <p>The·first·call·to·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.WebSocketServer.close"·title="websockets.server.WebSocketServer.close"><code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">close</span></code></a>·starts·a |
Offset 564, 19 lines modified | Offset 564, 19 lines modified | ||
564 | passes·them·to·user-provided·connection·handlers.·This·is·an·<em>inversion·of | 564 | passes·them·to·user-provided·connection·handlers.·This·is·an·<em>inversion·of |
565 | control</em>·scenario:·library·code·calls·user·code.</p> | 565 | control</em>·scenario:·library·code·calls·user·code.</p> |
566 | <p>If·a·connection·drops,·the·corresponding·handler·should·terminate.·If·the | 566 | <p>If·a·connection·drops,·the·corresponding·handler·should·terminate.·If·the |
567 | server·shuts·down,·all·connection·handlers·must·terminate.·Canceling | 567 | server·shuts·down,·all·connection·handlers·must·terminate.·Canceling |
568 | connection·handlers·would·terminate·them.</p> | 568 | connection·handlers·would·terminate·them.</p> |
569 | <p>However,·using·cancellation·for·this·purpose·would·require·all·connection | 569 | <p>However,·using·cancellation·for·this·purpose·would·require·all·connection |
570 | handlers·to·handle·it·properly.·For·example,·if·a·connection·handler·starts | 570 | handlers·to·handle·it·properly.·For·example,·if·a·connection·handler·starts |
571 | some·tasks,·it·should·catch·< | 571 | some·tasks,·it·should·catch·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">CancelledError</span></code>,·terminate·or |
572 | cancel·these·tasks,·and·then·re-raise·the·exception.</p> | 572 | cancel·these·tasks,·and·then·re-raise·the·exception.</p> |
573 | <p>Cancellation·is·tricky·in·< | 573 | <p>Cancellation·is·tricky·in·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code>·applications,·especially·when·it |
574 | interacts·with·finalization·logic.·In·the·example·above,·what·if·a·handler | 574 | interacts·with·finalization·logic.·In·the·example·above,·what·if·a·handler |
575 | gets·interrupted·with·< | 575 | gets·interrupted·with·<code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">CancelledError</span></code>·while·it’s·finalizing |
576 | the·tasks·it·started,·after·detecting·that·the·connection·dropped?</p> | 576 | the·tasks·it·started,·after·detecting·that·the·connection·dropped?</p> |
577 | <p>websockets·considers·that·cancellation·may·only·be·triggered·by·the·caller·of | 577 | <p>websockets·considers·that·cancellation·may·only·be·triggered·by·the·caller·of |
578 | a·coroutine·when·it·doesn’t·care·about·the·results·of·that·coroutine·anymore. | 578 | a·coroutine·when·it·doesn’t·care·about·the·results·of·that·coroutine·anymore. |
579 | (Source:·<a·class="reference·external"·href="https://groups.google.com/forum/#!msg/python-tulip/LZQe38CR3bg/7qZ1p_q5yycJ">Guido·van·Rossum</a>).·Since·connection·handlers·run | 579 | (Source:·<a·class="reference·external"·href="https://groups.google.com/forum/#!msg/python-tulip/LZQe38CR3bg/7qZ1p_q5yycJ">Guido·van·Rossum</a>).·Since·connection·handlers·run |
580 | arbitrary·user·code,·websockets·has·no·way·of·deciding·whether·that·code·is | 580 | arbitrary·user·code,·websockets·has·no·way·of·deciding·whether·that·code·is |
581 | still·doing·something·worth·caring·about.</p> | 581 | still·doing·something·worth·caring·about.</p> |
582 | <p>For·these·reasons,·websockets·never·cancels·connection·handlers.·Instead·it | 582 | <p>For·these·reasons,·websockets·never·cancels·connection·handlers.·Instead·it |
Offset 597, 40 lines modified | Offset 597, 40 lines modified | ||
597 | <p>Once·the·WebSocket·connection·is·established,·internal·tasks | 597 | <p>Once·the·WebSocket·connection·is·established,·internal·tasks |
598 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·and | 598 | <code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">transfer_data_task</span></code>·and |
Max diff block lines reached; 16375/33359 bytes (49.09%) of diff not shown. |
Offset 299, 15 lines modified | Offset 299, 15 lines modified | ||
299 | <p>Finally,·you·can·enable·debug·logs·to·get·details·about·everything·websockets | 299 | <p>Finally,·you·can·enable·debug·logs·to·get·details·about·everything·websockets |
300 | is·doing.·This·can·be·useful·when·developing·clients·as·well·as·servers.</p> | 300 | is·doing.·This·can·be·useful·when·developing·clients·as·well·as·servers.</p> |
301 | <p>See·<a·class="reference·internal"·href="#log-levels"><span·class="std·std-ref">log·levels</span></a>·below·for·a·list·of·events·logged·by | 301 | <p>See·<a·class="reference·internal"·href="#log-levels"><span·class="std·std-ref">log·levels</span></a>·below·for·a·list·of·events·logged·by |
302 | websockets·logs·at·each·log·level.</p> | 302 | websockets·logs·at·each·log·level.</p> |
303 | </section> | 303 | </section> |
304 | <section·id="configure-logging"> | 304 | <section·id="configure-logging"> |
305 | <h2>Configure·logging<a·class="headerlink"·href="#configure-logging"·title="Link·to·this·heading">#</a></h2> | 305 | <h2>Configure·logging<a·class="headerlink"·href="#configure-logging"·title="Link·to·this·heading">#</a></h2> |
306 | <p>websockets·relies·on·the·< | 306 | <p>websockets·relies·on·the·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">logging</span></code>·module·from·the·standard·library·in |
307 | order·to·maximize·compatibility·and·integrate·nicely·with·other·libraries:</p> | 307 | order·to·maximize·compatibility·and·integrate·nicely·with·other·libraries:</p> |
308 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">logging</span> | 308 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">logging</span> |
309 | </pre></div> | 309 | </pre></div> |
310 | </div> | 310 | </div> |
311 | <p>websockets·logs·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">"websockets.client"</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">"websockets.server"</span></code> | 311 | <p>websockets·logs·to·the·<code·class="docutils·literal·notranslate"><span·class="pre">"websockets.client"</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">"websockets.server"</span></code> |
312 | loggers.</p> | 312 | loggers.</p> |
313 | <p>websockets·doesn’t·provide·a·default·logging·configuration·because | 313 | <p>websockets·doesn’t·provide·a·default·logging·configuration·because |
Offset 338, 20 lines modified | Offset 338, 20 lines modified | ||
338 | </pre></div> | 338 | </pre></div> |
339 | </div> | 339 | </div> |
340 | <p>However,·this·technique·runs·into·two·problems:</p> | 340 | <p>However,·this·technique·runs·into·two·problems:</p> |
341 | <ul·class="simple"> | 341 | <ul·class="simple"> |
342 | <li><p>The·formatter·applies·to·all·records.·It·will·crash·if·it·receives·a·record | 342 | <li><p>The·formatter·applies·to·all·records.·It·will·crash·if·it·receives·a·record |
343 | without·a·<code·class="docutils·literal·notranslate"><span·class="pre">websocket</span></code>·attribute.·For·example,·this·happens·when·logging | 343 | without·a·<code·class="docutils·literal·notranslate"><span·class="pre">websocket</span></code>·attribute.·For·example,·this·happens·when·logging |
344 | that·the·server·starts·because·there·is·no·current·connection.</p></li> | 344 | that·the·server·starts·because·there·is·no·current·connection.</p></li> |
345 | <li><p>Even·with·< | 345 | <li><p>Even·with·<code·class="xref·py·py-meth·docutils·literal·notranslate"><span·class="pre">str.format()</span></code>·style,·you’re·restricted·to·attribute·and·index |
346 | lookups,·which·isn’t·enough·to·implement·some·fairly·simple·requirements.</p></li> | 346 | lookups,·which·isn’t·enough·to·implement·some·fairly·simple·requirements.</p></li> |
347 | </ul> | 347 | </ul> |
348 | <p>There’s·a·better·way.·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·accept | 348 | <p>There’s·a·better·way.·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>·accept |
349 | a·<code·class="docutils·literal·notranslate"><span·class="pre">logger</span></code>·argument·to·override·the·default·< | 349 | a·<code·class="docutils·literal·notranslate"><span·class="pre">logger</span></code>·argument·to·override·the·default·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Logger</span></code>.·You |
350 | can·set·<code·class="docutils·literal·notranslate"><span·class="pre">logger</span></code>·to·a·< | 350 | can·set·<code·class="docutils·literal·notranslate"><span·class="pre">logger</span></code>·to·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">LoggerAdapter</span></code>·that·enriches·logs.</p> |
351 | <p>For·example,·if·the·server·is·behind·a·reverse | 351 | <p>For·example,·if·the·server·is·behind·a·reverse |
352 | proxy,·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"·title="websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">remote_address</span></code></a>·gives | 352 | proxy,·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"·title="websockets.legacy.protocol.WebSocketCommonProtocol.remote_address"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">remote_address</span></code></a>·gives |
353 | the·IP·address·of·the·proxy,·which·isn’t·useful.·IP·addresses·of·clients·are | 353 | the·IP·address·of·the·proxy,·which·isn’t·useful.·IP·addresses·of·clients·are |
354 | provided·in·an·HTTP·header·set·by·the·proxy.</p> | 354 | provided·in·an·HTTP·header·set·by·the·proxy.</p> |
355 | <p>Here’s·how·to·include·them·in·logs,·assuming·they’re·in·the | 355 | <p>Here’s·how·to·include·them·in·logs,·assuming·they’re·in·the |
356 | <code·class="docutils·literal·notranslate"><span·class="pre">X-Forwarded-For</span></code>·header:</p> | 356 | <code·class="docutils·literal·notranslate"><span·class="pre">X-Forwarded-For</span></code>·header:</p> |
357 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">basicConfig</span><span·class="p">(</span> | 357 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">basicConfig</span><span·class="p">(</span> |
Offset 376, 17 lines modified | Offset 376, 17 lines modified | ||
376 | <span·class="p">):</span> | 376 | <span·class="p">):</span> |
377 | ····<span·class="o">...</span> | 377 | ····<span·class="o">...</span> |
378 | </pre></div> | 378 | </pre></div> |
379 | </div> | 379 | </div> |
380 | </section> | 380 | </section> |
381 | <section·id="logging-to-json"> | 381 | <section·id="logging-to-json"> |
382 | <h2>Logging·to·JSON<a·class="headerlink"·href="#logging-to-json"·title="Link·to·this·heading">#</a></h2> | 382 | <h2>Logging·to·JSON<a·class="headerlink"·href="#logging-to-json"·title="Link·to·this·heading">#</a></h2> |
383 | <p>Even·though·< | 383 | <p>Even·though·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">logging</span></code>·predates·structured·logging,·it’s·still·possible·to |
384 | output·logs·as·JSON·with·a·bit·of·effort.</p> | 384 | output·logs·as·JSON·with·a·bit·of·effort.</p> |
385 | <p>First,·we·need·a·< | 385 | <p>First,·we·need·a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">Formatter</span></code>·that·renders·JSON:</p> |
386 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">json</span> | 386 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="kn">import</span>·<span·class="nn">json</span> |
387 | <span·class="kn">import</span>·<span·class="nn">logging</span> | 387 | <span·class="kn">import</span>·<span·class="nn">logging</span> |
388 | <span·class="kn">import</span>·<span·class="nn">datetime</span> | 388 | <span·class="kn">import</span>·<span·class="nn">datetime</span> |
389 | <span·class="k">class</span>·<span·class="nc">JSONFormatter</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">Formatter</span><span·class="p">):</span> | 389 | <span·class="k">class</span>·<span·class="nc">JSONFormatter</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">Formatter</span><span·class="p">):</span> |
390 | <span·class="w">····</span><span·class="sd">"""</span> | 390 | <span·class="w">····</span><span·class="sd">"""</span> |
391 | <span·class="sd">····Render·logs·as·JSON.</span> | 391 | <span·class="sd">····Render·logs·as·JSON.</span> |
Offset 424, 15 lines modified | Offset 424, 15 lines modified | ||
424 | <span·class="n">logger</span>·<span·class="o">=</span>·<span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">()</span> | 424 | <span·class="n">logger</span>·<span·class="o">=</span>·<span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">()</span> |
425 | <span·class="n">logger</span><span·class="o">.</span><span·class="n">addHandler</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">)</span> | 425 | <span·class="n">logger</span><span·class="o">.</span><span·class="n">addHandler</span><span·class="p">(</span><span·class="n">handler</span><span·class="p">)</span> |
426 | <span·class="n">logger</span><span·class="o">.</span><span·class="n">setLevel</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">INFO</span><span·class="p">)</span> | 426 | <span·class="n">logger</span><span·class="o">.</span><span·class="n">setLevel</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">INFO</span><span·class="p">)</span> |
427 | </pre></div> | 427 | </pre></div> |
428 | </div> | 428 | </div> |
429 | <p>Finally,·we·populate·the·<code·class="docutils·literal·notranslate"><span·class="pre">event_data</span></code>·custom·attribute·in·log·records·with | 429 | <p>Finally,·we·populate·the·<code·class="docutils·literal·notranslate"><span·class="pre">event_data</span></code>·custom·attribute·in·log·records·with |
430 | a·< | 430 | a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">LoggerAdapter</span></code>:</p> |
431 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">class</span>·<span·class="nc">LoggerAdapter</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">LoggerAdapter</span><span·class="p">):</span> | 431 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="k">class</span>·<span·class="nc">LoggerAdapter</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">LoggerAdapter</span><span·class="p">):</span> |
432 | <span·class="w">····</span><span·class="sd">"""Add·connection·ID·and·client·IP·address·to·websockets·logs."""</span> | 432 | <span·class="w">····</span><span·class="sd">"""Add·connection·ID·and·client·IP·address·to·websockets·logs."""</span> |
433 | ····<span·class="k">def</span>·<span·class="nf">process</span><span·class="p">(</span><span·class="bp">self</span><span·class="p">,</span>·<span·class="n">msg</span><span·class="p">,</span>·<span·class="n">kwargs</span><span·class="p">):</span> | 433 | ····<span·class="k">def</span>·<span·class="nf">process</span><span·class="p">(</span><span·class="bp">self</span><span·class="p">,</span>·<span·class="n">msg</span><span·class="p">,</span>·<span·class="n">kwargs</span><span·class="p">):</span> |
434 | ········<span·class="k">try</span><span·class="p">:</span> | 434 | ········<span·class="k">try</span><span·class="p">:</span> |
435 | ············<span·class="n">websocket</span>·<span·class="o">=</span>·<span·class="n">kwargs</span><span·class="p">[</span><span·class="s2">"extra"</span><span·class="p">][</span><span·class="s2">"websocket"</span><span·class="p">]</span> | 435 | ············<span·class="n">websocket</span>·<span·class="o">=</span>·<span·class="n">kwargs</span><span·class="p">[</span><span·class="s2">"extra"</span><span·class="p">][</span><span·class="s2">"websocket"</span><span·class="p">]</span> |
436 | ········<span·class="k">except</span>·<span·class="ne">KeyError</span><span·class="p">:</span> | 436 | ········<span·class="k">except</span>·<span·class="ne">KeyError</span><span·class="p">:</span> |
437 | ············<span·class="k">return</span>·<span·class="n">msg</span><span·class="p">,</span>·<span·class="n">kwargs</span> | 437 | ············<span·class="k">return</span>·<span·class="n">msg</span><span·class="p">,</span>·<span·class="n">kwargs</span> |
Offset 449, 24 lines modified | Offset 449, 24 lines modified | ||
449 | <span·class="p">):</span> | 449 | <span·class="p">):</span> |
450 | ····<span·class="o">...</span> | 450 | ····<span·class="o">...</span> |
451 | </pre></div> | 451 | </pre></div> |
452 | </div> | 452 | </div> |
453 | </section> | 453 | </section> |
454 | <section·id="disable-logging"> | 454 | <section·id="disable-logging"> |
455 | <h2>Disable·logging<a·class="headerlink"·href="#disable-logging"·title="Link·to·this·heading">#</a></h2> | 455 | <h2>Disable·logging<a·class="headerlink"·href="#disable-logging"·title="Link·to·this·heading">#</a></h2> |
456 | <p>If·your·application·doesn’t·configure·< | 456 | <p>If·your·application·doesn’t·configure·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">logging</span></code>,·Python·outputs·messages |
457 | of·severity·<code·class="docutils·literal·notranslate"><span·class="pre">WARNING</span></code>·and·higher·to·< | 457 | of·severity·<code·class="docutils·literal·notranslate"><span·class="pre">WARNING</span></code>·and·higher·to·<code·class="xref·py·py-data·docutils·literal·notranslate"><span·class="pre">stderr</span></code>.·As·a·consequence, |
458 | you·will·see·a·message·and·a·stack·trace·if·a·connection·handler·coroutine | 458 | you·will·see·a·message·and·a·stack·trace·if·a·connection·handler·coroutine |
459 | crashes·or·if·you·hit·a·bug·in·websockets.</p> | 459 | crashes·or·if·you·hit·a·bug·in·websockets.</p> |
460 | <p>If·you·want·to·disable·this·behavior·for·websockets,·you·can·add | 460 | <p>If·you·want·to·disable·this·behavior·for·websockets,·you·can·add |
461 | a·< | 461 | a·<code·class="xref·py·py-class·docutils·literal·notranslate"><span·class="pre">NullHandler</span></code>:</p> |
462 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">addHandler</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">NullHandler</span><span·class="p">())</span> | 462 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">addHandler</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">NullHandler</span><span·class="p">())</span> |
463 | </pre></div> | 463 | </pre></div> |
464 | </div> | 464 | </div> |
465 | <p>Additionally,·if·your·application·configures·< | 465 | <p>Additionally,·if·your·application·configures·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">logging</span></code>,·you·must·disable |
466 | propagation·to·the·root·logger,·or·else·its·handlers·could·output·logs:</p> | 466 | propagation·to·the·root·logger,·or·else·its·handlers·could·output·logs:</p> |
467 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">propagate</span>·<span·class="o">=</span>·<span·class="kc">False</span> | 467 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">propagate</span>·<span·class="o">=</span>·<span·class="kc">False</span> |
468 | </pre></div> | 468 | </pre></div> |
469 | </div> | 469 | </div> |
470 | <p>Alternatively,·you·could·set·the·log·level·to·<code·class="docutils·literal·notranslate"><span·class="pre">CRITICAL</span></code>·for·the | 470 | <p>Alternatively,·you·could·set·the·log·level·to·<code·class="docutils·literal·notranslate"><span·class="pre">CRITICAL</span></code>·for·the |
471 | <code·class="docutils·literal·notranslate"><span·class="pre">"websockets"</span></code>·logger,·as·the·highest·level·currently·used·is·<code·class="docutils·literal·notranslate"><span·class="pre">ERROR</span></code>:</p> | 471 | <code·class="docutils·literal·notranslate"><span·class="pre">"websockets"</span></code>·logger,·as·the·highest·level·currently·used·is·<code·class="docutils·literal·notranslate"><span·class="pre">ERROR</span></code>:</p> |
472 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">setLevel</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">CRITICAL</span><span·class="p">)</span> | 472 | <div·class="highlight-default·notranslate"><div·class="highlight"><pre><span></span><span·class="n">logging</span><span·class="o">.</span><span·class="n">getLogger</span><span·class="p">(</span><span·class="s2">"websockets"</span><span·class="p">)</span><span·class="o">.</span><span·class="n">setLevel</span><span·class="p">(</span><span·class="n">logging</span><span·class="o">.</span><span·class="n">CRITICAL</span><span·class="p">)</span> |
Offset 272, 15 lines modified | Offset 272, 15 lines modified | ||
272 | ········<article·role="main"> | 272 | ········<article·role="main"> |
273 | ··········<section·id="performance"> | 273 | ··········<section·id="performance"> |
274 | <h1>Performance<a·class="headerlink"·href="#performance"·title="Link·to·this·heading">#</a></h1> | 274 | <h1>Performance<a·class="headerlink"·href="#performance"·title="Link·to·this·heading">#</a></h1> |
275 | <p>Here·are·tips·to·optimize·performance.</p> | 275 | <p>Here·are·tips·to·optimize·performance.</p> |
276 | <section·id="uvloop"> | 276 | <section·id="uvloop"> |
277 | <h2>uvloop<a·class="headerlink"·href="#uvloop"·title="Link·to·this·heading">#</a></h2> | 277 | <h2>uvloop<a·class="headerlink"·href="#uvloop"·title="Link·to·this·heading">#</a></h2> |
278 | <p>You·can·make·a·websockets·application·faster·by·running·it·with·<a·class="reference·external"·href="https://github.com/MagicStack/uvloop">uvloop</a>.</p> | 278 | <p>You·can·make·a·websockets·application·faster·by·running·it·with·<a·class="reference·external"·href="https://github.com/MagicStack/uvloop">uvloop</a>.</p> |
279 | <p>(This·advice·isn’t·specific·to·websockets.·It·applies·to·any·< | 279 | <p>(This·advice·isn’t·specific·to·websockets.·It·applies·to·any·<code·class="xref·py·py-mod·docutils·literal·notranslate"><span·class="pre">asyncio</span></code> |
280 | application.)</p> | 280 | application.)</p> |
281 | </section> | 281 | </section> |
282 | <section·id="broadcast"> | 282 | <section·id="broadcast"> |
283 | <h2>broadcast<a·class="headerlink"·href="#broadcast"·title="Link·to·this·heading">#</a></h2> | 283 | <h2>broadcast<a·class="headerlink"·href="#broadcast"·title="Link·to·this·heading">#</a></h2> |
284 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.broadcast"·title="websockets.broadcast"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">broadcast()</span></code></a>·is·the·most·efficient·way·to·send·a·message·to | 284 | <p><a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.broadcast"·title="websockets.broadcast"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">broadcast()</span></code></a>·is·the·most·efficient·way·to·send·a·message·to |
285 | many·clients.</p> | 285 | many·clients.</p> |
286 | </section> | 286 | </section> |
Offset 305, 17 lines modified | Offset 305, 17 lines modified | ||
305 | practice·(“heartbeat”).·In·that·case,·it·terminates·the·connection·and·your | 305 | practice·(“heartbeat”).·In·that·case,·it·terminates·the·connection·and·your |
306 | application·gets·a·<a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·exception.</p></li> | 306 | application·gets·a·<a·class="reference·internal"·href="../../reference/exceptions/#websockets.exceptions.ConnectionClosed"·title="websockets.exceptions.ConnectionClosed"><code·class="xref·py·py-exc·docutils·literal·notranslate"><span·class="pre">ConnectionClosed</span></code></a>·exception.</p></li> |
307 | </ol> | 307 | </ol> |
308 | <p>Timings·are·configurable·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code> | 308 | <p>Timings·are·configurable·with·the·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·and·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code> |
309 | arguments·of·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.·Shorter·values | 309 | arguments·of·<a·class="reference·internal"·href="../../reference/asyncio/client/#websockets.client.connect"·title="websockets.client.connect"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">connect()</span></code></a>·and·<a·class="reference·internal"·href="../../reference/asyncio/server/#websockets.server.serve"·title="websockets.server.serve"><code·class="xref·py·py-func·docutils·literal·notranslate"><span·class="pre">serve()</span></code></a>.·Shorter·values |
310 | will·detect·connection·drops·faster·but·they·will·increase·network·traffic·and | 310 | will·detect·connection·drops·faster·but·they·will·increase·network·traffic·and |
311 | they·will·be·more·sensitive·to·latency.</p> | 311 | they·will·be·more·sensitive·to·latency.</p> |
312 | <p>Setting·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·to·< | 312 | <p>Setting·<code·class="docutils·literal·notranslate"><span·class="pre">ping_interval</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·the·whole·keepalive·and |
313 | heartbeat·mechanism.</p> | 313 | heartbeat·mechanism.</p> |
314 | <p>Setting·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·to·< | 314 | <p>Setting·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·disables·only·timeouts.·This·enables |
315 | keepalive,·to·keep·idle·connections·open,·and·disables·heartbeat,·to·support·large | 315 | keepalive,·to·keep·idle·connections·open,·and·disables·heartbeat,·to·support·large |
316 | latency·spikes.</p> | 316 | latency·spikes.</p> |
317 | <div·class="hint·admonition"> | 317 | <div·class="hint·admonition"> |
318 | <p·class="admonition-title">Why·doesn’t·websockets·rely·on·TCP·keepalive?</p> | 318 | <p·class="admonition-title">Why·doesn’t·websockets·rely·on·TCP·keepalive?</p> |
319 | <p>TCP·keepalive·is·disabled·by·default·on·most·operating·systems.·When | 319 | <p>TCP·keepalive·is·disabled·by·default·on·most·operating·systems.·When |
320 | enabled,·the·default·interval·is·two·hours·or·more,·which·is·far·too·much.</p> | 320 | enabled,·the·default·interval·is·two·hours·or·more,·which·is·far·too·much.</p> |
321 | </div> | 321 | </div> |
Offset 347, 15 lines modified | Offset 347, 15 lines modified | ||
347 | faster·than·a·server·can·process·them,·this·manifests·as·latency·as·well, | 347 | faster·than·a·server·can·process·them,·this·manifests·as·latency·as·well, |
348 | because·data·is·waiting·in·flight,·mostly·in·OS·buffers.</p> | 348 | because·data·is·waiting·in·flight,·mostly·in·OS·buffers.</p> |
349 | <p>If·the·server·is·more·than·20·seconds·behind,·it·doesn’t·see·the·Pong·before | 349 | <p>If·the·server·is·more·than·20·seconds·behind,·it·doesn’t·see·the·Pong·before |
350 | the·default·timeout·elapses.·As·a·consequence,·it·closes·the·connection. | 350 | the·default·timeout·elapses.·As·a·consequence,·it·closes·the·connection. |
351 | This·is·a·reasonable·choice·to·prevent·overload.</p> | 351 | This·is·a·reasonable·choice·to·prevent·overload.</p> |
352 | <p>If·traffic·spikes·cause·unwanted·timeouts·and·you’re·confident·that·the·server | 352 | <p>If·traffic·spikes·cause·unwanted·timeouts·and·you’re·confident·that·the·server |
353 | will·catch·up·eventually,·you·can·increase·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·or·you·can·set·it | 353 | will·catch·up·eventually,·you·can·increase·<code·class="docutils·literal·notranslate"><span·class="pre">ping_timeout</span></code>·or·you·can·set·it |
354 | to·< | 354 | to·<code·class="xref·py·py-obj·docutils·literal·notranslate"><span·class="pre">None</span></code>·to·disable·heartbeat·entirely.</p> |
355 | <p>The·same·reasoning·applies·to·situations·where·the·server·sends·more·traffic | 355 | <p>The·same·reasoning·applies·to·situations·where·the·server·sends·more·traffic |
356 | than·the·client·can·accept.</p> | 356 | than·the·client·can·accept.</p> |
357 | </li> | 357 | </li> |
358 | </ul> | 358 | </ul> |
359 | <p>The·latency·measured·during·the·last·exchange·of·Ping·and·Pong·frames·is | 359 | <p>The·latency·measured·during·the·last·exchange·of·Ping·and·Pong·frames·is |
360 | available·in·the·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.latency"·title="websockets.legacy.protocol.WebSocketCommonProtocol.latency"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">latency</span></code></a> | 360 | available·in·the·<a·class="reference·internal"·href="../../reference/asyncio/common/#websockets.legacy.protocol.WebSocketCommonProtocol.latency"·title="websockets.legacy.protocol.WebSocketCommonProtocol.latency"><code·class="xref·py·py-attr·docutils·literal·notranslate"><span·class="pre">latency</span></code></a> |
361 | attribute.·Alternatively,·you·can·measure·the·latency·at·any·time·with·the | 361 | attribute.·Alternatively,·you·can·measure·the·latency·at·any·time·with·the |
Offset 35, 28 lines modified | Offset 35, 28 lines modified | ||
35 | .sp | 35 | .sp |
36 | websockets·is·a·library·for·building·\fI\%WebSocket\fP·servers·and·clients·in·Python | 36 | websockets·is·a·library·for·building·\fI\%WebSocket\fP·servers·and·clients·in·Python |
37 | with·a·focus·on·correctness,·simplicity,·robustness,·and·performance. | 37 | with·a·focus·on·correctness,·simplicity,·robustness,·and·performance. |
38 | .sp | 38 | .sp |
39 | It·supports·several·network·I/O·and·control·flow·paradigms: | 39 | It·supports·several·network·I/O·and·control·flow·paradigms: |
40 | .INDENT·0.0 | 40 | .INDENT·0.0 |
41 | .IP·1.·3 | 41 | .IP·1.·3 |
42 | The·default·implementation·builds·upon·\f | 42 | The·default·implementation·builds·upon·\fBasyncio\fP,·Python\(aqs·standard |
43 | asynchronous·I/O·framework.·It·provides·an·elegant·coroutine\-based·API.·It\(aqs | 43 | asynchronous·I/O·framework.·It·provides·an·elegant·coroutine\-based·API.·It\(aqs |
44 | ideal·for·servers·that·handle·many·clients·concurrently. | 44 | ideal·for·servers·that·handle·many·clients·concurrently. |
45 | .IP·2.·3 | 45 | .IP·2.·3 |
46 | The·\f | 46 | The·\fBthreading\fP·implementation·is·a·good·alternative·for·clients, |
47 | especially·if·you·aren\(aqt·familiar·with·\f | 47 | especially·if·you·aren\(aqt·familiar·with·\fBasyncio\fP\&.·It·may·also·be·used |
48 | for·servers·that·don\(aqt·need·to·serve·many·clients. | 48 | for·servers·that·don\(aqt·need·to·serve·many·clients. |
49 | .IP·3.·3 | 49 | .IP·3.·3 |
50 | The·\fI\%Sans\-I/O\fP·implementation·is·designed·for·integrating·in·third\-party | 50 | The·\fI\%Sans\-I/O\fP·implementation·is·designed·for·integrating·in·third\-party |
51 | libraries,·typically·application·servers,·in·addition·being·used·internally | 51 | libraries,·typically·application·servers,·in·addition·being·used·internally |
52 | by·websockets. | 52 | by·websockets. |
53 | .UNINDENT | 53 | .UNINDENT |
54 | .sp | 54 | .sp |
55 | Here\(aqs·an·echo·server·with·the·\f | 55 | Here\(aqs·an·echo·server·with·the·\fBasyncio\fP·API: |
56 | .INDENT·0.0 | 56 | .INDENT·0.0 |
57 | .INDENT·3.5 | 57 | .INDENT·3.5 |
58 | .sp | 58 | .sp |
59 | .nf | 59 | .nf |
60 | .ft·C | 60 | .ft·C |
61 | #!/usr/bin/env·python | 61 | #!/usr/bin/env·python |
Offset 74, 15 lines modified | Offset 74, 15 lines modified | ||
74 | asyncio.run(main()) | 74 | asyncio.run(main()) |
75 | .ft·P | 75 | .ft·P |
76 | .fi | 76 | .fi |
77 | .UNINDENT | 77 | .UNINDENT |
78 | .UNINDENT | 78 | .UNINDENT |
79 | .sp | 79 | .sp |
80 | Here\(aqs·how·a·client·sends·and·receives·messages·with·the·\f | 80 | Here\(aqs·how·a·client·sends·and·receives·messages·with·the·\fBthreading\fP·API: |
81 | .INDENT·0.0 | 81 | .INDENT·0.0 |
82 | .INDENT·3.5 | 82 | .INDENT·3.5 |
83 | .sp | 83 | .sp |
84 | .nf | 84 | .nf |
85 | .ft·C | 85 | .ft·C |
86 | #!/usr/bin/env·python | 86 | #!/usr/bin/env·python |
Offset 192, 15 lines modified | Offset 192, 15 lines modified | ||
192 | .UNINDENT | 192 | .UNINDENT |
193 | .UNINDENT | 193 | .UNINDENT |
194 | .UNINDENT | 194 | .UNINDENT |
195 | .SS·Prerequisites | 195 | .SS·Prerequisites |
196 | .sp | 196 | .sp |
197 | This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript. | 197 | This·tutorial·assumes·basic·knowledge·of·Python·and·JavaScript. |
198 | .sp | 198 | .sp |
199 | If·you\(aqre·comfortable·with· | 199 | If·you\(aqre·comfortable·with·virtual·environments, |
200 | you·can·use·one·for·this·tutorial.·Else,·don\(aqt·worry:·websockets·doesn\(aqt·have | 200 | you·can·use·one·for·this·tutorial.·Else,·don\(aqt·worry:·websockets·doesn\(aqt·have |
201 | any·dependencies;·it·shouldn\(aqt·create·trouble·in·the·default·environment. | 201 | any·dependencies;·it·shouldn\(aqt·create·trouble·in·the·default·environment. |
202 | .sp | 202 | .sp |
203 | If·you·haven\(aqt·installed·websockets·yet,·do·it·now: | 203 | If·you·haven\(aqt·installed·websockets·yet,·do·it·now: |
204 | .INDENT·0.0 | 204 | .INDENT·0.0 |
205 | .INDENT·3.5 | 205 | .INDENT·3.5 |
206 | .sp | 206 | .sp |
Offset 313, 28 lines modified | Offset 313, 28 lines modified | ||
313 | \fBcolumn\fP·\-\-·between·\fB0\fP·and·\fB6\fP\&. | 313 | \fBcolumn\fP·\-\-·between·\fB0\fP·and·\fB6\fP\&. |
314 | .UNINDENT | 314 | .UNINDENT |
315 | .TP | 315 | .TP |
316 | .B·Returns | 316 | .B·Returns |
317 | Row·where·the·checker·lands,·between·\fB0\fP·and·\fB5\fP\&. | 317 | Row·where·the·checker·lands,·between·\fB0\fP·and·\fB5\fP\&. |
318 | .TP | 318 | .TP |
319 | .B·Raises | 319 | .B·Raises |
320 | \f | 320 | \fBRuntimeError\fP·\-\-·if·the·move·is·illegal. |
321 | .UNINDENT | 321 | .UNINDENT |
322 | .UNINDENT | 322 | .UNINDENT |
323 | .INDENT·7.0 | 323 | .INDENT·7.0 |
324 | .TP | 324 | .TP |
325 | .B·moves | 325 | .B·moves |
326 | List·of·moves·played·during·this·game,·as·\fB(player,·column,·row)\fP | 326 | List·of·moves·played·during·this·game,·as·\fB(player,·column,·row)\fP |
327 | tuples. | 327 | tuples. |
328 | .UNINDENT | 328 | .UNINDENT |
329 | .INDENT·7.0 | 329 | .INDENT·7.0 |
330 | .TP | 330 | .TP |
331 | .B·winner | 331 | .B·winner |
332 | \fI\%PLAYER1\fP·or·\fI\%PLAYER2\fP·if·they | 332 | \fI\%PLAYER1\fP·or·\fI\%PLAYER2\fP·if·they |
333 | won;·\f | 333 | won;·\fBNone\fP·if·the·game·is·still·ongoing. |
334 | .UNINDENT | 334 | .UNINDENT |
335 | .UNINDENT | 335 | .UNINDENT |
336 | .SS·Bootstrap·the·web·UI | 336 | .SS·Bootstrap·the·web·UI |
337 | .sp | 337 | .sp |
338 | Create·an·\fBindex.html\fP·file·next·to·\fBconnect4.js\fP·and·\fBconnect4.css\fP | 338 | Create·an·\fBindex.html\fP·file·next·to·\fBconnect4.js\fP·and·\fBconnect4.css\fP |
339 | with·this·content: | 339 | with·this·content: |
340 | .INDENT·0.0 | 340 | .INDENT·0.0 |
Offset 837, 15 lines modified | Offset 837, 15 lines modified | ||
837 | await·websocket.send(json.dumps(event)) | 837 | await·websocket.send(json.dumps(event)) |
838 | .ft·P | 838 | .ft·P |
839 | .fi | 839 | .fi |
840 | .UNINDENT | 840 | .UNINDENT |
841 | .UNINDENT | 841 | .UNINDENT |
842 | .INDENT·0.0 | 842 | .INDENT·0.0 |
843 | .INDENT·3.5 | 843 | .INDENT·3.5 |
844 | .IP·"Don\(aqt·forget·to·serialize·the·event·with·\f | 844 | .IP·"Don\(aqt·forget·to·serialize·the·event·with·\fBjson.dumps()\fP\&." |
845 | .sp | 845 | .sp |
846 | Else,·websockets·raises·\fBTypeError:·data·is·a·dict\-like·object\fP\&. | 846 | Else,·websockets·raises·\fBTypeError:·data·is·a·dict\-like·object\fP\&. |
847 | .UNINDENT | 847 | .UNINDENT |
848 | .UNINDENT | 848 | .UNINDENT |
849 | .sp | 849 | .sp |
850 | Modify·the·\fBhandler()\fP·coroutine·in·\fBapp.py\fP·as·follows: | 850 | Modify·the·\fBhandler()\fP·coroutine·in·\fBapp.py\fP·as·follows: |
851 | .INDENT·0.0 | 851 | .INDENT·0.0 |
Offset 918, 15 lines modified | Offset 918, 15 lines modified | ||
918 | .IP·\(bu·2 | 918 | .IP·\(bu·2 |
919 | parse·an·event·of·type·\fB\(dqplay\(dq\fP,·the·only·type·of·event·that·the·user | 919 | parse·an·event·of·type·\fB\(dqplay\(dq\fP,·the·only·type·of·event·that·the·user |
920 | interface·sends; | 920 | interface·sends; |
921 | .IP·\(bu·2 | 921 | .IP·\(bu·2 |
922 | play·the·move·in·the·board·with·the·\fI\%play()\fP·method, | 922 | play·the·move·in·the·board·with·the·\fI\%play()\fP·method, |
923 | alternating·between·the·two·players; | 923 | alternating·between·the·two·players; |
924 | .IP·\(bu·2 | 924 | .IP·\(bu·2 |
925 | if·\fI\%play()\fP·raises·\f | 925 | if·\fI\%play()\fP·raises·\fBRuntimeError\fP·because·the |
926 | move·is·illegal,·send·an·event·of·type·\fB\(dqerror\(dq\fP; | 926 | move·is·illegal,·send·an·event·of·type·\fB\(dqerror\(dq\fP; |
927 | .IP·\(bu·2 | 927 | .IP·\(bu·2 |
928 | else,·send·an·event·of·type·\fB\(dqplay\(dq\fP·to·tell·the·user·interface·where·the | 928 | else,·send·an·event·of·type·\fB\(dqplay\(dq\fP·to·tell·the·user·interface·where·the |
929 | checker·lands; | 929 | checker·lands; |
930 | .IP·\(bu·2 | 930 | .IP·\(bu·2 |
931 | if·the·move·won·the·game,·send·an·event·of·type·\fB\(dqwin\(dq\fP\&. | 931 | if·the·move·won·the·game,·send·an·event·of·type·\fB\(dqwin\(dq\fP\&. |
932 | .UNINDENT | 932 | .UNINDENT |
Offset 1206, 15 lines modified | Offset 1206, 15 lines modified | ||
1206 | In·addition·to·the·game·itself,·you·need·to·keep·track·of·the·WebSocket | 1206 | In·addition·to·the·game·itself,·you·need·to·keep·track·of·the·WebSocket |
1207 | connections·of·the·two·players.·Since·both·players·receive·the·same·events, | 1207 | connections·of·the·two·players.·Since·both·players·receive·the·same·events, |
1208 | you·don\(aqt·need·to·treat·the·two·connections·differently;·you·can·store·both | 1208 | you·don\(aqt·need·to·treat·the·two·connections·differently;·you·can·store·both |
1209 | in·the·same·set. | 1209 | in·the·same·set. |
1210 | .sp | 1210 | .sp |
Max diff block lines reached; 172944/177249 bytes (97.57%) of diff not shown. |