|
@@ -8,45 +8,56 @@
|
|
|
* 使用基于协程的会话
|
|
|
* 使用 `run_async() <pywebio.session.run_async>` 启动后台协程
|
|
|
"""
|
|
|
+import asyncio
|
|
|
+
|
|
|
+from pywebio import start_server, run_async
|
|
|
from pywebio.input import *
|
|
|
from pywebio.output import *
|
|
|
-from pywebio import start_server, run_async
|
|
|
|
|
|
-import asyncio
|
|
|
+# 最大消息记录保存
|
|
|
+MAX_MESSAGES_CNT = 10 ** 4
|
|
|
|
|
|
chat_msgs = [] # 聊天记录 (name, msg)
|
|
|
-online_cnt = 0 # 在线人数
|
|
|
+online_users = set() # 在线用户
|
|
|
|
|
|
|
|
|
async def refresh_msg(my_name):
|
|
|
"""刷新聊天消息"""
|
|
|
+ global chat_msgs
|
|
|
last_idx = len(chat_msgs)
|
|
|
while True:
|
|
|
await asyncio.sleep(0.5)
|
|
|
for m in chat_msgs[last_idx:]:
|
|
|
if m[0] != my_name: # 仅刷新其他人的新信息
|
|
|
put_markdown('`%s`: %s' % m)
|
|
|
+
|
|
|
+ # 清理聊天记录
|
|
|
+ if len(chat_msgs) > MAX_MESSAGES_CNT:
|
|
|
+ chat_msgs = chat_msgs[len(chat_msgs) // 2:]
|
|
|
+
|
|
|
last_idx = len(chat_msgs)
|
|
|
|
|
|
|
|
|
async def main():
|
|
|
- global online_cnt
|
|
|
+ global chat_msgs
|
|
|
|
|
|
set_output_fixed_height(True)
|
|
|
set_title("PyWebIO Chat Room")
|
|
|
+ put_markdown("""欢迎来到聊天室,你可以和当前所有在线的人聊天\n
|
|
|
+ 本应用使用不到80行代码实现,源代码[链接](https://github.com/wang0618/PyWebIO/blob/master/demos/chat_room.py)""", lstrip=True)
|
|
|
|
|
|
- put_text("欢迎来到聊天室,你可以和当前所有在线的人聊天")
|
|
|
- nickname = await input("请输入你的昵称", required=True, valid_func=lambda n: '无法使用该昵称' if n == '📢' else None)
|
|
|
+ nickname = await input("请输入你的昵称", required=True,
|
|
|
+ valid_func=lambda n: '昵称已被使用' if n in online_users or n == '📢' else None)
|
|
|
|
|
|
- online_cnt += 1
|
|
|
- chat_msgs.append(('📢', '`%s`加入聊天室. 当前在线人数 %s' % (nickname, online_cnt)))
|
|
|
- put_markdown('`📢`: `%s`加入聊天室. 当前在线人数 %s' % (nickname, online_cnt))
|
|
|
+ online_users.add(nickname)
|
|
|
+ chat_msgs.append(('📢', '`%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users))))
|
|
|
+ put_markdown('`📢`: `%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users)))
|
|
|
|
|
|
refresh_task = run_async(refresh_msg(nickname))
|
|
|
|
|
|
while True:
|
|
|
data = await input_group('发送消息', [
|
|
|
- input(name='msg', help_text='消息内容支持Markdown 语法'),
|
|
|
+ input(name='msg', help_text='消息内容支持Markdown 语法', required=True),
|
|
|
actions(name='cmd', buttons=['发送', '退出'])
|
|
|
])
|
|
|
if data['cmd'] == '退出':
|
|
@@ -55,11 +66,14 @@ async def main():
|
|
|
put_markdown('`%s`: %s' % (nickname, data['msg']))
|
|
|
chat_msgs.append((nickname, data['msg']))
|
|
|
|
|
|
- online_cnt -= 1
|
|
|
+ online_users.remove(nickname)
|
|
|
refresh_task.close()
|
|
|
- chat_msgs.append(('📢', '`%s`退出聊天室. 当前在线人数 %s' % (nickname, online_cnt)))
|
|
|
+ chat_msgs.append(('📢', '`%s`退出聊天室. 当前在线人数 %s' % (nickname, len(online_users))))
|
|
|
put_text("你已经退出聊天室")
|
|
|
|
|
|
+ if not online_users:
|
|
|
+ chat_msgs = []
|
|
|
+
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
start_server(main, debug=True, port=8080)
|