Tôi muốn viết một máy chủ mà khách hàng có thể kết nối và nhận các cập nhật định kỳ mà không cần phải thăm dò ý kiến. Vấn đề tôi đã gặp phải với asyncore là nếu bạn không trả về true khi dispatcher.writable() được gọi, bạn phải đợi cho đến sau khi asyncore.loop đã hết thời gian (mặc định là 30s).Asyncore của Python định kỳ gửi dữ liệu bằng cách sử dụng thời gian chờ biến đổi. Có cách nào tốt hơn?
Hai cách tôi đã cố gắng giải quyết vấn đề này là 1) giảm thời gian chờ xuống giá trị thấp hoặc 2) kết nối truy vấn khi cập nhật tiếp theo và tạo ra giá trị thời gian chờ thích hợp. Tuy nhiên, nếu bạn tham khảo 'Chọn Luật' trong 'man 2 select_tut', nó nói, "Bạn nên luôn luôn cố gắng sử dụng select() mà không có thời gian chờ."
Có cách nào tốt hơn để thực hiện việc này không? Xoắn có thể? Tôi muốn thử và tránh các chủ đề phụ. Tôi sẽ bao gồm thời gian chờ dụ biến ở đây:
#!/usr/bin/python
import time
import socket
import asyncore
# in seconds
UPDATE_PERIOD = 4.0
class Channel(asyncore.dispatcher):
def __init__(self, sock, sck_map):
asyncore.dispatcher.__init__(self, sock=sock, map=sck_map)
self.last_update = 0.0 # should update immediately
self.send_buf = ''
self.recv_buf = ''
def writable(self):
return len(self.send_buf) > 0
def handle_write(self):
nbytes = self.send(self.send_buf)
self.send_buf = self.send_buf[nbytes:]
def handle_read(self):
print 'read'
print 'recv:', self.recv(4096)
def handle_close(self):
print 'close'
self.close()
# added for variable timeout
def update(self):
if time.time() >= self.next_update():
self.send_buf += 'hello %f\n'%(time.time())
self.last_update = time.time()
def next_update(self):
return self.last_update + UPDATE_PERIOD
class Server(asyncore.dispatcher):
def __init__(self, port, sck_map):
asyncore.dispatcher.__init__(self, map=sck_map)
self.port = port
self.sck_map = sck_map
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(("", port))
self.listen(16)
print "listening on port", self.port
def handle_accept(self):
(conn, addr) = self.accept()
Channel(sock=conn, sck_map=self.sck_map)
# added for variable timeout
def update(self):
pass
def next_update(self):
return None
sck_map = {}
server = Server(9090, sck_map)
while True:
next_update = time.time() + 30.0
for c in sck_map.values():
c.update() # <-- fill write buffers
n = c.next_update()
#print 'n:',n
if n is not None:
next_update = min(next_update, n)
_timeout = max(0.1, next_update - time.time())
asyncore.loop(timeout=_timeout, count=1, map=sck_map)
Nick: Đó là thay đổi nhỏ để làm cho chức năng hoạt động? Bạn có thể đặt mã? Cảm ơn –