Tôi không thể tìm thấy điều này trong docs, nhưng làm thế nào tôi có nghĩa là để thoát ra khỏi asyncore.loop()
mà không sử dụng tín hiệu?Làm thế nào để thoát khỏi một điều phối viên asyncore từ một xử lý?
Trả lời
Nhanh chóng giải quyết sau khi xem mã nguồn. Nhờ các tài liệu để liên kết trực tiếp với nguồn!
Có ngoại lệ ExitNow bạn chỉ có thể tăng từ ứng dụng, thoát khỏi vòng lặp.
Sử dụng ví dụ EchoHandler
từ tài liệu, tôi đã sửa đổi nó để thoát ngay lập tức khi nhận dữ liệu.
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(8192)
if data:
raise asyncore.ExitNow('Server is quitting!')
Ngoài ra, hãy nhớ rằng bạn có thể bắt được ExitNow
để ứng dụng của bạn không tăng nếu bạn đang sử dụng nội bộ. Đây là một số nguồn của tôi:
def run(config):
instance = LockServer(config)
try:
asyncore.loop()
except asyncore.ExitNow, e:
print e
Vòng asyncore cũng thoát khi không còn kết nối, vì vậy bạn có thể đóng kết nối. Nếu bạn có nhiều kết nối đang diễn ra thì bạn có thể sử dụng asyncore.close_all().
Cách tiếp cận khác là sử dụng thông số tính của cuộc gọi asyncore.loop. Sau đó, bạn có thể bọc asyncore.loop trong logic khác:
while(i_should_continue()):
asyncore.loop(count=1)
Điều này sẽ không dừng ngay lập tức kết nối mở hoặc hết thời gian chờ. Nhưng điều này có lẽ là một điều tốt? Tôi đang sử dụng điều này khi tôi bắt đầu một máy chủ nghe.
Hãy thử điều này:
Một lớp học cho các máy chủ (mở rộng asyncore.dispatcher):
class Server(asyncore.dispatcher):
def __init__(self, port):
asyncore.dispatcher.__init__(self)
self.host = socket.gethostname()
self.port = port
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((self.host, self.port))
self.listen(5)
print "[Server] Listening on {h}:{p}".format(h=self.host, p=self.port)
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print "[ServerSocket] We got a connection from {a}".format(a=addr)
SocketHandler(sock)
Một lớp học cho các chủ đề ai sẽ là người để quản lý máy chủ (kéo dài Thread) ... kiểm tra method run(), có nơi chúng ta gọi là asyncore.loop():
class ServerThread(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.server = Server(port)
def run(self):
asyncore.loop()
def stop(self):
self.server.close()
self.join()
Bây giờ để khởi động server:
# This is the communication server, it is going to listen for incoming connections, it has its own thread:
s = ServerThread(PORT)
s.start() # Here we start the thread for the server
print "Server is ready..."
print "Is ServerThread alive? {t}".format(t=str(s.is_alive()))
raw_input("Press any key to stop de server now...")
print "Trying to stop ServerThread..."
s.stop()
print "The server will die in 30 seconds..."
Bạn sẽ lưu ý rằng máy chủ không chết ngay lập tức ... nhưng nó chết một cách duyên dáng
Đây có lẽ là giải pháp thích hợp nếu bạn muốn dừng vòng lặp "ngoài vòng lặp". Các giải pháp khác ở trên là để dừng vòng lặp trong vòng lặp. –