2012-04-23 16 views
5

Próbuję zawrzeć mój mózg wokół koncepcji, które zatrudnia gevent. Oto przykład z repozytorium geventu. To prosty serwer echa.gevent StreamServer.start() wydaje się nie robić tego, co oczekuję

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() 

To wydaje się dość proste i działa. Jednak, jak mówi w komentarzu, że serve_forever() jest funkcją blokującą. Jeśli zmienię ostatnią linię na server.start(), program zatrzyma się po wykonaniu każdego wiersza jeden raz. Robię coś złego, ale dokumentacja nie jest bardzo pomocna.

W sekcji dokumentów implementing servers with gevent, to mówi, że za pomocą start() powinien zapoczątkować nową Greenlet dla każdego nowego połączenia przy użyciu następującego kodu:

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 

a następnie w prawo po to mówi, że The server_forever() method calls start() and then waits until interrupted or until the server is stopped. Jak mam uruchomić serwer przy użyciu start(), tak aby rzeczywiście pozostał przy życiu, aby złapać pierwsze połączenie?

również:

  1. Jaka jest różnica między start() i serve_forever()?
  2. W jakich sytuacjach powinienem wybrać jeden nad drugim?
  3. Czy podczas korzystania z pierwszej metody konieczne są połączenia z gevent.spawn() i gevent.joinall(), ale w jakiś sposób tak oczywiste, że zostały pominięte w dokumentacji serwera StreamServer?

Odpowiedz

9
  1. start() jest funkcją, która stawia asynchroniczny serwer w trybie odsłuchu. Nie przeszkadza to jednak wyjść z programu, co należy do obowiązków użytkownika.
  2. w prostych przypadkach można użyć serve_forever(). Funkcja start() staje się użyteczna, gdy musisz uruchomić wiele serwerów lub zrobić coś innego oprócz uruchamiania serwera.
  3. no, gevent.spawn() i gevent.joinall() nie mają nic wspólnego z serwerami.

Z gevent 1.0 najlepiej jest użyć funkcji gevent.wait(), która blokuje do momentu, gdy nie będzie już aktywnych połączeń/greenletów/słuchaczy/obserwatorów.

Oto przykład: https://github.com/gevent/gevent/blob/master/examples/portforwarder.py

+0

Dziękuję, to wyczyściło to. Dzięki za pisanie gevent :) – msvalkon

+0

fyi ten link wydaje się martwy – scape

+0

@scape dzięki, zaktualizowany. –

Powiązane problemy