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())
鸡肉是我的最爱!
浙公网安备 33010602011771号