模拟websocket服务器向客户端发送数据的python代码

部署运行你感兴趣的模型镜像
import asyncio
import websockets
import sys
from datetime import datetime

# 全局客户端连接池
connected = set()


async def broadcast(message: str):
    """广播消息到所有连接的客户端"""
    if connected:  # 仅当有客户端连接时执行
        print(f"[BROADCAST] {message}")
        # 遍历副本防止迭代时集合被修改
        for ws in list(connected):
            try:
                await ws.send(message)
            except websockets.exceptions.ConnectionClosed:
                # 移除断开的客户端
                connected.remove(ws)


async def terminal_input_handler():
    """终端输入监听协程"""
    while True:
        # 阻塞等待终端输入(按回车发送)
        user_input = await asyncio.to_thread(sys.stdin.readline)
        if user_input.strip().lower() == 'exit':
            print("[SERVER] 接收到退出指令,正在关闭...")
            break

        # 格式化消息(带时间戳)
        timestamp = datetime.now().strftime("%H:%M:%S")
        message = f"{user_input.strip()}"

        # 执行广播
        await broadcast(message)


async def handle_client(websocket):
    """处理客户端连接"""
    print(f"[CONNECTION] 新客户端接入: {websocket.remote_address}")
    connected.add(websocket)

    try:
        # 保持连接(客户端不主动发消息时,仅接收广播)
        await websocket.wait_closed()
    finally:
        connected.remove(websocket)
        print(f"[DISCONNECTION] 客户端断开: {websocket.remote_address}")


async def main():
    # 启动 WebSocket 服务器(监听 8765 端口)
    async with websockets.serve(handle_client, "0.0.0.0", 8765):
        # 启动终端输入监听
        input_task = asyncio.create_task(terminal_input_handler())

        # 等待任务完成(输入 exit 或 Ctrl+C 退出)
        try:
            await input_task
        except KeyboardInterrupt:
            print("\n[SERVER] 接收到中断信号,正在关闭...")


