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ż:
- Jaka jest różnica między
start()
iserve_forever()
? - W jakich sytuacjach powinienem wybrać jeden nad drugim?
- Czy podczas korzystania z pierwszej metody konieczne są połączenia z
gevent.spawn()
igevent.joinall()
, ale w jakiś sposób tak oczywiste, że zostały pominięte w dokumentacji serwera StreamServer?
Dziękuję, to wyczyściło to. Dzięki za pisanie gevent :) – msvalkon
fyi ten link wydaje się martwy – scape
@scape dzięki, zaktualizowany. –