I'm not very experienced with Python and new to Tornado websockets, so I have a problem grasping the idea how it actually works.
Concretely, this is a usual example:
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def open(self):
print("WebSocket opened")
def on_message(self, message):
self.write_message(u"You said: " + message)
def on_close(self):
print("WebSocket closed")
What confuses me is the way the requests are served. I read that Tornado is non-blocking and if understood well single-threaded, where each request is handled by a handler in a fast way and if the operation lasts longer then there are callbacks which are called when certain operation (e.g. database) is finished. This allows a large number of users to be served. But what confuses me with these websockets and examples, is what is self in this case?
I know that it is a similar thing like this in Java and C#, but I don't understand how this self represents different clients each time a client sends a message? Moreover, is there only a single instance of EchoWebSocket per application, or there is an instance per request?
Additionally, how should I keep the references to the clients? I tried two ways:
class EchoWebSocket(tornado.websocket.WebSocketHandler):
clients = []
def open(self):
print("WebSocket opened")
def on_message(self, message):
EchoWebSocket.clients.append(self)
self.write_message(u"You said: " + message)
def on_close(self):
print("WebSocket closed")
And
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def __init__(self, application, request):
super(EchoWebSocket,self).__init__(application, request)
self.clients = []
def open(self):
print("WebSocket opened")
def on_message(self, message):
self.clients.append(self)
self.write_message(u"You said: " + message)
def on_close(self):
print("WebSocket closed")
But the second approach doesn't seem to be working. What is the proper way to do it and why?
In python, by convention self
is a reference to the current class' instance object.
AFAIK, the tornado framework creates an instance of the class WebSocketHandler for each client. So you don't really have to keep a reference to clients. Each client is naturally handled by a different instance of the handler. Practically it means that self
will be different objects for two distinct clients.
To keep references to connected clients, something like that would work:
class EchoWebSocket(tornado.websocket.WebSocketHandler):
all_clients = set()
def open(self):
self.all_clients.add(self)
def on_message(self, message):
pass
def on_close(self):
self.all_clients.remove(self)