Wednesday, 15 July 2015

Prompt for user input using python asyncio.create_server instance -


I am learning about Python 3 asyncio library, and I have participated in a small problem sent by the client Instead of email echo, I'm trying to optimize the ecosver instance from Python Docs to prompt for user input.

I thought it would be as easy to add a call to the input , But surely the input () will be blocked So that unless the user input causes problems.

Ideally I would like to continue to get data from the customer, even when nothing happens to "say" to the server is somewhat like a chat client where each connection is to chat with the server I want to be able to switch every individual connection and send the necessary input from stdin. Almost like a P2P chat client

consider the following modified EchoServer code:.

Class EchoServerClientProtocol asyncio Import (asyncio.Protocol): def connection_made (auto, transport): peername = Transport.get_extra_info ('peername') Print ('Connection to'). Format (name name)) self.transport = transport def data_received (self, data): message = data.decode () print ('Received data: {! R}'. Format (message)) Answer = Input () Print ('Send: {! R}'. Format (Answer) self.transport.write (reply.encode ()) # Print (Client Clock Socket ') #self.transport.close () loop = asyncio.get_event_loop ( ) # Each customer relationship will create a new protocol example Coro = loop.create_server (EchoServerClientProtocol, '127.0.0.1', 8888) server = loop.run_until_complete (coro) # until pressed CTRL + c print requests Go Defense is (are served on ''). Format (server.sockets [0] .getsockname ()) Try: loop.run_forever () except for KeyboardInterrupt: pass # server server.close off () loop.run_until_complete (server.wait_closed ()) loop.close () < / Code>

I will go to stdin on the input form on the server side and specify which connection to send the connection to the connected client still?

A callback to run when you have data available on sys.stdin Schedule, and then use to pass stdin data from your data_received method:

  import sys import asyncio def got_stdin_data (cue): asyncio.async (Q.put (sys.stdin.readline ()) class EchoServerClientProtocol (asyncio.Protocol): def connection_made (self, transport): peername = transport (., 'By name') '(' contact name ') format . (Format) (name)) self.transport = transport def data_failed (self, data): message = data.decode () print ('received data: {! R}'. Format (message)) fut = asyncio.async ( Q.get ()) fut.add_done_callback (self.write_reply) def write_reply (self, fut): responses = fut.result () print ('send: {! R}'. Format (answer)) self.transport.write (Reply.encode ()) # print ('close client socket') #self.transport.close () q = asyncio.Queue () loop = asyncio.get_event_loop () loop.add_reader (sys.stdin, got_stdin_data, cue ) # Each customer relationship is a new protocol example Coro = loop.create_server (EchoServerClientProtocol, '127.0.0.1', 8888) all R = loop.run_until_complete (will create code) #Until pressed CTRL + c, requests are pressed ('Serving' {} '. Format (server.sockets [0] .getsockname ())) Try: In addition to the keyboard interrupt: loop.run_forever (): close the # server server .coule () loop.run_until_complete (server.wait_closed ()) loop.close ()  

The only difficult thing is how we do queueput / que.get methods; Both are corline, which can not be used in the callback or protocol in the example methods by yielding yield . Instead, we schedule them with the event loop using asyncio.async , and then add_done_callback get () method call.


No comments:

Post a Comment