एक अन्य सर्वर को कॉल करने के लिए एसिन्सीओ सर्वर प्राप्त करें - पायथन, लूप, रनटाइम-त्रुटि, पायथन-एसिन्सीओ, सर्वर-टू-सर्वर

इसलिए मैंने asyncio क्लाइंट और सर्वर का उदाहरण संशोधित किया है (यहां पाया गया: https://docs.python.org/3/library/asyncio-protocol.html#protocol-example-tcp-echo-server-and-client) और मैं चाहता हूं कि सभी क्लाइंट के लिए सर्वरोनहोम को कॉल करें, और बदले में इसके लिए servertwo.py को कॉल करें।

client.py

#!/usr/bin/env python3.4
import asyncio

class EchoClient(asyncio.Protocol):
message = "This is the Client"

def connection_made(self, transport):
transport.write(self.message.encode())

def data_received(self, data):
print("data received: {}".format(data.decode()))

def connection_lost(self, exc):
asyncio.get_event_loop().stop()

loop = asyncio.get_event_loop()
coro = loop.create_connection(EchoClient, "127.0.0.1", 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

serverone.py

#!/usr/bin/env python3.4

import asyncio

class EchoClient(asyncio.Protocol):
message = "Server One sending message"

def connection_made(self, transport):
transport.write(self.message.encode())

def data_received(self, data):
print("data received: {}".format(data.decode()))

def connection_lost(self, exc):
asyncio.get_event_loop().stop()

class EchoServer(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info("peername")
self.transport = transport

def data_received(self, data):
loop = asyncio.get_event_loop()
coro = loop.create_connection(EchoClient, "127.0.0.1", 8889)
loop.run_until_complete(coro)
# close the socket
self.transport.close()
loop.close()

loop = asyncio.get_event_loop()
coro = loop.create_server(EchoServer, "127.0.0.1", 8888)
server = loop.run_until_complete(coro)
try:
loop.run_forever()
except KeyboardInterrupt:
print("exit")
finally:
server.close()
loop.close()

servertwo.py

#!/usr/bin/env python3.4

import asyncio

class EchoServer(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info("peername")
self.transport = transport

def data_received(self, data):
print("data received: {}".format(data.decode()))
self.transport.write(data)
# close the socket
self.transport.close()

loop = asyncio.get_event_loop()
coro = loop.create_server(EchoServer, "127.0.0.1", 8889)
server = loop.run_until_complete(coro)
try:
loop.run_forever()
except KeyboardInterrupt:
print("exit")
finally:
server.close()
loop.close()

मैं लॉन्च करता हूँ servertwo.py तथा serverone.py एक टर्मिनल में, फिर कॉल करें client.py। चीजें आंशिक रूप से काम करती हैं; क्लाइंट सर्वरोन को कॉल करता है जो सीरवर्टो को कॉल करता है, लेकिन फिर सर्वरोन इस त्रुटि के साथ विफल हो जाता है:

Exception in callback <bound method _SelectorSocketTransport._read_ready of <asyncio.selector_events._SelectorSocketTransport object at 0x7fbf4453b048>>()
handle: Handle(<bound method _SelectorSocketTransport._read_ready of <asyncio.selector_events._SelectorSocketTransport object at 0x7fbf4453b048>>, ())
Traceback (most recent call last):
File "/usr/lib64/python3.4/asyncio/events.py", line 39, in _run
self._callback(*self._args)
File "/usr/lib64/python3.4/asyncio/selector_events.py", line 458, in _read_ready
self._protocol.data_received(data)
File "./serverone.py", line 25, in data_received
loop.run_until_complete(coro)
File "/usr/lib64/python3.4/asyncio/base_events.py", line 203, in run_until_complete
self.run_forever()
File "/usr/lib64/python3.4/asyncio/base_events.py", line 179, in run_forever
raise RuntimeError("Event loop is running.")
RuntimeError: Event loop is running.

दस्तावेज़ीकरण "बहुत सारे अजीब उपयोग के मामलों को कवर नहीं करता है, इसलिए मैं थोड़ा अटक गया हूं।" क्या मुझे प्रयोग करना चाहिए? asyncio.async कॉल करने के लिए क्या मैं समस्या को सही तरीके से समझ रहा हूं?

मैं कैसे ठीक करूं या उससे बचूं RuntimeError?

उत्तर:

जवाब के लिए 3 № 1

आप उपयोग कर सकते हैं asyncio.async द्वारा तय किए गए कोरटीन को शेड्यूल करने के लिए create_connection इवेंट लूप द्वारा चलाया जाए, और उसके बाद उपयोग करें add_done_callback की विधि asyncio.Future (अधिक विशेष रूप से, ए asyncio.Task) उस async एक बार कोरटाइन होने के बाद लूप बंद करने के लिए रिटर्न:

class EchoServer(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info("peername")
self.transport = transport

def data_received(self, data):
loop = asyncio.get_event_loop()
coro = loop.create_connection(EchoClient, "127.0.0.1", 8890)
fut = asyncio.async(coro)
fut.add_done_callback(self.shutdown)

def shutdown(self, *args):
self.transport.close()
loop.stop()

संबंधित सवाल
सबसे लोकप्रिय