2014-02-21 146 views
1

我創建了一個分開運行的zmq_forwarder.py,它將消息從應用程序傳遞到sockJS連接,目前我正在處理燒瓶應用程序如何通過zmq從sockJS接收消息。我正在粘貼我的zmq_forwarder.py的內容。即時通訊新的ZMQ,我不知道爲什麼每次我運行它,它使用100%的CPU負載。如何避免CPU使用率過高?

import zmq 

# Prepare our context and sockets 
context = zmq.Context() 

receiver_from_server = context.socket(zmq.PULL) 
receiver_from_server.bind("tcp://*:5561") 

forwarder_to_server = context.socket(zmq.PUSH) 
forwarder_to_server.bind("tcp://*:5562") 

receiver_from_websocket = context.socket(zmq.PULL) 
receiver_from_websocket.bind("tcp://*:5563") 

forwarder_to_websocket = context.socket(zmq.PUSH) 
forwarder_to_websocket.bind("tcp://*:5564") 

# Process messages from both sockets 
# We prioritize traffic from the server 
while True: 

    # forward messages from the server 
    while True: 
     try: 
      message = receiver_from_server.recv(zmq.DONTWAIT) 
     except zmq.Again: 
      break 

     print "Received from server: ", message 
     forwarder_to_websocket.send_string(message) 

    # forward messages from the websocket 
    while True: 
     try: 
      message = receiver_from_websocket.recv(zmq.DONTWAIT) 
     except zmq.Again: 
      break 

     print "Received from websocket: ", message 
     forwarder_to_server.send_string(message) 

正如你所看到的,我已經設置了4個插座。應用程序連接到端口5561將數據推送到zmq,端口5562從zmq接收(雖然我仍然想知道如何實際設置它來監聽由zmq發送的消息)。在另一方面,從sockjs接收ZMQ端口5564的數據和將數據發送到其上的端口5563.

我讀過zmq.DONTWAIT使得接收到消息異步和非阻塞的,所以我加入它。

有沒有辦法改善代碼,以便我不超載CPU?目標是能夠使用zmq在flask應用程序和websocket之間傳遞消息。

回答

5

您正在輪詢您的兩個接收器插槽,沒有任何阻塞(zmq.DONTWAIT),這將不可避免地超出CPU。

請注意,ZMQ中有一些支持在單個線程中輪詢多個套接字 - 請參閱this answer。我認爲你可以在poller.poll(millis)中調整超時時間,這樣如果有很多傳入的消息,你的代碼只使用大量的CPU,否則就是空閒的。

您的其他選擇是使用ZMQ事件循環以異步方式使用回調來響應傳入消息。查看此主題的PyZMQ documentation,從下面的「回聲」的例子適用:

# set up the socket, and a stream wrapped around the socket 
s = ctx.socket(zmq.REP) 
s.bind('tcp://localhost:12345') 
stream = ZMQStream(s) 

# Define a callback to handle incoming messages 
def echo(msg): 
    # in this case, just echo the message back again 
    stream.send_multipart(msg) 

# register the callback 
stream.on_recv(echo) 

# start the ioloop to start waiting for messages 
ioloop.IOLoop.instance().start() 
+0

感謝您的答覆,但你能否詳細說明「你的另一種選擇是使用ZMQ事件循環傳入的消息異步響應,使用回調。「? –

+0

沒問題 - 我已經添加了一個鏈接和一個例子。 – DNA

+0

嗯......我實際上正在建造一個燒瓶+龍捲風應用程序。並且爲了通過zmq將消息從應用程序傳遞到sockjs連接,我必須單獨運行zmq腳本。已經在查看您分享的鏈接。希望我能夠在龍捲風之上運行zmq腳本。我一定會讓你知道它是怎麼回事。謝謝您的幫助! –