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())

  

posted on 2025-06-12 13:56  老吃鸡  阅读(47)  评论(0)    收藏  举报

导航