2014-12-23 4 views
2

Я пытаюсь создать сервер WebSocket с использованием очень популярного Tornado server for Python, но у меня возникла проблема с созданием переменной self с глобальным охватом для записи данных в веб-сокет вне класса.Threading с использованием глобальных переменных

This answer решил мою проблему точно, но я хотел сделать это еще дальше и обернуть все это в поток.

Это мое гнездо:

wss = [] 

class WSHandler(tornado.websocket.WebSocketHandler): 

    def check_origin(self, origin): 
     return True 

    def open(self): 
     print ('New connection established.') 
     if self not in wss: 
      wss.append(self) 

    def on_message(self, message): 
     print ('Received message: %s' % message) 

    def on_close(self): 
     print ('Connection closed.') 
     if self in wss: 
      wss.remove(self) 

Это метод, который находится за пределами класса, который записывает в сокет:

def write_data(message): 
    for ws in wss: 
     print ("Sending: %s" % message) 
     ws.write_message(message); 

Это резьбовая класс сервера:

class ServerThread(threading.Thread): 

    def run(self): 
     print ("Starting server.") 
     http_server = tornado.httpserver.HTTPServer(application) 
     http_server.listen(4045) 
     main_loop = tornado.ioloop.IOLoop.instance() 
     main_loop.start() 

    def send_data(self, message): 
     write_data(message); 

Странная вещь, когда код не завернут в класс Thread, запись m Этод прекрасно работает. В приведенном выше коде, когда я звоню:

server_thread = ServerThread() 
server_thread.start() 
server_thread.send_data("Ping!") 

ничего не происходит. Вводится метод write_data(message), но, очевидно, wss[] пуст.

Любая помощь, которую вы могли бы предоставить, была бы очень признательна!

Update:

Я постоянно смотрит в эту проблему, но безрезультатно. Еще одна странная вещь: New connection established. никогда не печатает на консоль, заставляя меня думать, что сокет никогда не присоединяется к списку, а не является проблемой с переменным охватом.

+0

Я не могу воспроизвести это. https://gist.github.com/binux/2e1c7b3b2b8de18f950c Существуют ли какие-либо другие потоки в вашей программе? tornado.ioloop.IOLoop.instance() - это общий объект IOLoop, который не работает с потоком. – Binux

+0

Это то, что у меня есть до сих пор: http://pastebin.com/S4hkDRqg Оператор печати в 'send_data (self, message)' работает не так, как ожидалось, и сокет не пишет 'Ping!' –

+0

Вы не должен отправлять send_data после thread.start немедленно. Пока веб-узел еще не подключен. – Binux

ответ

Смежные вопросы