Estoy aprendiendo a usar HTML5 WebSockets y como parte de eso estoy escribiendo un servidor en Python para que pueda conocer los detalles de cómo funcionan. Creé uno el otro día que funcionó bastante bien, pero quería expandirlo para que admitiera múltiples puntos finales, con cada punto final como un "servicio" diferente que puede manejar clientes de websocket.Enviar el objeto socket al proceso de ejecución bifurcado (multiprocesamiento.Queue)
Por el momento, mi aplicación trabaja con los procesos de desove y tal (estoy usando multiprocesamiento en lugar de enhebrado desde que leí que la rosca no es realmente multihilo en CPython y eso es lo que pienso que estoy usando (instalación por defecto en Ubuntu 12.04)), pero tengo problemas para enviar los sockets de clientes recibidos a los procesos de servicio.
Así es como los mando (esto se ejecuta en un bucle):
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)
'servidor' es un socket de escucha para las conexiones entrantes. El método handshake se encarga de validar su solicitud y determinar en qué proceso de servicio colocar al cliente. 'response' es la respuesta http para enviar, 'close' es True si hubo un error, y 'service' es una clase que hereda de multiprocessing.Queue. WebSocktes.WebSocketClient es donde se almacena la implementación de envío y recepción y básicamente funciona como un contenedor para un socket.
'clientConnQueue' se crea de este modo:
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()
director es un multiprocessing.Manager()
El error que consigo cuando intento de colocar un cliente en el clientConnQueue es el siguiente:
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
Luego recibo un error de tubería rota en el lado de recepción.
Recibí el mismo error cuando estaba usando un multiprocesamiento.Queue enviar la conexión y pensé que cambiarlo a una cola creada por un administrador solucionaría el problema. Sin embargo, parece hacer la misma implementación exacta.
Claramente esta no es la forma en que se supone que se debe enviar algo como esto a un proceso en ejecución, entonces, ¿cuál es la forma correcta de enviar objetos no serializables a un proceso?
Cada socket de cliente no necesariamente obtendrá su propio hilo, pero cada servicio obtiene su propio proceso/hilo y le deja al servicio exactamente qué hacer con el socket. Sin embargo, ese es un buen punto ... los servidores http no tienen que lidiar con la posibilidad de 1000 conexiones simultáneas de larga duración y eso implica una gran cantidad de memoria si cada conexión tiene su propio hilo. –