Я пытаюсь создать простой доморощенный локальный TCP-сервер, используя asyncio (это всего лишь Python 3.6.9, поскольку у меня только LTS Ubuntu на этой машине):
import asyncio
import socket
import urllib.parse
from http.server import BaseHTTPRequestHandler
from io import BytesIO
class HTTPRequest(BaseHTTPRequestHandler):
def __init__(self, request_text):
self.rfile = BytesIO(request_text)
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
rpc_request = urllib.parse.urlparse(self.path)
self.endpoint = rpc_request.path
self.query = urllib.parse.parse_qs(rpc_request.query)
def send_error(self, code, message):
self.error_code = code
self.error_message = message
class Srv(asyncio.Protocol):
def __init__(self, address=('127.0.0.1', 12345), family=socket.AF_INET, loop: asyncio.AbstractEventLoop=None):
self._address = address
self._family = family
self._loop = loop if loop is not None else asyncio.get_event_loop()
self._server = None
def connection_made(self, transport):
self._transport = transport
def data_received(self, data):
request = HTTPRequest(data)
print("\tQuery:", request.query)
self._transport.write(b'Hi!')
self._transport.close()
def eof_received(self):
pass
def factory(self):
return self
async def run(self):
sock = socket.socket(family=self._family)
sock.bind(self._address)
sock.listen()
if self._family == socket.AF_UNIX:
self._server = await self._loop.create_unix_server(protocol_factory=self.factory, sock=sock)
else:
self._server = await self._loop.create_server(protocol_factory=self.factory, sock=sock, family=self._family)
self._running = True
omg = Srv()
async def wat():
await omg.run()
await omg._server.wait_closed()
try:
asyncio.get_event_loop().run_until_complete(wat())
except:
omg._server.close()
Кажется, запуск и даже получение данных:
$ python3 0_o.py
Query: {'data': ['"abcd"']}
Query: {'data': ['"abcd"']}
(отпечатки сделаны с Srv.data_received
), но curl говорит, что не получает от него ответа:
$ curl '127.0.0.1:12345/query?data="abcd"'
curl: (52) Empty reply from server
$ curl '127.0.0.1:12345/query?data="abcd"'
curl: (52) Empty reply from server
С моей точки зрения, я я переопределил все из примеров эхо-серверов в документации python stdlib, но, очевидно, write()
и close()
внутри data_received()
, похоже, не дают никакого эффекта.
Чего мне не хватает?