2012-04-23 18 views
5

Estoy tratando de adaptar mi cerebro a los conceptos que gevent emplea. Aquí hay un ejemplo del repositorio de código gevent. Es un servidor de eco simple.gevent StreamServer.start() no parece hacer lo que espero

from gevent.server import StreamServer 

# this handler will be run for each incoming connection in a dedicated greenlet 
def echo(socket, address): 
    print ('New connection from %s:%s' % address) 
    socket.sendall('Welcome to the echo server! Type quit to exit.\r\n') 
    # using a makefile because we want to use readline() 
    fileobj = socket.makefile() 
    while True: 
     line = fileobj.readline() 
     if not line: 
      print ("client disconnected") 
      break 
     if line.strip().lower() == 'quit': 
      print ("client quit") 
      break 
     fileobj.write(line) 
     fileobj.flush() 
     print ("echoed %r" % line) 


if __name__ == '__main__': 
    # to make the server use SSL, pass certfile and keyfile arguments to the constructor 
    server = StreamServer(('0.0.0.0', 6000), echo) 
    # to start the server asynchronously, use its start() method; 
    # we use blocking serve_forever() here because we have no other jobs 
    print ('Starting echo server on port 6000') 
    server.serve_forever() 

Parece bastante sencillo y funciona. Sin embargo, como dice en el comentario que serve_forever() es una función de bloqueo. Si cambio la última línea a server.start(), el programa se detendrá después de ejecutar cada línea una vez. Estoy haciendo algo mal, pero la documentación no es muy útil.

En la sección de documentación implementing servers with gevent, se dice que el uso de start() debe generar una nueva greenlet para cada nueva conexión cuando se utiliza el siguiente código:

def handle(socket, address): 
    print 'new connection!' 

server = StreamServer(('127.0.0.1', 1234), handle) # creates a new server 
server.start() # start accepting new connections 

Y luego a la derecha después de que se dice que The server_forever() method calls start() and then waits until interrupted or until the server is stopped. ¿Cómo se supone que voy a ejecutar el servidor usando start() para que realmente permanezca vivo para capturar la primera conexión?

también:

  1. ¿Cuál es la diferencia entre start() y serve_forever()?
  2. ¿En qué contextos debo elegir uno sobre el otro?
  3. ¿Son necesarias las llamadas a gevent.spawn() y gevent.joinall() cuando se utiliza el primer método, pero de alguna manera tan obvio que se han quedado fuera de la documentación de StreamServer?

Respuesta

9
  1. inicio() es una función asíncrona que pone a un servidor en un modo de escucha. Sin embargo, no impide que su programa salga, lo que es su responsabilidad.
  2. en casos simples puede usar serve_forever(). start() se vuelve útil cuando necesita iniciar varios servidores o hacer otra cosa además de iniciar un servidor.
  3. no, gevent.spawn() y gevent.joinall() no tienen nada que ver con los servidores.

Con gevent 1.0 en realidad es mejor usar gevent.wait() que bloquea hasta que no haya más conexiones activas/greenlets/listeners/watchers.

He aquí un ejemplo: https://github.com/gevent/gevent/blob/master/examples/portforwarder.py

+0

Gracias, este sacó. Gracias por escribir gevent :) – msvalkon

+0

fyi este enlace parece muerto – scape

+0

@scape gracias, actualizado. –

Cuestiones relacionadas