2017-08-18 4 views
3

J'ai un serveur Python WebSocket. Cela peut renvoyer une réponse lorsqu'il reçoit un message.Envoi actif de messages depuis le serveur Tornado WebSocket

import tornado.web 
import tornado.websocket 
import tornado.ioloop 

class WebSocketHandler(tornado.websocket.WebSocketHandler): 

    def open(self): 
     print("New client connected") 
     self.write_message("You are connected") 

    def on_message(self, message): 
     self.write_message(u"You said: " + message) 

    def on_close(self): 
     print("Client disconnected") 

    def check_origin(self, origin): 
     return True 

application = tornado.web.Application([ 
     (r"/", WebSocketHandler), 
]) 


if __name__ == "__main__": 
    application.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

Cependant, cela ne peut pas envoyer de messages avant qu'il n'en reçoive un. Comment envoyer un message activement? Par exemple, il mesure le temps et s'il n'a pas reçu de messages pendant 10 secondes, il envoie "Dormez-vous?". Je veux créer un chatbot en utilisant WebSocket. J'utilise tornado et websocket parce que je le sais seulement, et je serais intéressé si vous connaissez de meilleures méthodes à utiliser à cet égard.

Répondre

0

Vous pouvez ajouter un calendrier avec tornado.ioloop.PeriodicCallback et simplement vérifier s'il y a eu une activité ou non en fonction du temps, comme ce qui suit (je l'ai adapté à partir de votre code et this answer):

import tornado.web 
import tornado.websocket 
import tornado.ioloop 
import time 

class WebSocketHandler(tornado.websocket.WebSocketHandler): 
    def simple_init(self): 
     self.last = time.time() 
     self.stop = False 

    def open(self): 
     self.simple_init() 
     print("New client connected") 
     self.write_message("You are connected") 
     self.loop = tornado.ioloop.PeriodicCallback(self.check_ten_seconds, 1000, io_loop=tornado.ioloop.IOLoop.instance()) 
     self.loop.start() 

    def on_message(self, message): 
     self.write_message(u"You said: " + message) 
     self.last = time.time() 

    def on_close(self): 
     print("Client disconnected") 
     self.loop.stop() 

    def check_origin(self, origin): 
     return True 

    def check_ten_seconds(self): 
     print("Just checking") 
     if (time.time() - self.last > 10): 
      self.write_message("You sleeping mate?") 
      self.last = time.time() 

Maintenant, avec une alternance client entre la marche au ralenti et l'écriture (adapté de here):

class Client(object): 
    def __init__(self, url, timeout): 
     self.url = url 
     self.timeout = timeout 
     self.ioloop = IOLoop.instance() 
     self.ws = None 
     self.connect() 
     PeriodicCallback(self.keep_alive, 20000, io_loop=self.ioloop).start() 
     self.ioloop.start() 

    @gen.coroutine 
    def connect(self): 
     print("trying to connect") 
     try: 
      self.ws = yield websocket_connect(self.url) 
     except Exception as e: 
      print("connection error") 
     else: 
      print("connected") 
      self.run() 

    @gen.coroutine 
    def run(self): 
     once = False 
     while True: 
      msg = yield self.ws.read_message() 
      print(msg) 
      if once: 
       time.sleep(11) 
       once = False 
      else: 
       time.sleep(1) 
       once = True 
      self.ws.write_message("Hello matey") 
      if msg is None: 
       print("connection closed") 
       self.ws = None 
       break 

    def keep_alive(self): 
     if self.ws is None: 
      self.connect() 
     else: 
      self.ws.write_message("keep alive") 

on obtient le résultat escompté:

trying to connect 
connected 
You are connected 
You said: Hello matey 
You sleeping mate? 
You said: Hello matey 
You said: Hello matey 
You sleeping mate?