Aiohttp: Websocket рдХреНрд▓рд╛рдЗрдВрдЯ рд╣реИрдВрдЧрд┐рдВрдЧ / рдмреНрд▓реЙрдХрд┐рдВрдЧ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 26 рд╕рд┐рддре░ 2018  ┬╖  12рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: aio-libs/aiohttp

рдХрд╣рд╛рдиреА рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдореЗрдВ

ws.receive() рд╡реЗрдмрд╕реЛрдХреЗрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣рд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж рд▓рдЯрдХрд╛ рд╣реБрдЖ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИред

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░

ws.receive рдЖрдЙрдЯрдкреБрдЯ рдФрд░ рдХреБрдЫ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░

рдпрд╣ рд╕рд┐рд░реНрдл рд╡реЗрдмрд╕реНрдХреИрдЯ рдкрд░ рд╣реИрдВрдЧ / рдмреНрд▓реЙрдХ рд╣реЛрддрд╛ рд╣реИред

рдкреНрд░рдЬрдирди рдХреЗ рдЪрд░рдг

рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рд╣реИред

    async def _ws_subscribe(self,
                            session: ClientSession,
                            url: str
                            ) -> Dict:
        """ Fetch data from web socket asynchronously.

        This helper method fetches data from a web socket asynchronously. It is used to
        fetch subscribe to websockets of the SkyQ box.

        Args:
            session (aiohttp.ClientSession): Session to use when fetching the data.
            url (str): WebSocket URL to fetch.

        Returns:
            dict: The body of data returned.

        """
        LOGGER.debug(f"Inside _ws_subscribe()...")

        async with session.ws_connect(url, autoclose=False) as ws:
            while True:
                LOGGER.debug(f"Inside _ws_subscribe() infinite loop pre ws.receive.")
                payload = await ws.receive()
                LOGGER.debug(f"READ SOMETHING! _ws_subscribe() infinite loop post ws.receive")
                LOGGER.debug(f'type = {payload.type}')
                LOGGER.debug(f'payload data = {payload.data}')
                LOGGER.debug(f'payload exception = {ws.exception()}')
                if payload.type == aiohttp.WSMsgType.TEXT:
                    LOGGER.debug('Web-socket data received.')
                    asyncio.create_task(self._handle(payload))
                    # asyncio.ensure_future(self._handle(payload))
                elif payload.type == aiohttp.WSMsgType.BINARY:
                    LOGGER.debug('Web-socket binary data received.')
                elif payload.type == aiohttp.WSMsgType.PING:
                    LOGGER.debug('Web-socket ping received')
                    ws.pong()
                elif payload.type == aiohttp.WSMsgType.PONG:
                    LOGGER.debug('Web-socket pong received')
                else:
                    if payload.type == aiohttp.WSMsgType.CLOSE:
                        await ws.close()
                    elif payload.type == aiohttp.WSMsgType.ERROR:
                        LOGGER.info(f'Error during receive {ws.exception()}')
                    elif payload.type == aiohttp.WSMsgType.CLOSED:
                        pass

                    break

рдкрд░рд┐рдгрд╛рдо рд▓реЙрдЧ:

