ws代理服务,mock ws
结合charles + python websocket代理服务器,mock web 、app端的websocket。
1、将 APP,web端的ws请求代理到charles
2、设置 charles 代理ws 到 remote server
3 启动remote server 。 Python代码如下
import asyncio import websockets import json import base64 import gzip,json from io import BytesIO import ssl def encode(json_data): # 1. gzip压缩 json_bytes = json.dumps(json_data).encode("utf-8") buf = BytesIO() with gzip.GzipFile(fileobj=buf, mode="wb") as f: f.write(json_bytes) gzip_payload = buf.getvalue() # 2、base64加密 base64_encoded = base64.b64encode(gzip_payload).decode("utf-8") print(base64_encoded) return base64_encoded # 目标 WebSocket 服务端地址 TARGET_WS_URI = "wss://xxxxxx/ws/v1" # data = { # "assets": [ # { # "accountId": 97, # "cash": 72839.01, # "equity": 72777.018, # "exType": 3, # "freeEquity": 0.0, # "im": 31.0, # "leverage": 0.0, # "marketVal": -62.0, # "mm": 24.8, # "netCashPower": 72745.828, # "riskLevel": "Danger", # "symbol": "USD" # } # ], # "equity": { # "accountId": 97, # "exType": 3, # "totalEquity": 72777.018 # } # } data = { "assets": [ { "accountId": 154, "cash": 2619.2, "equity": 2578.1, "exType": 2, "freeEquity": 0.0, "im": 1269.54192, "leverage": 0.02, "marketVal": -41.05, "mm": 982.71588, "netCashPower": 14.4246, "riskLevel": "Safe", "symbol": "USD" } ], "equity": { "accountId": 154, "exType": 2, "totalEquity": 2577.6666666 } } asset_compressData = encode(data) rules = [ # { # "matched": False, # "contain_text": "subjective.account.asset.position", # "response": { # "accountId": 97, # "event": "account.asset.update", # "compressData": asset_compressData, # "channel": "subjective.account.asset.position" # } # }, { "matched": False, "contain_text": "account.asset", "response": { "accountId": 154, "event": "account.asset.update", "compressData": asset_compressData, "channel": "account.asset" } }, ] async def loop_send_mock(client_ws, message): while True: await asyncio.sleep(3) try: await client_ws.send(json.dumps(message)) print(f"[mock loop] sent: {message}") except websockets.exceptions.ConnectionClosed: break async def proxy_handler(client_ws): try: ssl_context = ssl._create_unverified_context() # 连接真实服务端 async with websockets.connect(TARGET_WS_URI, ssl=ssl_context) as server_ws: async def from_client_to_server(): async for message in client_ws: print(f"From client: {message}") for rule in rules: if rule["contain_text"] in message and not rule["matched"]: rule["matched"] = True asyncio.create_task(loop_send_mock(client_ws, rule["response"])) break await server_ws.send(message) async def from_server_to_client(): async for message in server_ws: print(f"From server: {message}") await client_ws.send(message) # 同时启动双向转发 await asyncio.gather( from_client_to_server(), from_server_to_client(), ) except websockets.exceptions.ConnectionClosed: print("Connection closed") except Exception as e: print(f"Error: {e}") async def main(): async with websockets.serve(proxy_handler, "0.0.0.0", 8765): print("WebSocket proxy server running on ws://localhost:8765") await asyncio.Future() # run forever if __name__ == "__main__": asyncio.run(main())
鸡肉是我的最爱!