2017-05-22 88 views
0

我正在使用使用eventlet用Python編寫的一個服務器端的端點和用JavaScript編寫客戶端起始點的WebSockets:不能初始化併發WebSocket連接[eventlet,燒瓶,JavaScript的]

var ws = new WebSocket("ws://192.168.1.25:16081/some_url"); 
ws.onopen = function() 
{ 
    console.log("Transmitting " + data) 
    ws.send(data) 
}; 

ws.onmessage = function (evt) 
{ 
    console.log(evt.data) 
    // Do stuff with evt.data 
}; 

而且Python代碼:

import eventlet 
eventlet.sleep() 
from eventlet import wsgi 
from eventlet import websocket 
from eventlet.support import six 

@websocket.WebSocketWSGI 
def game_room(ws): 
    print(ws) 
    try: 
     while True: 
      time.sleep(1) 
      #Do stuff, some server-pushing 
    except Exception,e: 
     #Disconnect, do stuff 

def dispatch(environ, start_response): 
    """ This resolves to the web page or the websocket depending on 
    the path.""" 
    if environ['PATH_INFO'] == '/some_url': 
     return game_room(environ, start_response) 


if __name__ == "__main__": 
    # run an example app from the command line 
    listener = eventlet.listen(('0.0.0.0', 16081)) 
    wsgi.server(listener, dispatch, debug=True) 

爲簡潔起見,我截斷了一些代碼。如果我使用JavaScript進入頁面,它可以正常工作。運行wsgi服務器的控制檯報告已通過客戶端計算機的正確IP進行連接。問題是,如果我使用手機導航到同一頁面,套接字不會報告任何內容。如果我關閉機器上的選項卡並重新加載套接字服務器,我可以連接手機。不知何故,它似​​乎無法處理併發連接。

我不知道從哪裏開始。運行服務器時可以編輯一些選項嗎?

+0

此代碼將引發'NameError time is not defined'。 – temoto

回答

0

請將測試代碼降至最低,然後將其粘貼完整。不要隱藏部分代碼。截斷的代碼引導我們走向神祕猜測的道路。

而且我的第一個猜測是,你有這樣的:

import time 
import eventlet 

def fun(name): 
    while True: 
    print('{0} tick'.format(name)) 
    time.sleep(1) 

eventlet.spawn(fun, 'f1') 
eventlet.spawn(fun, 'f2') 
eventlet.sleep(10) 

只允許一個協同程序運行,因爲time.sleep是阻止一切。

請認識到使用兩種不同sleep函數的代碼味道。始終明白爲什麼,並有充分的理由去做。

  • 在這個綜合的例子中,你最好的選擇是使用eventlet.sleep
  • 在實際代碼sleep幾乎不用,你寧願對數據流的反應比流的時間。
  • 如果您必須調用以純Python編寫的阻塞函數,請使用eventlet.import_patched來獲得所需模塊的綠色版本,並且所有阻塞函數都修復爲協程。
  • 如果您必須調用阻塞在C模塊內部的函數,請使用eventlet.tpool.execute使其在單獨的OS線程中運行。

不幸的是,如果你截斷類似from eventlet.green import time,問題是不同的這個答案可能是完全不相干的。

+0

非常感謝。我截斷了代碼,因爲我認爲問題不會出現在我排除的邏輯中。我想阻止端點不斷查詢數據庫,所以我試着包含一個sleep()函數,每秒只調用一次(或任意的時間間隔)。什麼會是更好的方法? –

+0

如果您想將部分應用程序邏輯放入數據庫中,請使用您數據庫的通知機制。例如:https://www.chrisstucchio.com/blog/2013/postgres_external_triggers.html 如果您希望數據庫嚴格地作爲存儲,請讓一個應用程序實例通過您選擇的某個通信渠道通知其他人。例如:ZeroMQ PUB/SUB。 – temoto