Gunicorn y Websockets
Pregunta
Estoy tratando de obtener http://www.gelens.org/code/gevent-WebSocket / funcionando y sigue obteniendo el siguiente error.
socket_id=1 already closed.
result = self._run(*self.args, **self.kwargs)
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/gevent/pywsgi.py", line 571, in handle
handler.handle()
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/gevent/pywsgi.py", line 180, in handle
result = self.handle_one_request()
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/gevent/pywsgi.py", line 314, in handle_one_request
self.handle_one_response()
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/geventwebsocket/handler.py", line 26, in handle_one_response
return self._handle_websocket()
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/geventwebsocket/handler.py", line 50, in _handle_websocket
self.log_request()
File "/home/walt/virtualenv/ws/local/lib/python2.7/site-packages/gevent/pywsgi.py", line 394, in log_request
log.write(self.format_request() + '\n')
AttributeError: 'Logger' object has no attribute 'write'
Estoy ejecutando Python 2.7.2 en Mint Linux
Solución
Obtengo este mismo error con GEVENT-Websocket 0.3.4 y gevent 0.13.6 al ejecutar el ejemplo de gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" example:app
.
El problema proviene de un desajuste de las expectativas entre gevent y gunicorn.El módulo PyWSGI de GEVENT, espera un objeto registrador que implementa un método de generación de generación, como objetos de archivo, stdout, etc. Gunicorn, sin embargo, pasa en un objeto que tiene registrador Métodos (depuración, información, error, crítica, advertencia, etc.).
El código de problema en PyWSGI:
def log_request(self):
log = self.server.log
if log:
log.write(self.format_request() + '\n')
Para solucionar esto para mí, pirateé las líneas en un tenedor de gevent y las cambié a lo siguiente:
def log_request(self):
log = self.server.log
if log:
if hasattr(log, "info"):
log.info(self.format_request() + '\n')
else:
log.write(self.format_request() + '\n')
Otros consejos
Se utiliza el código de BKAD y se agrega al archivo principal principal de la aplicación
def log_request(self):
log = self.server.log
if log:
if hasattr(log, "info"):
log.info(self.format_request() + '\n')
else:
log.write(self.format_request() + '\n')
import gevent
gevent.pywsgi.WSGIHandler.log_request = log_request
a Heder para que no tenga que modificar las bibliotecas de terceros.
Utilice las últimas versiones de GEVENT y GEVENT-WebSocket en PYPI.