2017-04-13 140 views
0

我正在使用Python 3.5編碼的websocket服務器。這是需要提供我的網站實時信息。Python龍捲風SSL websocket連接

我使用的「服務器」庫稱爲tornadoversion 4.5b2),它處理websocket連接和http請求。爲了向後兼容(如果瀏覽器還不支持websocket),我使用python庫sockjs-tornado(版本1.0.3),它也向websocket連接添加了一些附加功能。

現在我的問題是,如果我啓動服務器,我會在控制檯中發現很多龍捲風ssl錯誤。它不會崩潰,但是如果大約80個客戶端連接到websocket 3,則會經常發生錯誤。我使用加密連接並且它可以工作,但是如果發生其中一個錯誤,則某些客戶端將從websocket連接中被踢出。

Python腳本使用多個線程,服務器受cloudflare保護,這是一種中間人,並將每個請求重定向到服務器或用戶。

這些都是3個錯誤:

​ 
ERROR:tornado.general:Uncaught exception, closing connection. 
Traceback (most recent call last): 
    File "/home/website/python/tornado/iostream.py", line 523, in _handle_events 
    self._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 1398, in _handle_write 
    super(SSLIOStream, self)._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 847, in _handle_write 
    assert self._write_buffer_size >= 0 
AssertionError 
ERROR:tornado.application:Exception in callback None 
Traceback (most recent call last): 
    File "/home/website/python/tornado/ioloop.py", line 888, in start 
    handler_func(fd_obj, events) 
    File "/home/website/python/tornado/stack_context.py", line 277, in null_wrapper 
    return fn(*args, **kwargs) 
    File "/home/website/python/tornado/iostream.py", line 523, in _handle_events 
    self._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 1398, in _handle_write 
    super(SSLIOStream, self)._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 847, in _handle_write 
    assert self._write_buffer_size >= 0 
AssertionError 

此錯誤不會經常出現的第一個。

ERROR:tornado.application:Uncaught exception GET /sockjs/398/ssputw1s/websocket 
HTTPServerRequest(protocol='https', host='****.com:8443', method='GET', uri='/sockjs/398/ssputw1s/websocket', version='HTTP/1.1', remote_ip='****', headers={'Accept-Encoding': 'gzip', 'Cf-Visitor': '{"scheme":"https"}', 'Sec-Websocket-Key': '****', 'Host': '****.com:8443', 'X-Forwarded-Proto': 'https', 'Cache-Control': 'no-cache', 'Sec-Websocket-Version': '13', 'Cf-Ipcountry': 'FR', 'X-Forwarded-For': '****', 'Sec-Websocket-Extensions': 'x-webkit-deflate-frame', 'Origin': 'https://****.com', 'Cf-Connecting-Ip': '****', 'Cookie': '****', 'Upgrade': 'websocket', 'Cf-Ray': '34edb1a17c456908-CDG', 'User-Agent': '****', 'Connection': 'Upgrade', 'Pragma': 'no-cache'}) 
Traceback (most recent call last): 
    File "/home/website/python/tornado/web.py", line 1464, in _stack_context_handle_exception 
    raise_exc_info((type, value, traceback)) 
    File "<string>", line 4, in raise_exc_info 
    File "/home/website/python/tornado/stack_context.py", line 316, in wrapped 
    ret = fn(*args, **kwargs) 
    File "/home/website/python/tornado/websocket.py", line 865, in _on_masked_frame_data 
    self._on_frame_data(_websocket_mask(self._frame_mask, data)) 
    File "/home/website/python/tornado/websocket.py", line 910, in _on_frame_data 
    self._receive_frame() 
    File "/home/website/python/tornado/websocket.py", line 784, in _receive_frame 
    self.stream.read_bytes(2, self._on_frame_start) 
    File "/home/website/python/tornado/iostream.py", line 324, in read_bytes 
    self._try_inline_read() 
    File "/home/website/python/tornado/iostream.py", line 711, in _try_inline_read 
    pos = self._read_to_buffer_loop() 
    File "/home/website/python/tornado/iostream.py", line 625, in _read_to_buffer_loop 
    if self._read_to_buffer() == 0: 
    File "/home/website/python/tornado/iostream.py", line 738, in _read_to_buffer 
    chunk = self.read_from_fd() 
    File "/home/website/python/tornado/iostream.py", line 1487, in read_from_fd 
    chunk = self.socket.read(self.read_chunk_size) 
    File "/usr/lib64/python3.5/ssl.py", line 799, in read 
    return self._sslobj.read(len, buffer) 
    File "/usr/lib64/python3.5/ssl.py", line 585, in read 
    v = self._sslobj.read(len) 
ssl.SSLWantWriteError: The operation did not complete (write) (_ssl.c:2090) 

而且有時會出現這樣的錯誤:

ERROR:tornado.general:Uncaught exception, closing connection. 
Traceback (most recent call last): 
    File "/home/website/python/tornado/iostream.py", line 523, in _handle_events 
    self._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 1398, in _handle_write 
    super(SSLIOStream, self)._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 872, in _handle_write 
    del self._write_buffer[:self._write_buffer_pos] 
BufferError: Existing exports of data: object cannot be re-sized 
ERROR:tornado.application:Exception in callback None 
Traceback (most recent call last): 
    File "/home/website/python/tornado/ioloop.py", line 888, in start 
    handler_func(fd_obj, events) 
    File "/home/website/python/tornado/stack_context.py", line 277, in null_wrapper 
    return fn(*args, **kwargs) 
    File "/home/website/python/tornado/iostream.py", line 523, in _handle_events 
    self._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 1398, in _handle_write 
    super(SSLIOStream, self)._handle_write() 
    File "/home/website/python/tornado/iostream.py", line 872, in _handle_write 
    del self._write_buffer[:self._write_buffer_pos] 
BufferError: Existing exports of data: object cannot be re-sized 

回答

0

這看起來像是在Tornado 4.5b2中的一個bug,它正在this issue中討論。尋找它在4.5b3或4.5 final中得到修復,同時你可以回到4.4版本。

+1

實際上,既然你說你正在使用多個線程,這看起來可能是錯誤地使用線程的結果。你只能**從'IOLoop'線程調用'WebSocketHandler'的方法;你不能從任何其他線程寫入套接字。 –

0

看起來像在圖書館中的錯誤 - 即競爭條件,導致多個實體使用相同的寫緩存在同一時間。

  • 一號錯誤 - _write_buffer_size下溢 - 另一個實體從中讀取時不恰當
  • 第三錯誤 - buffer in use時,它不應該是

抓住它,你需要跟蹤所有操作使用_write_buffer s並更改_write_buffer_size s和他們來自哪裏。