我正在嘗試製作一個通常向服務器發送請求並接收響應的應用程序。如果它本來就是這樣的話,我會和HTTP一起去,並稱它爲一筆交易。但是,對服務器的某些請求會對其他客戶端進行更改,因此我希望服務器向所有受影響的客戶端發送一條應該更新的消息。
爲此,我選擇了WebSockets協議和Tornado庫以使用Python進行工作。簡單的消息交換非常簡單,儘管不同步。但是,WebSocket客戶端實際上不是可配置的,我一直在努力讓客戶端監聽傳入的通知,而不會中斷主消息交換。如何使龍捲風websocket客戶端接收服務器通知?
服務器部分由tornado.websocket.WebSocketHandler
,其具有on_message
方法表示:
from tornado.websocket import WebSocketHandler
class MyHandler(WebSocketHandler):
def on_message(self, message):
print('message:', message)
我想類似的東西在客戶端部,其僅由函數tornado.websocket.websocket_connect
表示(source) 。該功能發起tornado.websocket.WebSocketClientConnection
(source)對象,其具有方法on_message
,但由於纏結異步結構,我還沒有能夠正確地重寫它,而不會破壞主要消息交換。
我試圖去另一種方式是on_message_callback
。這聽起來像我可以使用的東西,但我不知道如何使用它與read_message
。這是我最好的嘗試:
import tornado.websocket
import tornado.ioloop
ioloop = tornado.ioloop.IOLoop.current()
def clbk(message):
print('received', message)
async def main():
url = 'server_url_here'
conn = await tornado.websocket.websocket_connect(url, io_loop = ioloop, on_message_callback=clbk)
while True:
print(await conn.read_message()) # The execution hangs here
st = input()
conn.write_message(st)
ioloop.run_sync(main)
有了這個是服務器代碼:
import tornado.ioloop
import tornado.web
import tornado.websocket
import os
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def open(self):
self.write_message('hello')
def on_message(self, message):
self.write_message(message)
self.write_message('notification')
if __name__ == "__main__":
app = tornado.web.Application([(r"/", EchoWebSocket)])
app.listen(os.getenv('PORT', 8080))
tornado.ioloop.IOLoop.current().start()
我不知道是怎麼回事。我甚至用這個方向走向正確的方向嗎?
但是,我們的主要問題?我如何運行常規消息交換並同時接收通知? – Leva7
有了回調函數,你可以擺脫'while/read_message'循環,並在需要時調用'conn.write_message'。使用'input()'做這個工作很棘手,但如果你真正想調用'write_message'的時間在回調中,它就會工作。使用協程,使用'IOLoop.spawn_callback'啓動兩個協程,一個運行讀取循環,另一個執行任何其他您想要執行的操作來生成消息。 –