(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="6">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $ pyskyq -vv green
[2018-09-26 09:12:14] DEBUG:pyskyq.cli:Starting SkyQ...
[2018-09-26 09:12:14] DEBUG:pyskyq.skyremote:Initialised SkyRemote object with host=skyq, port=49160
[2018-09-26 09:12:14] DEBUG:pyskyq.status:Initialised Status object object with host=skyq, port=9006
[2018-09-26 09:12:14] DEBUG:asyncio:Using selector: KqueueSelector
[2018-09-26 09:12:14] DEBUG:pyskyq.status:Asyncio event loop thread running...
[2018-09-26 09:12:14] DEBUG:pyskyq.skyq:Initialised SkyQ object with host=skyq.
[2018-09-26 09:12:14] INFO:pyskyq.cli:Script ends here
[2018-09-26 09:12:14] DEBUG:pyskyq.status:Setting up web socket listener on ws://skyq:9006/as/system/status.
[2018-09-26 09:12:14] DEBUG:pyskyq.status:Inside _ws_subscribe()...
[2018-09-26 09:12:14] DEBUG:asyncio:Get address info skyq:9006, type=<SocketKind.SOCK_STREAM: 1>
[2018-09-26 09:12:14] DEBUG:asyncio:Getting address info skyq:9006, type=<SocketKind.SOCK_STREAM: 1> took 15.352ms: [(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('10.0.1.6', 9006))]
[2018-09-26 09:12:14] DEBUG:asyncio:poll 60478.847 ms took 14.299 ms: 1 events
[2018-09-26 09:12:14] DEBUG:asyncio:connect <socket.socket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('0.0.0.0', 0)> to ('10.0.1.6', 9006)
[2018-09-26 09:12:14] DEBUG:asyncio:poll 60461.657 ms took 21.045 ms: 1 events
[2018-09-26 09:12:14] DEBUG:asyncio:<socket.socket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('10.0.1.30', 50141), raddr=('10.0.1.6', 9006)> connected to 10.0.1.6:9006: (<_SelectorSocketTransport fd=8 read=polling write=<idle, bufsize=0>>, <aiohttp.client_proto.ResponseHandler object at 0x1033c8ac8>)
[2018-09-26 09:12:14] DEBUG:asyncio:poll 60429.970 ms took 7.192 ms: 1 events
[2018-09-26 09:12:14] DEBUG:pyskyq.status:Inside _ws_subscribe() infinite loop pre ws.receive.

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реЙрдХреЗрдЯ рдЦреБрд▓рд╛ рд╣реИ рдФрд░ рдбреЗрдЯрд╛ рдкрд░реЛрд╕ рд░рд╣рд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдиреЗрдЯрдХреИрдЯ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="6">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $ nc skyq 9006
GET /as/system/status HTTP/1.1
Host: skyq:9006
Accept: */*
Connection: Upgrade
Upgrade: websocket

я┐╜~я┐╜{
   "camessage" : {
      "reason" : "no message",
      "state" : "unavailable"
   },
   "drmstatus" : {
      "state" : "available"
   },
   "entitlements" : [
      "ANALYTICS",
      "BIGBASIC",
      "ETHAN_APP_1",
      "HD",
      "PDL",
      "SKY_DRM_CE",
      "SKY_DRM_MR",
      "SKY_IPPV",
      "ULTRA+",
      "SKY+",
      "GATEWAYENABLER",
      "SIDELOAD"
   ],
   "epginfobits" : {
      "epginfobits" : "0xFDE5FFC0",
      "mask" : "0x5FFA003F",
      "state" : "available"
   },
   "gatewayservices" : {
      "state" : "available"
   },
   "hdmi" : {
      "2160p10bitCapable" : false,
      "authenticatedHDCP" : "1.x",
      "sinkHDCP" : "1.x",
      "sinkHLG" : false,
      "sinkUHD" : false,
      "state" : "available",
      "uhdConfigured" : false
   },
   "network" : {
      "state" : "available"
   },
   "nssplayback" : {
      "state" : "available"
   },
   "pvr" : {
      "state" : "available"
   },
   "schedule" : {
      "lastdate" : "20181003",
      "state" : "available"
   },
   "servicelist" : {
      "state" : "available"
   },
   "smartcard" : {
      "active" : true,
      "bouquet" : "4101",
      "countryCode" : "GBR",
      "currency" : "GBP",
      "cwe" : true,
      "householdid" : "10947783",
      "paired" : true,
      "state" : "available",
      "subbouquet" : "1",
      "transactionlimit" : 65535,
      "viewingCardNumber" : "725 325 260"
   },
   "swupdate" : {
      "reason" : "IDLE",
      "state" : "unavailable"
   },
   "systemupdates" : {
      "entitlements" : 2,
      "install" : 1,
      "servicegenres" : 1,
      "smartcard" : 1
   },
   "updatetask" : {
      "reason" : "no update",
      "state" : "unavailable"
   }
}
^C(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="7">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $

рдЖрдкрдХрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг

(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="6">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $ uname -a
Darwin bradmac 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64
(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="7">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $ pip freeze
aiohttp==3.4.4
appnope==0.1.0
arrow==0.12.1
async-timeout==3.0.0
async-upnp-client==0.12.4
attrs==18.2.0
backcall==0.1.0
binaryornot==0.4.4
bleach==2.1.3
certifi==2018.4.16
chardet==3.0.4
click==6.7
cookiecutter==1.6.0
cycler==0.10.0
decorator==4.3.0
Django==2.1.1
entrypoints==0.2.3
ez-setup==0.9
future==0.16.0
html5lib==1.0.1
idna==2.7
idna-ssl==1.1.0
ipykernel==4.8.2
ipython==6.4.0
ipython-genutils==0.2.0
ipywidgets==7.2.1
jedi==0.12.0
Jinja2==2.10
jinja2-time==0.2.0
jsonschema==2.6.0
jupyter==1.0.0
jupyter-client==5.2.3
jupyter-console==5.2.0
jupyter-core==4.4.0
kaggle==1.4.2
kiwisolver==1.0.1
MarkupSafe==1.0
matplotlib==2.2.2
mistune==0.8.3
multidict==4.4.2
nbconvert==5.3.1
nbformat==4.4.0
notebook==5.5.0
numpy==1.14.4
pandocfilters==1.4.2
parso==0.2.1
pexpect==4.6.0
pickleshare==0.7.4
pipenv==2018.7.1
poyo==0.4.1
prompt-toolkit==1.0.15
ptyprocess==0.6.0
Pygments==2.2.0
pyparsing==2.2.0
PyScaffold==3.0.3
python-dateutil==2.7.3
python-didl-lite==1.1.0
pytz==2018.4
pyzmq==17.0.0
qtconsole==4.3.1
requests==2.19.1
Send2Trash==1.5.0
simplegeneric==0.8.1
six==1.11.0
terminado==0.8.1
testpath==0.3.1
tornado==5.0.2
tqdm==4.24.0
traitlets==4.3.2
urllib3==1.22
virtualenv==16.0.0
virtualenv-clone==0.3.0
voluptuous==0.11.5
wcwidth==0.1.7
webencodings==0.5.1
whichcraft==0.4.1
widgetsnbextension==3.2.1
yarl==1.2.6
(pyskyq-4vSEKDfZ) тЬФ [brad<strong i="8">@bradmac</strong>:~/Code/pyskyq] [16-create-status-end-point-property|тЬЪ 5тАж2] $

рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ...

рдкрд╛рдпрдерди рд╕рдВрд╕реНрдХрд░рдг 3.7.0 рд╣реИ

рд╕рднреА 12 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

GitMate.io рдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрднрд╡рддрдГ рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЗ https://github.com/aio-libs/aiohttp/issues/2200 (рдкреГрд╖реНрдарднреВрдорд┐ рдЧреНрд░рд╛рд╣рдХ рд╡реЗрдмрд╕рд╛рдЗрдХреЗрдЯ SIGINT рдкрд░ рд▓рдЯрдХреЗ рд╣реБрдП рд╣реИрдВ), https://github.com/aio-libs/aiohttp/issues/ 1002 (Websocket response .close () рдЕрдирд┐рд╢реНрдЪрд┐рдд рдХрд╛рд▓ рддрдХ рд▓рдЯрдХрд╛ рд░рд╣ рд╕рдХрддрд╛ рд╣реИ), https://github.com/aio-libs/aiohttp/issues/376 (ProactorEventLoop рд╣реИрдВрдЧ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ), https://github.com/aio-libs/aiohttp/issues / 3027 (ws_connect рд▓рдЯрдХрд╛), рдФрд░ https://github.com/aio-libs/aiohttp/issues/265 (рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд╡реЗрдмрд╕реНрдХреЗрдЯ рд▓рд╛рдЧреВ рдХрд░реЗрдВ)ред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдЬреИрд╕реЗ client_ws.py # L204 рдирд╣реАрдВ рд▓реМрдЯ рд░рд╣рд╛ рд╣реИ ... рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

рд╕рд░реНрд╡рд░ рдПрдХ рд╕реНрдХрд╛рдИрдХреНрдпреВ рд╕реЗрдЯ-рдЯреЙрдк рдмреЙрдХреНрд╕ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдбрдмреНрд▓реНрдпреВрдПрд╕ рдХреЗ рдЖрд░рдПрдлрд╕реА-рдЕрдиреБрдкрд╛рд▓рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрд┐рдВрдЧ / рдХрд╡рд┐рддрд╛рдУрдВ рдХрд╛ рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ ... рдФрд░ рдкреЗрд▓реЛрдб рдореЗрдВ рдЕрдЬреАрдм я┐╜~я┐╜ рд╣реИ ... рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдУрдкрдХреЛрдб рдпрд╛ рдХреБрдЫ рдЕрдиреНрдп рдХреНрд╡рд┐рдХ рд╣реИ ...

Websocket рдПрдХ рдмрд╛рдЗрдирд░реА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ я┐╜~я┐╜ рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓рдВрдмрд╛рдИ рдПрдиреНрдХреЛрдб рдХрд░рддрд╛ рд╣реИред
рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореИрдВ рдЗрд╕реЗ рдбрд┐рдХреЛрдб рдХрд░рдиреЗ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреЗрд▓реЛрдб рдЖрдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЖрдкрдХреА рднрд╛рдЧреАрджрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рдЖрдкрдХреА рдорджрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред

я┐╜~я┐╜ рдмрд╛рдЗрдирд░реА рдореЗрдВ 001111110111111000111111 рд╣реИ, рдЬреЛ рд╣реИ: рд╣реЗрдХреНрд╕ рдореЗрдВ 3F7E3F ред

рдЙрди рдмрд╛рдЗрдЯреНрд╕ рдЗрд╕ рдЕрдВрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреА рддрд░рд╣ рд▓рдЧ рд░рд╣реЗ рд╣реЛ ...
00111111
01111110
00111111

рдореИрдВ рд╡реЗрдВ RFC рдХрд╛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХреНрдпрд╛ рдХрд╣ рд░рд╣рд╛ рд╣реИ?

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рд╣реИ? рдпрд╛рдиреА, рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреЗрд▓реЛрдб рд▓рдВрдмрд╛рдИ рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реИ, рдФрд░ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдлреНрд░реЗрдо рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣реА рдЪреАрдЬ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП?

рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдпрд╣ рд╡реЗрдм рд╕реЙрдХреЗрдЯ рдХреНрд▓реА рдХреНрд▓рд╛рдЗрдВрдЯ , рдЬреЛ рд▓рд┐рдЦрд╛ рд╣реИ, рдЖрдЙрдЯрдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╢реАрд░реНрд╖ рдкрд░ рдмрд╛рдЗрдирд░реА рд╕рд╛рдорд╛рди рд╢рд╛рдорд┐рд▓ рд╣реИ:

`` `
ws ws: // skyq: 9006 / as / system / рд╕реНрдерд┐рддрд┐
<{
"рдЫрд▓рд╛рд╡рд╛": {
"рдХрд╛рд░рдг": "рдХреЛрдИ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ",
"рд░рд╛рдЬреНрдп": "рдЕрдиреБрдкрд▓рдмреНрдз"
},
"рдбреНрд░рдорд╕реНрдЯреИрдЯрд╕": {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"рд╣рдХрджрд╛рд░": [
"рд╡рд┐рд╢реНрд▓реЗрд╖рдг",
"BIGBASIC",
"ETHAN_APP_1",
"рдПрдЪрдбреА",
"рдкреАрдбреАрдПрд▓",
"SKY_DRM_CE",
"SKY_DRM_MR",
"SKY_IPPV",
"рдЕрд▓реНрдЯреНрд░рд╛ +",
"SKY +",
"GATEWAYENABLER",
"рд╕рд┐рдбрд▓реЙрдб"
],
"рдПрдкрд┐рдиреЗрдлреЛрдмрд┐рдЯреНрд╕": {
"рдПрдкрд┐рдиреЗрдлреЛрдмрд┐рдЯреНрд╕": "0xFDE5FFC0",
"рдорд╛рд╕реНрдХ": "0x5FFA003F",
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"рджреНрд╡рд╛рд░рдкрд╛рд▓": {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"hdmi": {
"2160p10bitCapable": рдЧрд▓рдд,
"рдкреНрд░рдорд╛рдгреАрдХреГрддHDCP": "рдХреЛрдИ рдирд╣реАрдВ",
"рдХрд╛рд░рдг": "рдПрдЪрдбреАрдПрдордЖрдИ рдЖрдЙрдЯрдкреБрдЯ рдкреЛрд░реНрдЯ рдЕрдХреНрд╖рдо рд╣реИ",
"рд╕рд┐рдВрдХрдПрдЪрдбреАрд╕реАрдкреА": "рдиреЛрди",
"рд╕рд┐рдВрдХрдПрдЪрдПрд▓рдЬреА": рдЧрд▓рдд,
"рд╕рд┐рдВрдХрдпреВрдПрдЪрдбреА": рдЧрд▓рдд,
"рд░рд╛рдЬреНрдп": "рдЕрдиреБрдкрд▓рдмреНрдз",
"uhdConfigured": рдЕрд╕рддреНрдп
},
"рдиреЗрдЯрд╡рд░реНрдХ" : {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"nssplayback": {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"pvr": {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"рдЕрдиреБрд╕реВрдЪреА" : {
"рдЕрдВрддрд┐рдо рддрд┐рдерд┐": "20181003",
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"рд╕рд░реНрд╡рд┐рд╕рд▓рд┐рд╕реНрдЯ": {
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз"
},
"рд╕реНрдорд╛рд░реНрдЯ рдХрд╛рд░реНрдб" : {
"рд╕рдХреНрд░рд┐рдп": рд╕рдЪ,
"рдЧреБрд▓рджрд╕реНрддрд╛": "4101",
"рджреЗрд╢рдХреЛрдб": "GBR",
"рдореБрджреНрд░рд╛": "GBP",
"cwe": рд╕рдЪ рд╣реИ,
"рдЧреГрд╣рд╕реНрде": "10947783",
"рдмрдирддреА": рд╕рдЪ,
"рд░рд╛рдЬреНрдп": "рдЙрдкрд▓рдмреНрдз",
"рд╕рдмрдмреЙрдХреЗрдЯ": "1",
"рд▓реЗрди-рджреЗрди рд╕рдВрдмрдВрдзреА": 65535,
"рд╡реНрдпреВрдЕрд░рдХрд╛рд░реНрдбрдирдВрдмрд░": "725 325 260"
},
"рд╕реНрд╡рдкрдж": {
"рдХрд╛рд░рдг": "IDLE",
"рд░рд╛рдЬреНрдп": "рдЕрдиреБрдкрд▓рдмреНрдз"
},
"рд╕рд┐рд╕реНрдЯрдо рдЕрдкрдбреЗрдЯ" : {
"рдПрдВрдЯрд╛рдЗрдЯреЗрд▓рдореЗрдВрдЯ": 2,
"рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ": 1,
"рд╕реЗрд╡рд╛рдпреЛрдЬрди": 1,
"рд╕реНрдорд╛рд░реНрдЯрдХрд╛рд░реНрдб": 1
},
"updatetask": {
"рдХрд╛рд░рдг": "рдХреЛрдИ рдЕрджреНрдпрддрди рдирд╣реАрдВ",
"рд░рд╛рдЬреНрдп": "рдЕрдиреБрдкрд▓рдмреНрдз"
}
}

^ рд╕реА
рдЗрдВрдЯрд░рдкреНрдЯ
тЬФ [ рдмреНрд░реИрдб @ рдмреНрд░реИрдбрдореИрдХ : ~] $ `` `

рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╣рддрд╛ рд╣реИ: WS рд╕рдВрджреЗрд╢ рдореЗрдВ рдкрд╣рд▓рд╛ 3F рдмрд╛рдЗрдЯ рдирд┐рд╖рд┐рджреНрдз рд╣реИ (рднрд╡рд┐рд╖реНрдп рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЖрд░рдХреНрд╖рд┐рдд)ред
рдХреНрдпрд╛ рдЖрдк рд╡рд╛рдХрдИ рдХреБрдЫ рдпрд╛рдж рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ?

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмреЗрд╕ рдлреНрд░реЗрдорд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдореЗрдВ 2d, 3rd рдФрд░ 4th рдмрд┐рдЯ рдХрд╛ рдЬрд┐рдХреНрд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдХрд┐рд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рд╛рдВ, рд╢рд╛рдпрдж рдореБрдЭреЗ рдЧрд▓рдд рд▓рдЧрд╛ред рдпрд╣ рдПрдХ рдпреВрдирд┐рдХреЛрдб / ASCII рдореБрджреНрджрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдПрдХ рдФрд░ рдирдЬрд╝рд░ рдбрд╛рд▓реВрдВрдЧрд╛ред

рдореИрдВрдиреЗ рдХреБрдЫ рдЕрдиреНрдп рдСрдирд▓рд╛рдЗрди рдХрдиреНрд╡рд░реНрдЯрд░реНрд╕ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ ... рдореБрдЭреЗ рдпрд╣ рдЕрдм рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ:
рд╣реЗрдХреНрд╕ = ef bf bd 7e ef bf bd
рдмрд╛рдЗрдирд░реА = 11101111 10111111 10111101 01111110 11101111 10111111 10111101

рдпрджрд┐ RFC 6455 рдХреЗ рдЕрдиреБрд╕рд╛рд░

5.2.  Base Framing Protocol

   This wire format for the data transfer part is described by the ABNF
   [RFC5234] given in detail in this section.  (Note that, unlike in
   other sections of this document, the ABNF in this section is
   operating on groups of bits.  The length of each group of bits is
   indicated in a comment.  When encoded on the wire, the most
   significant bit is the leftmost in the ABNF).  A high-level overview
   of the framing is given in the following figure.  In a case of
   conflict between the figure below and the ABNF specified later in
   this section, the figure is authoritative.

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

   FIN:  1 bit

      Indicates that this is the final fragment in a message.  The first
      fragment MAY also be the final fragment.

   RSV1, RSV2, RSV3:  1 bit each

      MUST be 0 unless an extension is negotiated that defines meanings
      for non-zero values.  If a nonzero value is received and none of
      the negotiated extensions defines the meaning of such a nonzero
      value, the receiving endpoint MUST _Fail the WebSocket
      Connection_.

рддрдм рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ RSV1 рдФрд░ RSV2 1 рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╕реБрдЭрд╛рд╡ рджреЗрддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рдХреБрдЫ etxension рдкрд░ рдмрд╛рддрдЪреАрдд рдирд╣реАрдВ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИ? рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИред

JSON рдбреЙрдХ рдореЗрдВ рд╡рд░реНрдгреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 1703

рдкреЗрд▓реЛрдб рд▓рдВрдмрд╛рдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ RFC рдХрд╛ рдХрд╣рдирд╛ рд╣реИ:

Payload length:  7 bits, 7+16 bits, or 7+64 bits

      The length of the "Payload data", in bytes: if 0-125, that is the
      payload length.  If 126, the following 2 bytes interpreted as a
      16-bit unsigned integer are the payload length.  If 127, the
      following 8 bytes interpreted as a 64-bit unsigned integer (the
      most significant bit MUST be 0) are the payload length.  Multibyte
      length quantities are expressed in network byte order.  Note that
      in all cases, the minimal number of bytes MUST be used to encode
      the length, for example, the length of a 124-byte-long string
      can't be encoded as the sequence 126, 0, 124.  The payload length
      is the length of the "Extension data" + the length of the
      "Application data".  The length of the "Extension data" may be
      zero, in which case the payload length is the length of the
      "Application data".

рддреЛ, рдпрд╣ рд╕рдм рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдЖрдЧреЗ рдХрд╣рд╛рдБ рдЬрд╛рддреЗ рд╣реИрдВ? рдпрджрд┐ рд╕рд░реНрд╡рд░ рдмреНрд░реЗрди-рдбреЗрдб рд╣реИ рдФрд░ RFC рдХрдВрдкреНрд▓реЗрдВрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдореБрдЭреЗ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреНрдп рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ... рдХреНрдпрд╛ рдЖрдк рдХреЛрдИ рд╕реБрдЭрд╛рд╡ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ?

рдЕрднреА рднреА рд╕рдВрджрд┐рдЧреНрдз рд▓рдЧ рд░рд╣рд╛ рд╣реИред
рдПрдХрдорд╛рддреНрд░ рдЬреНрдЮрд╛рдд рдПрдХреНрд╕рдЯреЗрдВрд╢рди WebSocket рд╕рдВрдкреАрдбрд╝рди рд╣реИ рдЬреЛ RSV1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ RSV2 рдХрд┐рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, opcode FF рднреА рдЖрд░рдХреНрд╖рд┐рдд рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЬрдм рддрдХ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рд╕рд░реНрд╡рд░ рдХреНрдпрд╛ рднреЗрдЬрддрд╛ рд╣реИ, рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ "рдареАрдХ" рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред

@asvetlov рдореИрдВрдиреЗ websockets рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ... рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЖрдкрдХреЗ рд╕рд╛рде рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдбреАрдмрдЧ рдХрд░рдиреЗ рдкрд░ рдЕрдзрд┐рдХ рд╕рдордп рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛ ...

aoihttp - рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ

import asyncio
import logging
import sys

import aiohttp

LOGGER = logging.getLogger(__name__)
logformat = "[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout,
                    format=logformat, datefmt="%Y-%m-%d %H:%M:%S")


async def main():
    async with aiohttp.ClientSession() as session:
        async with session.ws_connect('http://skyq:9006/as/system/status') as ws:
            payload = await ws.receive()
            print(payload.text)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

websockets - рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

import asyncio
import websockets
import logging
import sys

LOGGER = logging.getLogger(__name__)
logformat = "[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout,
                    format=logformat, datefmt="%Y-%m-%d %H:%M:%S")


async def hello():
    async with websockets.connect(
            'ws://skyq:9006/as/system/status') as websocket:

        payload = await websocket.recv()
        print(f"{payload}")

asyncio.get_event_loop().run_until_complete(hello())

рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ рддреЛ рдЗрд╕ рдЯрд┐рдХрдЯ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд▓реНрдХ рдореБрдХреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдЦреБрд▓рд╛ рд░рдЦрдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдмрдЧ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ ... рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдЬреЛ рдкреЛрд╕реНрдЯреЗрд▓ рдХреЗ рдирд┐рдпрдо рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░рддреА рд╣реИред

рдореИрдВ рдЗрд╕реЗ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдЖрдкрдХреА рдорджрдж рдХреА рд╕рд░рд╛рд╣рдирд╛ рдХрд░рддрд╛ рд╣реВрдВред

рдЕрднреА рднреА рд╕рдВрджрд┐рдЧреНрдз рд▓рдЧ рд░рд╣рд╛ рд╣реИред
рдПрдХрдорд╛рддреНрд░ рдЬреНрдЮрд╛рдд рдПрдХреНрд╕рдЯреЗрдВрд╢рди WebSocket рд╕рдВрдкреАрдбрд╝рди рд╣реИ рдЬреЛ RSV1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ RSV2 рдХрд┐рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, opcode FF рднреА рдЖрд░рдХреНрд╖рд┐рдд рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╣рд╛рдп @ рд╕рддреНрд╕рд▓реЛрд╡

рдЬрдм рддрдХ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рд╕рд░реНрд╡рд░ рдХреНрдпрд╛ рднреЗрдЬрддрд╛ рд╣реИ, рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ "рдареАрдХ" рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рдорддрд▓рдм рдерд╛ "рдЬрдм рддрдХ, рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдПрдХ рд╕рд░реНрд╡рд░ рдХреНрдпрд╛ рднреЗрдЬрддрд╛ рд╣реИ, рдЖрдк рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдареАрдХ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред"

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдЗрд╕ рдмрд╛рдд рд╕реЗ рдкреВрд░реА рддрд░рд╣ рдЕрд╕рд╣рдордд рд╣реВрдВред

рдЖрдк рд░реЛрдмрд╕реНрдЯрдиреЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ?

"рдЬреЛ рдЖрдк рднреЗрдЬрддреЗ рд╣реИрдВ, рдЙрд╕рдореЗрдВ рд░реВрдврд╝рд┐рд╡рд╛рджреА рд░рд╣реЗрдВ рдФрд░ рдЬреЛ рдЖрдк рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЙрд╕рдореЗрдВ рдЙрджрд╛рд░ рд╣реЛред"

MFC рдФрд░ SHOULDs рдФрд░ MUST NOTs рдХреЗ рдмрд╛рд╡рдЬреВрдж, RFC рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк RFC рдХреЗ рд╕рд╛рде рдЕрдиреБрдкрд╛рд▓рди рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ _completely _... рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡реЗ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХрдИ рдЗрдВрдЯрд░рдиреЗрдЯ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╣реИрдВ, рднрдпрд╛рд╡рд╣ bastardised рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЖрдзреЗ-рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред

рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп / рдкреНрд░реЛрдЯреЛрдХреЛрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрдирдХреЛ рдЗрд╕ рд╕реАрдорд╛ рддрдХ рдХреНрд╖рдорд╛ рдХрд░ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред RFC1122 рджреЗрдЦреЗрдВред рд╕рдВрдЪрд╛рд░ рдореЗрдВ рджреВрд╕рд░реЗ рдкреНрд░рддрд┐рднрд╛рдЧреА рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рдмрд┐рдирд╛ (рдХреБрдЫ) рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЙрд▓реНрд▓рдВрдШрди рдХреЛ рдорд╛рдл рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╡ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдЖрдк рд╣рд╛рд░реНрдб-рд▓рд╛рдЗрди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рдореЗрдЬрдмрд╛рди 100% рдЕрдиреБрдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмреБрд░рд╛ рд╣реИ, рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдмрд╣реБрдд рдмреБрд░рд╛ рд╣реИред рдпрд╣ рдХрд╣рдиреЗ рдЬреИрд╕рд╛ рд╣реИ: 'рдореИрдВ рдХреЗрд╡рд▓ рдорд╣рд╛рд░рд╛рдиреА рдХреА рдЕрдВрдЧреНрд░реЗрдЬреА рдмреЛрд▓рддрд╛ рд╣реВрдВ, рдФрд░ рдпрджрд┐ рдЖрдк рдореБрдЭрд╕реЗ рдЕрдВрдЧреНрд░реЗрдЬреА рдХреА рдХреБрдЫ рдЕрдЬреАрдм рдмреЛрд▓реА рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрд╕реЗ рдмрд╛рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред'

рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдкреВрд░рд╛ рдмрд┐рдВрджреБ рд╕рдВрдЪрд╛рд░ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рд╣реИред

рдЗрд╕рд▓рд┐рдП рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдмрд╛рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдХрдареЛрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╢рд╛рдВрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рдзрд┐ kwargs рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЬреЛ "рдЖрд░рд╛рдо рд╕реЗ рдирд┐рдкрдЯрдиреЗ" рдХреЛ рдЪрд╛рд▓реВ рдХрд░реЗрдВ), рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдЪреАрдЬреЛрдВ рдХреЛ рддрдм рднреА рдмрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рджреВрд╕рд░рд╛ рдкрдХреНрд╖ рдареАрдХ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реЛред ред

рдЗрд╕ рд╕рдорд╛рд▓реЛрдЪрдирд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рд╕рдореБрджрд╛рдп рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП aio-libs рдХрд╛ рдпреЛрдЧрджрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред ЁЯСН ЁЯСН

@asvetlov рдЗрд╕ рдкрд░ рд╕рд┐рд░реНрдл рдПрдХ рдЕрдкрдбреЗрдЯ ... рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдореЗрд░реЗ (рдЧреИрд░-рдЖрдЬреНрдЮрд╛рдХрд╛рд░реА) рд╕рд░реНрд╡рд░ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ Upgrade: рд╣реИрдбрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ рдореИрдВ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рд╢реАрд░реНрд╖рдХ рдХреЗрд╕ рд╣реЗрдбрд░ рдХреЗ рдореБрджреНрджреЗ рдкрд░ рдЖрдк рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ ... рдпрд╣ рдПрдХ рдЦрд░рд╛рдм рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдЙрд▓реНрд▓рдВрдШрди рдХрд╛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдорд▓рд╛ рд╣реИ рдЬреЛ рд╡реЗрдмрд╕реЛрдХреЗрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдХрд╛рдо рди рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

AtomsForPeace picture AtomsForPeace  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

JulienPalard picture JulienPalard  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

alxpy picture alxpy  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jonringer picture jonringer  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

kr41 picture kr41  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