python - In a no-coroutine function, how do you get a return value from coroutine function of Tornado TCP? -


i wrote 3 sections of code tornado tcp. i've encountered difficulties.

my code following:

client.py

'''tcp client'''   socket import socket, af_inet, sock_stream s = socket(af_inet, sock_stream) s.connect(('localhost', 20000)) resp = s.recv(8192) print('response:', resp) s.send(b'hello\n') s.close() 

server.py

'''tcp server'''  #! /usr/bin/env python #coding=utf-8  tornado.tcpserver import tcpserver tornado.ioloop import ioloop tornado.gen import *  clientdict=dict()        #save infomation of client  class tcpconnection(object):     def __init__(self,stream,address):         self._stream=stream         self._address=address         self._stream.set_close_callback(self.on_close)      @coroutine     def send_messages(self):         yield self.send_message(b'world \n')         response = yield self.read_message()          return response       def read_message(self):         return self._stream.read_until(b'\n')      def send_message(self,data):         return self._stream.write(data)      def on_close(self):         global clientdict         clientdict.pop(self._address)         print("the monitored %d has left",self._address)  class monitorserver(tcpserver):     @coroutine     def handle_stream(self,stream,address):         global clientdict         print("new connection",address,stream)         clientdict.setdefault(address, tcpconnection(stream,address))    if __name__=='__main__':     print('server start .....')     server=monitorserver()     server.listen(20000)     ioloop.instance().start() 

main.py

import time threading import thread import copy server import *  def watchclient():     '''call "send" function when new client connect''      global clientdict     print('start watch')     lastclientlist=list()     while true:         currentclientlist=copy.deepcopy([key key in clientdict.keys()])         difference=list(set(currentclientlist).difference(set(lastclientlist)))          if len(difference)>0:             send(difference)             lastclientlist=copy.deepcopy(currentclientlist)             time.sleep(5)         else:             time.sleep(5)             continue  def send(addresslist):     '''send message new client , response'''     global clientdict     address in addresslist:         response=clientdict[address].send_messages()         print(address," response :",response)  def listen():     server=monitorserver()     server.listen(20000)     ioloop.instance().start()   if __name__=='__main__':     listenthread=thread(target=listen)     watchthead=thread(target=watchclient)     watchthead.start()     listenthread.start() 

i want "print information" when main.py run---address,response:b'hello\n'

but in fact "print information" ----

('127.0.0.1', 41233)  response :<tornado.concurrent.future object @ 0x7f2894d30518> 

it can't return b'hello\n'.

then guess can't response reasonably in no-coroutine function(def send(addresslist)) coroutine function( @coroutine def send_messages(self)).

how solve this?

by way, want know how make clientdict property of class monitorserver,not global property. please me! thank you.

in general, calls coroutine should coroutine itself. mixing threads , coroutines can tricky; coroutine-based code deliberately not thread-safe.

the correct way call coroutine non-coroutine function on different thread this:

def call_coro_from_thread(f, *args, **kwargs):     q = queue.queue()     def wrapper():         fut = f(*args, **kwargs)         fut.add_done_callback(q.put)     ioloop.instance().add_callback(wrapper)     fut = q.get()     return fut.result() 

ioloop.add_callback necessary safely transfer control ioloop thread, , queue used transfer result back.


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -