2

Have an app that is using (Python 3.6) Tkinter & Tornado. Would like it send a websocket message when a button is pressed.

The sendSocket is in my class that handles the interface. I am able to open my sockets ok, and can send data into the socket handler ok. Additionally, it serves up my html file ok from my RequestHandler.

I can see that my code hits the sendSocketMessage line ok. However, I never get the print from within the SocketHandler.send_message def. There are no errors in the console.

    def sendSocketMessage(self, data = "whatever"):
        print("sending")
        #WebSocketeer.send_message(data)        
        ioloop.IOLoop.current().add_callback(WebSocketeer.send_message, data)

class WebSocketeer(websocket.WebSocketHandler):    
    def open(self):
       print("WebSocket opened")

    def on_message(self, message):
       print("got message: " + message)

    def on_close(self):
       print("WebSocket closed")

    @classmethod
    def send_message(self, message):
        print("sending message: " + message)
        for session_id, session in self.session.server._sessions._items.iteritems():
            session.conn.emit(event, message)

Code based off of these SO responses

2
  • add_callback is not working? That is rather strange. Commented Oct 1, 2018 at 3:51
  • Can you try with a lambda and see if it works, example - ioloop.IOLoop.current().add_callback(lambda: WebSocketeer.send_message(data))? Commented Oct 1, 2018 at 4:02

2 Answers 2

0

Found a way to make it work here: How to run functions outside websocket loop in python (tornado)

But am still wondering why the add_callback doesn't work - as, from what I've read, this is the recommended way.

Sign up to request clarification or add additional context in comments.

Comments

0

This is what I've got working, taken from: https://github.com/tornadoweb/tornado/issues/2802

clients = [];
class WSHandler(tornado.websocket.WebSocketHandler):
    
    def open(self):
        print('connection opened...')
        clients.append(self);

    def on_message(self, message):
        self.write_message("The server says: " + message + " back at you")
        print('received:', message)

    def on_close(self):
        clients.remove(self);
        print('connection closed...')

    @classmethod
    def send_message(self, message):
        print("sending message: " + message)
        for client in clients:
            client.write_message(message);
        #for session_id, session in self.session.server._sessions._items.iteritems():
        #    session.conn.emit(event, message);
        return True;

def sendRandom():
    global thread, data;
    try:
        print("sendRandom()");
        time.sleep(0.125);
        n = random.randint(0,1000);
        data = str(n);
        data = {"msg":"data","data":data};
        if eventLoop is not None:
            #If response needed
                #sendData(eventLoop,WSHandler.send_message,json.dumps(data));
            #else
            eventLoop.add_callback(WSHandler.send_message,json.dumps(data));
    except:
        print("Err");
        traceback.print_exc();

clients = [];

def sendData(loop,f,*a,**kw):
    print("%s %s" % (type(loop),type(f)));
    concurrent_future = concurrent.futures.Future();
    async def wrapper():
        try:
           rslt = f(*a,**kw);
        except Exception as e:
            concurrent_future.set_exception(e);
        else:
            concurrent_future.set_result(rslt);
    loop.add_callback(wrapper);
    return concurrent_future.result();

eventLoop = None;

application = tornado.web.Application([
   (r'/data', WSHandler),
    ])

def startServer():
    global eventLoop;
    try:
        print("Starting server @%s:%d" %("localhost",9090));  
        asyncio.set_event_loop(asyncio.new_event_loop());
        eventLoop = tornado.ioloop.IOLoop();
        application.listen(9090)
        eventLoop.start();
    except KeyboardInterrupt:
        print("^C");
    except:
        print("ERR");
        traceback.print_exc();

if __name__ == "__main__":
    thread = Thread(target=startServer,);
    thread.setDaemon(True);
    thread.start();
    time.sleep(5);
    while True:
        sendRandom(); 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.