代码拉取完成,页面将自动刷新
# coding=utf8
import gevent
from gevent.queue import Queue
from gevent.server import StreamServer
users = {} # 维护所有用户的接受消息对列
def cache(msg):
'''
1) 当一个用户新登陆时,才触发handler:此时是把最后一个登陆者的登陆信息放到其他已经登陆用户的消息队列中;
2)当一个用户发消息时, 不触发handler:此时是把该消息放到所有已经登陆用户的消息队列中,包括本人
'''
msg += '\n'
for v in users.values():
v.put(msg)
def reader(username, f):
"""
读消息,并放到所有用户的接收消息队列中。
登陆时,f没有值; 发消息时才有
"""
for l in f:
msg = '%s> %s' % (username, l.strip())
msg += '\n'
for v in users.values():
v.put(msg)
def writer(q, sock):
"""广播消息"""
while True:
msg = q.get()
print 'id sock: ', id(sock)
sock.sendall(msg)
def read_name(f, sock):
while True:
sock.sendall('Please enter your name: ')
name = f.readline().strip()
if name:
if name in users:
sock.sendall('That username is already taken.\n')
else:
return name
def handle(sock, client_addr):
# 具体信息在f中
f = sock.makefile()
# 只是获得当前哪个用户登陆了,或者哪个用户发的消息
name = read_name(f, sock)
# 把该用户的登陆信息放到别的用户的队列中,或者把改用户发的消息放到其他用户的消息队列
cache('## %s joined from %s.' % (name, client_addr[0]))
q = Queue()
users[name] = q
print 'user %s: ' % name, len(users[name])
# ---------------------------------------------------------#
# ------ 以上代码只会在新用户第一次连接server时执行---------------#
# ------ 所以q并不是上面的空队列,而是reader填充后的队列!!!------#
# ---------------------------------------------------------#
try:
r = gevent.spawn(reader, name, f)
w = gevent.spawn(writer, q, sock)
gevent.joinall([r, w])
print 'not show'
finally:
del (users[name])
cache('## %s left the chat.' % name)
if __name__ == '__main__':
import sys
try:
myip = sys.argv[1]
except IndexError:
myip = '0.0.0.0'
print 'To join, telnet %s 8003' % myip
s = StreamServer((myip, 8003), handle)
s.serve_forever()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。