我正在尝试使用Autobahn / Asyncio连接到Websocket。我已经使用完全相同的代码连接到其他几个websocket,但是这个特定的websocket拒绝了我的尝试。我的连接升级失败,服务器响应为403。我尝试使用“ websockets”软件包连接到此websocket,并且已经成功,因此Autobahn实现中必须有一些默认设置,即造成问题。
我将来自websockets实现的成功握手请求与来自高速公路实现的不成功握手请求进行了比较:
websockets:要求:
GET /ws/v3 HTTP/1.1
Host: real.okex.com:10442
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: eTj8gJmhJGTj868ObmO2qg==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
User-Agent: Python/3.6 websockets/8.0
响应:
Server: nginx
Date: Tue, 09 Jul 2019 20:49:33 GMT
Connection: upgrade
upgrade: websocket
sec-websocket-accept: NJxn9G+1AJaYlHY1n1/Iy6P+2R8=
高速公路:要求:
GET /ws/v3 HTTP/1.1
User-Agent: AutobahnPython/18.11.1
Host: real.okex.com:10442
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: QI5/tydGJRB6/LMDXkQ1dg==
Sec-WebSocket-Version: 13
响应:
WebSocket connection upgrade failed (403 - Forbidden)
[我什至都对高速公路实现进行了硬编码,以发送与'websockets'实现完全相同的GET请求,但这没有用。
高速公路代码:
async def connect_to_OKEX():
while True:
try:
global OKEX_transport
ws_endpoint = 'wss://real.okex.com:10442/ws/v3'
factory = WebSocketClientFactory(ws_endpoint)
factory.protocol = OKEX_Protocol
coro = loop.create_connection(factory, 'www.okex.com', 443, ssl=True)
print("running {}".format(coro))
OKEX_transport, proto = await coro
print("proto {}".format(proto))
break
except Exception as e:
logger.exception('OKEX error connecting')
await asyncio.sleep(1)
websockets代码:
async def subscribe_without_login('wss://real.okex.com:10442/ws/v3', channels):
async with websockets.connect(url) as websocket:
.....
我正在使用的高速公路代码已成功用于其他多个websocket,所以也许我需要勾选一些特定于此websocket的标志?我该如何解决呢?
我在kraken websocket上遇到了完全相同的问题,根本原因是SNI使用了cloudflare。因为websocket升级握手是相同的,所以问题一定出在TLS中。
使用optionsForClientTLS(hostname)而不是ClientContextFactory创建客户端网络套接字后,403问题消失了。