import aiohttp
from aiohttp import web
personal_pool = {}
room_pool = {}
# 发送消息
async def broadcast_msg(user_name,msg,room=""):
# 如果不是聊天室,则单独返回
if not room:
ws = personal_pool[user_name]
await ws.send_str("服务器接收到了您的信息")
# 如果是聊天室则广播
else:
users = room_pool[room]
for name,ws in users.items():
if user_name != name :
await ws.send_str(user_name + " -> " + msg)
async def delete_ws():
pass
async def hello(request):
return web.Response(text="Hello, world")
async def websocket_handler(request):
# ws对象
ws = web.WebSocketResponse()
# 等待用户连接
await ws.prepare(request)
room = request.query.get('room')
user_name = request.query.get('user_name')
print("room",room)
print("user_name",user_name)
# -------------------------------------------------------------------
# 这一大段,都是存储ws的逻辑
# 如果是聊天室,则存入 room_pool , { "room1":{"张三":ws1,"李四":ws2}}
# 如果不是聊天室,则是和服务器的私人交互,personal_pool, {"张三":ws1,"李四":ws2}
# 退出的时候,要删除对应的ws,这里没写
if room:
if room in room_pool:
room_pool[room][user_name] = ws
else:
room_pool[room] = {user_name:ws}
else:
if user_name in personal_pool:
await ws.send_str("名字已有")
print('websocket connection closed')
return ws
else:
personal_pool[user_name] = ws
# -------------------------------------------------------------------
# 阻塞住,等待用户的消息
# websocket 可以理解 http请求,但是连接一直不断开
# 然后服务器不断的返回一些数据
# 直到最后return ws ,相当于http的response,然后就断开连接了
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
if msg.data == 'close':
await ws.close()
else:
await broadcast_msg(user_name,msg.data,room)
# await ws.send_str(msg.data + '->/answer')
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' % ws.exception())
# 断开连接了
print('websocket connection closed')
return ws
app = web.Application()
app.add_routes([web.get('/', hello)])
app.add_routes([web.get('/ws', websocket_handler)])
web.run_app(app)
# 测试工具网站 http://www.websocket-test.com/
# ws://127.0.0.1:8080/ws?room=kuaile&user_name=sun
# ws://127.0.0.1:8080/ws?room=kuaile&user_name=tim
# ws://127.0.0.1:8080/ws?user_name=tim
# 如果想使用websocket 做推送的话,代码显然不能满足条件
# 我们都知道websocket 是双向通信,但是这个简单的聊天室,本质上也是接收到客户端信息,然后做出响应,并没有感觉到服务端是主动的。
# 使用ws 就可以主动的给客户端发送消息,我们可以单独起一个线程/线程,再利用队列等技术消息传递的特性,来主动给客户端发送消息。
# 比如本文要给全服务用户推送消息,就可以写单独起一个线程 thread,然后利用queue推送
# 伪代码
"""
# 线程的逻辑
q = queue()
while True:
# 这里会阻塞,我们还可以用程序往这个q中放入推送的消息
msg = q.get()
# 获得推送的消息后发送给全服,我们把全部的ws都存在两个pool中了,只需要遍历就习惯
for ws in personal_pool:
# 发送
await ws.send_str(msg)
"""
aiohttp websocket 简单使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.