赞
踩
# -*- coding:utf-8 -*- # @FileName :demo.py # @Time :2021/7/26 18:09 # @Author :Ranger # @Info : import uvicorn from fastapi import FastAPI from starlette.websockets import WebSocket, WebSocketDisconnect from fastapi.responses import HTMLResponse from typing import List from datetime import datetime websocket_ip = 'localhost' app = FastAPI() class ChatText: def __init__(self, chat_src, chat_text): """ :param chat_src: 0-客户端 1-服务端 :param chat_text: """ self.chat_src = chat_src self.chat_text = chat_text self.timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') class CustomerChatUtils: def __init__(self, client_id): self.client_id = client_id self.server_websocket = None self.customer_websocket = None self.active = False self.timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.chat_message_list: List[ChatText] = [] class CustomerServiceUtils: def __init__(self): self.client_ids = [] self.customer_active_connections: List[WebSocket] = [] # 客户端活跃链接 self.server_active_connections: List[WebSocket] = [] # 服务端活跃链接 self.customer_chat_obj: List[CustomerChatUtils] = [] async def customer_connect(self, websocket: WebSocket): await websocket.accept() self.customer_active_connections.append(websocket) async def server_connect(self, websocket: WebSocket): await websocket.accept() self.server_active_connections.append(websocket) def customer_disconnect(self, websocket: WebSocket): self.customer_active_connections.remove(websocket) for item in self.customer_chat_obj: if item.customer_websocket == websocket: item.customer_websocket = None item.active = False def server_disconnect(self, websocket: WebSocket): self.server_active_connections.remove(websocket) for item in self.customer_chat_obj: if item.server_websocket == websocket: item.server_websocket = None def get_customer_chat_obj(self, client_id) -> CustomerChatUtils: """获取历史聊天记录 :param client_id: :return: """ current_chat_message = None for chat_message in self.customer_chat_obj: if chat_message.client_id == client_id: current_chat_message = chat_message break if current_chat_message is None: current_chat_message = CustomerChatUtils(client_id) self.customer_chat_obj.append(current_chat_message) return current_chat_message customer_service_utils = CustomerServiceUtils() @app.get("/chat/client/{client_id}") async def chat_client(client_id: int): html_content = f""" <!DOCTYPE html> <html> <head> <title>客户端</title> </head> <body> <h1>客户端 Chat</h1> <form action="" οnsubmit="sendMessage(event)"> <input type="text" id="messageText" autocomplete="off"/> <button>Send</button> </form> <ul id='messages'> </ul> <script> var ws = new WebSocket("ws://{websocket_ip}:8000/ws/customer/{client_id}"); """ + """ ws.onmessage = function(event) { var messages = document.getElementById('messages') var message = document.createElement('li') var content = document.createTextNode(event.data) message.appendChild(content) messages.appendChild(message) }; function sendMessage(event) { var input = document.getElementById("messageText") ws.send(input.value) input.value = '' event.preventDefault() } </script> </body> </html> """ return HTMLResponse(html_content) @app.get("/chat/server/{client_id}") async def chat_server(client_id: int): html_content = f""" <!DOCTYPE html> <html> <head> <title>服务端</title> </head> <body> <h1>服务端 Chat</h1> <form action="" οnsubmit="sendMessage(event)"> <input type="text" id="messageText" autocomplete="off"/> <button>Send</button> </form> <ul id='messages'> </ul> <script> var ws = new WebSocket("ws://{websocket_ip}:8000/ws/server/{client_id}"); """ + """ ws.onmessage = function(event) { var messages = document.getElementById('messages') var message = document.createElement('li') var content = document.createTextNode(event.data) message.appendChild(content) messages.appendChild(message) }; function sendMessage(event) { var input = document.getElementById("messageText") ws.send(input.value) input.value = '' event.preventDefault() } </script> </body> </html> """ return HTMLResponse(html_content) @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() await websocket.send_text(f"Message text was: {data}") @app.websocket("/ws/customer/{client_id}") async def websocket_endpoint_customer(websocket: WebSocket, client_id: int): await customer_service_utils.customer_connect(websocket) try: customer_chat_obj = customer_service_utils.get_customer_chat_obj(client_id) customer_chat_obj.active = True customer_chat_obj.customer_websocket = websocket for chat_message in customer_chat_obj.chat_message_list: if chat_message.chat_src == 0: await websocket.send_text(f'我 {chat_message.timestamp}: {chat_message.chat_text}') else: await websocket.send_text(f'客服 {chat_message.timestamp}: {chat_message.chat_text}') while True: data = await websocket.receive_text() print(f'客户端发送消息:{data}') _chat_text = ChatText(0, data) customer_chat_obj.chat_message_list.append(_chat_text) await websocket.send_text(f"我 {_chat_text.timestamp}: {data}") # 发送给服务端 if customer_chat_obj.server_websocket is not None: await customer_chat_obj.server_websocket.send_text(f"客户{client_id}-{_chat_text.timestamp}: {data}") except WebSocketDisconnect: customer_service_utils.customer_disconnect(websocket) @app.websocket("/ws/server/{client_id}") async def websocket_endpoint_server(websocket: WebSocket, client_id: int): await customer_service_utils.server_connect(websocket) try: customer_chat_obj = customer_service_utils.get_customer_chat_obj(client_id) if customer_chat_obj.active: customer_chat_obj.server_websocket = websocket for chat_message in customer_chat_obj.chat_message_list: if chat_message.chat_src == 0: await websocket.send_text(f'客户{client_id}-{chat_message.timestamp}: {chat_message.chat_text}') else: await websocket.send_text(f'我 {chat_message.timestamp}: {chat_message.chat_text}') while True: data = await websocket.receive_text() print(f'服务端发送消息:{data}') _chat_text = ChatText(1, data) customer_chat_obj.chat_message_list.append(_chat_text) await websocket.send_text(f"我 {_chat_text.timestamp}: {data}") if customer_chat_obj.customer_websocket is not None: await customer_chat_obj.customer_websocket.send_text( f"客服:{_chat_text.timestamp}: {data}") else: await websocket.send_text("非法的client_id") except WebSocketDisconnect: customer_service_utils.server_disconnect(websocket) uvicorn.run(app, host="0.0.0.0", port=8000)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。