99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
import requests, json, uuid, time, threading, sys
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
BASE = 'http://192.168.5.100:8009'
|
|
|
|
# Login
|
|
r = requests.post(f'{BASE}/api/auth/login', json={'userName':'nanxun','password':'123456'})
|
|
d = r.json()['data']
|
|
token, uid = d['token'], d['userId']
|
|
print(f'Logged in: {uid[:8]}...')
|
|
|
|
# Negotiate
|
|
nr = requests.post(f'{BASE}/chat/negotiate?access_token={token}&negotiateVersion=1',
|
|
headers={'X-Requested-With': 'XMLHttpRequest'})
|
|
neg = nr.json()
|
|
conn_id = neg['connectionId']
|
|
conn_token = neg['connectionToken']
|
|
print(f'Negotiate OK: connId={conn_id[:12]}... token={conn_token[:12]}...')
|
|
|
|
# WebSocket connect (proper SignalR protocol)
|
|
import websocket
|
|
ws_url = f'ws://192.168.5.100:8009/chat?id={conn_token}'
|
|
print(f'WS URL: {ws_url[:80]}...')
|
|
|
|
# Custom WebSocket with proper headers
|
|
class SignalRTracker:
|
|
def __init__(self):
|
|
self.open = False
|
|
self.msgs = []
|
|
self.errors = []
|
|
self.closed = False
|
|
|
|
def on_open(self, ws):
|
|
self.open = True
|
|
# Send the SignalR handshake
|
|
ws.send('{"protocol":"json","version":1}\x1e')
|
|
print('[SIGNALR] Handshake sent')
|
|
|
|
def on_message(self, ws, msg):
|
|
self.msgs.append(msg)
|
|
# SignalR messages are terminated with \x1e (record separator)
|
|
for m in msg.split('\x1e'):
|
|
m = m.strip()
|
|
if not m: continue
|
|
try:
|
|
data = json.loads(m)
|
|
t = data.get('type', 0)
|
|
if t == 1: print(f'[SIGNALR] Invocation: {str(data)[:200]}')
|
|
elif t == 6: print(f'[SIGNALR] Ping')
|
|
elif 'error' in data: print(f'[SIGNALR] Error: {data.get("error")}')
|
|
else: print(f'[SIGNALR] Msg type={t}: {str(data)[:200]}')
|
|
except:
|
|
print(f'[SIGNALR] Raw: {m[:200]}')
|
|
|
|
def on_error(self, ws, err):
|
|
self.errors.append(str(err))
|
|
print(f'[SIGNALR] Error: {str(err)[:150]}')
|
|
|
|
def on_close(self, ws, code, reason):
|
|
self.closed = True
|
|
print(f'[SIGNALR] Close: code={code} reason={str(reason)[:100]}')
|
|
|
|
tracker = SignalRTracker()
|
|
ws = websocket.WebSocketApp(ws_url,
|
|
on_open=tracker.on_open,
|
|
on_message=tracker.on_message,
|
|
on_error=tracker.on_error,
|
|
on_close=tracker.on_close,
|
|
header={'Authorization': f'Bearer {token}'})
|
|
|
|
t = threading.Thread(target=lambda: ws.run_forever(ping_interval=10), daemon=True)
|
|
t.start()
|
|
time.sleep(4)
|
|
|
|
if not tracker.open:
|
|
print('FAILED: WebSocket did not open')
|
|
print('Errors:', tracker.errors)
|
|
else:
|
|
print('SUCCESS: WebSocket connected!')
|
|
print(f'Received {len(tracker.msgs)} handshake responses')
|
|
|
|
# Now send a message
|
|
cid = str(uuid.uuid4())
|
|
mr = requests.post(f'{BASE}/api/message/send', json={
|
|
'ClientMsgId': cid, 'TargetId': '4eb50000-a3ad-9631-f5fe-08ded40a21f7',
|
|
'ChatType': 0, 'MsgType': 0, 'Text': f'signalr-push-test-{int(time.time())}'
|
|
}, headers={'Authorization': f'Bearer {token}'})
|
|
print(f'Send msg: code={mr.json()["code"]}')
|
|
|
|
time.sleep(5)
|
|
print(f'Total msgs received: {len(tracker.msgs)}')
|
|
for m in tracker.msgs:
|
|
print(f' MSG: {m[:300]}')
|
|
|
|
if tracker.closed:
|
|
print(f'\nConnection was closed')
|
|
|
|
print(f'\nSummary: connected={tracker.open} msgs={len(tracker.msgs)} errors={len(tracker.errors)}')
|