2012-05-28 49 views
6

我學習使用HTML5 WebSockets的和的那部分,我用Python寫一個服務器,這樣我就可以知道他們是如何工作的細節問題。我前幾天創建了一個工作得很好的工作,但我想擴展它,以便支持多個端點,每個端點都是可以處理websocket客戶端的不同「服務」。現在,我的實現與產卵過程等工作(我使用多處理,而不是線程,因爲我讀了線程是不是真的多線程在CPython中,這就是我認爲我正在使用(默認安裝在Ubuntu 12.04 )),但我無法將收到的客戶端套接字發送到服務進程。發送Socket對象分叉正在運行的進程(multiprocessing.Queue)

這裏是我送他們(這個循環運行):

try: 
    #get a new client 
    conn, addr = server.accept() 
    print "Client connected from", addr 
    request = conn.recv(4096) 
    response, close, service = self.handshake(request) 
    conn.send(response) 
    if close: 
     print "Invalid request from", addr 
     conn.close() 
     continue 
    client = WebSockets.WebSocketClient(conn, addr) 
    service.clientConnQueue.put(client) 

「服務器」是監聽傳入連接的插座。握手方法負責驗證其請求並確定將客戶端放入哪個服務進程。 'response'是要發送的http響應,'close'如果發生錯誤則爲True,'service'是從multiprocessing.Queue繼承的類。 WebSocktes.WebSocketClient是我的發送和接收實現存儲的地方,它基本上作爲套接字的包裝函數。

「clientConnQueue」創建像這樣:

class Service(multiprocessing.Process): 
    """Base class for all services.""" 
    def __init__(self, manager): 
     multiprocessing.Process.__init__(self) 
     self.manager = manager 
     self.clientConnQueue = self.manager.Queue() 
     self.shutdownFlag = multiprocessing.Event() 

經理是一個multiprocessing.Manager()

我得到的錯誤,當我嘗試把客戶在clientConnQueue如下:

File "./WebSocketServer.py", line 183, in <module> 
main() 
File "./WebSocketServer.py", line 180, in main 
server.runServer() 
File "./WebSocketServer.py", line 67, in runServer 
service.clientConnQueue.put(client) 
File "<string>", line 2, in put 
File "/usr/lib/python2.7/multiprocessing/managers.py", line 758, in _callmethod 
conn.send((self._id, methodname, args, kwds)) 
TypeError: expected string or Unicode object, NoneType found 

然後我在接收端得到一個破損的管道錯誤。

我得到了我使用的是multiprocessing.Queue發送連接時同樣的錯誤,我認爲它改變成一個管理器創建隊列會解決這個問題。但是,它似乎做了完全相同的實現。

顯然,這是沒有辦法的辦法都應該送這樣的事情正在運行的進程,那麼什麼是正確的方法是發送非序列化對象的過程?

回答

1

將套接字傳遞給另一個進程並不是一件小事。看,例如,這個問題: Can I open a socket and pass it to another process in Linux

無論如何,OS進程或線程是不是你真正想要實現websocket服務器,因爲大內存開銷。使用非阻塞套接字查看smth ...例如龍捲風http://www.tornadoweb.org/documentation/websocket.html

+1

每個客戶端套接字不一定會獲得它自己的線程,但是每個服務都會得到自己的進程/線程,並且完全由服務決定如何處理套接字。這是一個很好的觀點,但是http服務器不必處理1000個同時存在的長連接的可能性,並且如果每個連接都有自己的線程,那麼這會帶來很多內存開銷。 –

0

您不能發送套接字派生的進程,而無需使用深UNIX魔法。你可以閱讀在Unix環境本書高級編程,如果你真的想看看它是如何在C.

做對於一個簡單的解決方案改爲使用線程和你的代碼可能只是工作。雖然線程在Python中並不完美,但它對於執行IO密集型的東西來說相當不錯。

分叉之前或者創建監聽套接字,並得到所有的子進程來聽(打電話accept)。操作系統將確保只有其中一個獲得連接。這是通常編寫preforking服務器的方式。

1

它已經存在了4年以上,但需要一點點的工作。

在multiprocessing.reduction中掛着膽量,一個例子的細節可以在this github gist中看到。

0

如果您在進程分叉之前創建套接字,那麼其文件描述符將由子進程繼承。