if __name__ == "__main__":
    print("=== WebSocket 广播服务器启动 ===")
    print("终端输入消息后按回车即可广播,输入 'exit' 退出")
    print("客户端连接地址: ws://你的IP:8765")

    asyncio.run(main())

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think> 我们之前已经构建了一个较为完整的WebSocket客户端框架。根据用户当前的查询,他想要了解如何使用Python模拟客户端服务器建立WebSocket连接。实际上,我们之前的框架已经实现了这个功能。但是,为了更直接地回答用户的问题,我们可以提供一个更简洁的示例,并解释关键步骤。 ### 使用Python模拟WebSocket客户端的基本步骤 1. **安装必要的库**:使用`websocket-client`库(注意不是`websockets`,后者通常用于服务器端)。 2. **建立连接**:通过`create_connection`函数或使用`WebSocketApp`类(后者支持事件回调)。 3. **发送消息**:使用`send`方法。 4. **接收消息**:使用`recv`方法(同步)或通过回调函数(异步)。 5. **关闭连接**:使用`close`方法。 ### 简单示例 ```python from websocket import create_connection # 1. 建立连接 ws = create_connection("ws://echo.websocket.org/") # 2. 发送消息 message = "Hello, World" print(f"发送: {message}") ws.send(message) # 3. 接收响应 result = ws.recv() print(f"收到: {result}") # 4. 关闭连接 ws.close() ``` ### 使用事件驱动方式(推荐) ```python import websocket import threading import time def on_message(ws, message): print(f"收到消息: {message}") def on_error(ws, error): print(f"错误: {error}") def on_close(ws, close_status_code, close_msg): print("### 连接关闭 ###") def on_open(ws): def run(*args): for i in range(3): time.sleep(1) message = f"消息 {i+1}" ws.send(message) print(f"发送: {message}") time.sleep(1) ws.close() threading.Thread(target=run).start() if __name__ == "__main__": websocket.enableTrace(True) # 开启详细日志 ws = websocket.WebSocketApp("ws://echo.websocket.org/", on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close) ws.run_forever() ``` ### 关键点说明 1. **连接地址**:以`ws://`(非加密)或`wss://`(加密)开头。 2. **事件回调**: - `on_open`:连接建立时触发,可在此发送初始消息。 - `on_message`:收到消息时触发。 - `on_error`:发生错误时触发。 - `on_close`:连接关闭时触发。 3. **多线程处理**:在`on_open`中启动新线程发送消息,避免阻塞主循环。 ### 处理多个响应 如果需要监听多个响应通道(例如订阅多个主题),可以使用以下方法: 1. **在消息处理器中根据内容分发**:解析消息,根据消息中的主题字段调用不同的处理函数。 2. **使用STOMP协议**:WebSocket之上使用STOMP协议(一种简单的消息协议),可以方便地实现订阅/发布模式。 ### 示例:处理多个主题 ```python def on_message(ws, message): try: data = json.loads(message) topic = data.get("topic") if topic == "stock": handle_stock(data) elif topic == "news": handle_news(data) else: print(f"未知主题消息: {message}") except json.JSONDecodeError: print(f"非JSON消息: {message}") def handle_stock(data): print(f"股票更新: {data['symbol']} 价格: {data['price']}") def handle_news(data): print(f"新闻标题: {data['title']}") ``` ### 注意事项 - **线程安全**:WebSocketApp在单独的线程中运行,注意多线程数据共享安全。 - **重连机制**:网络不稳定时,需要在`on_close`中实现重连逻辑。 - **心跳包**:长时间空闲连接可能被断开,需要定时发送心跳包。 ### 完整框架 我们之前实现的`WebSocketClient`类已经包含了上述所有功能(重连、心跳、多主题订阅等),用户可以直接使用或根据需求修改。 ### 相关问题 1. 如何实现WebSocket客户端的自动重连? 2. WebSocket通信中如何处理二进制数据? 3. 如何在WebSocket连接中实现身份验证? 4. WebSocket与HTTP长轮询有什么区别? 5. 如何测试WebSocket客户端? [^1]: 参考了WebSocket的基本概念和Python实现方法。 [^2]: 提供了简单的创建连接、发送和接收消息的示例。 </think> 在Python模拟WebSocket客户端服务器建立连接,可以通过多种方式实现。以下是详细的方法和最佳实践: --- ### 一、基本实现方法 #### 1. 使用`websocket-client`库(推荐) ```python import websocket def on_message(ws, message): """接收消息回调""" print(f"收到响应: {message}") def on_error(ws, error): """错误处理回调""" print(f"发生错误: {error}") def on_close(ws, status_code, close_msg): """关闭连接回调""" print("连接已关闭") def on_open(ws): """连接建立回调""" print("连接已建立") # 发送初始请求 ws.send('{"command": "subscribe", "topics": ["topic1", "topic2"]}') # 创建WebSocket连接 ws = websocket.WebSocketApp( "wss://your-websocket-server.com/endpoint", on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open ) # 添加自定义请求头 ws.header = { "Authorization": "Bearer token", "X-Custom-Header": "value" } # 启动连接(在新线程中运行) ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) # 禁用SSL验证 ``` --- ### 二、多通道消息监听 #### 1. 基于主题的消息路由 ```python def handle_topic1(data): print(f"主题1更新: {data['value']}") def handle_topic2(data): print(f"主题2更新: {data['status']}") def on_message(ws, message): """消息路由分发""" try: data = json.loads(message) topic = data.get("topic") if topic == "topic1": handle_topic1(data) elif topic == "topic2": handle_topic2(data) else: print(f"未知主题消息: {message}") except json.JSONDecodeError: print(f"非JSON消息: {message}") ``` #### 2. 多线程并行监听 ```python from threading import Thread def start_listener(): """独立的消息监听线程""" def listen(): while True: try: response = ws.recv() # 阻塞接收 print(f"响应: {response}") except websocket.WebSocketConnectionClosedException: break Thread(target=listen, daemon=True).start() # 连接后启动监听线程 def on_open(ws): start_listener() ws.send("开始监听") ``` --- ### 三、高级功能实现 #### 1. 自动重连机制 ```python def run_websocket(): while True: try: ws.run_forever() except Exception as e: print(f"连接断开,5秒后重连: {e}") time.sleep(5) Thread(target=run_websocket).start() ``` #### 2. 心跳保持连接 ```python def heartbeat(): while ws.sock and ws.sock.connected: ws.send('{"type": "heartbeat"}') time.sleep(10) Thread(target=heartbeat, daemon=True).start() ``` --- ### 四、完整测试脚本 ```python import websocket import json import threading import time import ssl class WebSocketTester: def __init__(self, url): self.ws = websocket.WebSocketApp( url, on_message=self.on_message, on_open=self.on_open, on_close=self.on_close ) self.responses = [] self.running = False def on_message(self, ws, message): print(f"收到响应: {message}") self.responses.append(message) def on_open(self, ws): print("连接已建立") ws.send('{"action": "subscribe", "channels": ["live_updates"]}') def on_close(self, ws, status, msg): print(f"连接关闭: {status} - {msg}") self.running = False def start(self): self.running = True self.thread = threading.Thread(target=self.ws.run_forever) self.thread.daemon = True self.thread.start() def send(self, message): self.ws.send(message) def stop(self): self.ws.close() self.thread.join(timeout=1) # 测试用例 tester = WebSocketTester("wss://echo.websocket.org") tester.start() # 发送测试请求 tester.send('{"test": "ping"}') time.sleep(2) # 等待响应 # 验证响应 print(f"收到 {len(tester.responses)} 条响应:") for i, res in enumerate(tester.responses, 1): print(f"{i}. {res}") tester.stop() ``` --- ### 五、关键注意事项 1. **协议选择**: - 非加密连接:`ws://` - 加密连接(TLS):`wss://` 2. **请求头设置**: ```python ws.header = { "Cookie": "sessionid=abc123", "Authorization": "Basic ...", "X-Request-ID": "12345" } ``` 3. **二进制数据处理**: ```python # 接收二进制消息 def on_message(ws, message): if isinstance(message, bytes): print(f"收到二进制数据: {len(message)} bytes") ``` --- ### 六、测试验证方法 1. **使用测试服务器**: ```python # 免费回显测试服务器 tester = WebSocketTester("wss://ws.postman-echo.com/raw") ``` 2. **本地模拟服务器**: ```bash # 安装测试服务器 pip install websockets # 运行测试服务器 python -m websockets ws://localhost:8765 ``` 3. **消息断言测试**: ```python def test_response_count(): tester = WebSocketTester(TEST_URL) tester.start() tester.send("test_message") time.sleep(1) assert len(tester.responses) == 1 tester.stop() ``` --- ### 相关问题 1. 如何在WebSocket连接中实现身份验证? 2. WebSocket通信如何保证消息顺序性? 3. 如何处理WebSocket连接中的超时和重连? 4. Python WebSocket客户端如何发送二进制数据? 5. 如何测试高并发的WebSocket连接? [^1]: python websocket_python 模拟websocket通信 [^2]: python websocket模拟
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JMFS1119

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值