serve:在server端使用,等待客户端的连接。如果连接成功,返回一个websocket。
connect: 在client端使用,用于建立连接。
send:发送数据
recv:接收数据
close:关闭连接
#!/usr/bin/python3
# 主要功能:创建1个基本的websocket server, 符合asyncio 开发要求
import asyncio
import websockets
from datetime import datetime
async def handler(websocket):
data = await websocket.recv()
reply = f"Data received as \"{data}\". time: {datetime.now()}"
print(reply)
await websocket.send(reply)
print("Send reply")
async def main():
async with websockets.serve(handler, "localhost", 9999):
await asyncio.Future() # run forever
if __name__ == "__main__":
asyncio.run(main())
import asyncio
import websockets
import time
async def ws_client(url):
for i in range(1, 40):
async with websockets.connect(url) as websocket:
await websocket.send("Hello, I am PyPy.")
response = await websocket.recv()
print(response)
time.sleep(1)
asyncio.run(ws_client('ws://localhost:9999'))
import asyncio
import websockets
IP_ADDR = "127.0.0.1"
IP_PORT = "9090"
# 握手,通过接收Hi,发送"success"来进行双方的握手。
async def serverHands(websocket):
while True:
recv_text = await websocket.recv()
print("recv_text=" + recv_text)
if recv_text == "Hi":
print("connected success")
await websocket.send("success")
return True
else:
await websocket.send("connected fail")
# 接收从客户端发来的消息并处理,再返给客户端success
async def serverRecv(websocket):
while True:
recv_text = await websocket.recv()
print("recv:", recv_text)
await websocket.send("success,get mess:"+ recv_text)
# 握手并且接收数据
async def serverRun(websocket, path):
print(path)
await serverHands(websocket)
await serverRecv(websocket)
# main function
if __name__ == '__main__':
print("======server======")
server = websockets.serve(serverRun, IP_ADDR, IP_PORT)
asyncio.get_event_loop().run_until_complete(server)
asyncio.get_event_loop().run_forever()
import asyncio
import websockets
IP_ADDR = "127.0.0.1"
IP_PORT = "9090"
async def clientHands(websocket):
while True:
# 通过发送hello握手
await websocket.send("Hi")
response_str = await websocket.recv()
# 接收"success"来进行双方的握手
if "success" in response_str:
print("握手成功")
return True
# 向服务器端发送消息
async def clientSend(websocket):
while True:
input_text = input("input text: ")
if input_text == "exit":
print(f'"exit", bye!')
await websocket.close(reason="exit")
return False
await websocket.send(input_text)
recv_text = await websocket.recv()
print(f"{recv_text}")
# 进行websocket连接
async def clientRun():
ipaddress = IP_ADDR + ":" + IP_PORT
async with websockets.connect("ws://" + ipaddress) as websocket:
await clientHands(websocket)
await clientSend(websocket)
# main function
if __name__ == '__main__':
print("======client======")
asyncio.get_event_loop().run_until_complete(clientRun())
# -*- coding:utf8 -*-
import json
import socket
import asyncio
import logging
import websockets
import multiprocessing
IP = '127.0.0.1'
PORT_CHAT = 9090
USERS ={}
#提供聊天的后台
async def ServerWs(websocket,path):
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
filename="chat.log",
level=logging.INFO)
# 握手
await websocket.send(json.dumps({"type": "handshake"}))
async for message in websocket:
data = json.loads(message)
message = ''
# 用户发信息
if data["type"] == 'send':
name = '404'
for k, v in USERS.items():
if v == websocket:
name = k
data["from"] = name
if len(USERS) != 0: # asyncio.wait doesn't accept an empty list
message = json.dumps(
{"type": "user", "content": data["content"], "from": name})
# 用户注册
elif data["type"] == 'register':
try:
USERS[data["uuid"]] = websocket
if len(USERS) != 0: # asyncio.wait doesn't accept an empty list
message = json.dumps(
{"type": "login", "content": data["content"], "user_list": list(USERS.keys())})
except Exception as exp:
print(exp)
# 用户注销
elif data["type"] == 'unregister':
del USERS[data["uuid"]]
if len(USERS) != 0: # asyncio.wait doesn't accept an empty list
message = json.dumps(
{"type": "logout", "content": data["content"], "user_list": list(USERS.keys())})
#打印日志
logging.info(data)
# 群发
await asyncio.wait([user.send(message) for user in USERS.values()])
def server_run():
print("server")
start_server = websockets.serve(ServerWs, '0.0.0.0', PORT_CHAT)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
from multiprocessing import Process
multiprocessing.freeze_support()
server = Process(target=server_run, daemon=False)
server.start()
import asyncio
import websockets
import time
import json
import threading
# 功能模块
class OutputHandler():
async def run(self,message,send_ms,websocket):
# 用户发信息
await send_ms(message, websocket)
# 单发消息
# await send_ms(message, websocket)
# 群发消息
#await s('hi起来')
# 存储所有的客户端
Clients = {}
# 服务端
class WS_Server():
def __init__(self):
self.ip = "127.0.0.1"
self.port = 9090
# 回调函数(发消息给客户端)
async def callback_send(self, msg, websocket=None):
await self.sendMsg(msg, websocket)
# 发送消息
async def sendMsg(self, msg, websocket):
print('sendMsg:', msg)
# websocket不为空,单发,为空,群发消息
if websocket != None:
await websocket.send(msg)
else:
# 群发消息
await self.broadcastMsg(msg)
# 避免被卡线程
await asyncio.sleep(0.2)
# 群发消息
async def broadcastMsg(self, msg):
for user in Clients:
await user.send(msg)
# 针对不同的信息进行请求,可以考虑json文本
async def runCaseX(self,jsonMsg,websocket):
print('runCase')
op = OutputHandler()
# 参数:消息、方法、socket
await op.run(jsonMsg,self.callback_send,websocket)
# 连接一个客户端,起一个循环监听
async def echo(self,websocket, path):
# 添加到客户端列表
# Clients.append(websocket)
# 握手
await websocket.send(json.dumps({"type": "handshake"}))
# 循环监听
while True:
# 接受信息
try:
# 接受文本
recv_text = await websocket.recv()
message = "Get message: {}".format(recv_text)
# 返回客户端信息
await websocket.send(message)
# 转json
data = json.loads(recv_text)
# 用户发信息
if data["type"] == 'send':
name = '404'
for k, v in Clients.items():
if v == websocket:
name = k
data["from"] = name
if len(Clients) != 0: # asyncio.wait doesn't accept an empty list
message = json.dumps({"type": "send", "content": data["content"], "from": name})
await self.runCaseX(jsonMsg=message, websocket=websocket)
# 用户注册
elif data["type"] == 'register':
try:
Clients[data["uuid"]] = websocket
if len(Clients) != 0: # asyncio.wait doesn't accept an empty list
message = json.dumps({"type": "register", "content": data["content"], "user_list": list(Clients.keys())})
await self.runCaseX(jsonMsg=message, websocket=websocket)
except Exception as exp:
print(exp)
# 用户注销
elif data["type"] == 'unregister':
del Clients[data["uuid"]]
# 对message进行解析,跳进不同功能区
# await self.runCaseX(jsonMsg=data,websocket=websocket)
# 链接断开
except websockets.ConnectionClosed:
print("ConnectionClosed...", path)
# del Clients
break
# 无效状态
except websockets.InvalidState:
print("InvalidState...")
# del Clients
break
# 报错
except Exception as e:
print("ws连接报错",e)
# del Clients
break
# 启动服务器
async def runServer(self):
async with websockets.serve(self.echo, self.ip, self.port):
await asyncio.Future() # run forever
# 多协程模式,防止阻塞主线程无法做其他事情
def WebSocketServer(self):
asyncio.run(self.runServer())
# 多线程启动
def startServer(self):
# 多线程启动,否则会堵塞
thread = threading.Thread(target=self.WebSocketServer)
thread.start()
# thread.join()
if __name__=='__main__':
print("server")
s = WS_Server()
s.startServer()