gpt4 book ai didi

python - 如何在 python websocket 服务器握手响应中设置 "Sec-WebSocket-Protocol" header ?

转载 作者:行者123 更新时间:2023-12-03 12:15:26 26 4
gpt4 key购买 nike

我有一个 python websocket 服务器和一个 nodejs 客户端,但我不能
实现websocket's Protocol Handshake .

python服务器代码

以下最小的 websocket 服务器使用 Flask-sockets(使用 gevent-websocket )。文件名为 ws_server.py :

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from flask import Flask, request, Response
from flask_sockets import Sockets

app = Flask(__name__)
sockets = Sockets(app)

@sockets.route('/')
def echo_socket(ws):
# print("type request: ",type(request))
# print("dir request: ", dir(request))
print("request.headers: ", request.headers)
# print("type ws: ",type(ws))
# print("dir ws: ",dir(ws))

if hasattr(request, "Sec-Websocket-Protocol"):
print(request.headers["Sec-Websocket-Protocol"])
else:
print("INFO: No protocol specified")

if request.headers["Sec-Websocket-Protocol"] == "aProtocol":
print("INFO: protocol is OK")
else:
print("INFO: protocol not accepted: closing connection")
ws.close()

while not ws.closed:
message = ws.receive()
if message:
print("received: "+message)
ws.send(message)

if ws.closed:
print("INFO: connection has been closed")

if __name__ == "__main__":
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
server = pywsgi.WSGIServer(('', 5001), app, handler_class=WebSocketHandler)
server.serve_forever()

nodejs客户端代码

以下最小的 websocket 客户端使用 websocket图书馆。
文件名为 app.js :
'use strict'

var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();

function connectToServer(uri,protocol){
client.on('connectFailed', function (error) {
console.log('Connect Error: ' + error.toString());
});

client.on('connect', function (connection) {
console.log('WebSocket Client Connected');

connection.on('error', function (error) {
console.log("Connection Error: " + error.toString());
});

connection.on('close', function () {
console.log('echo-protocol Connection Closed');
});

connection.on('ping', () => {
connection.pong();
});

connection.on('message', function (message) {
if (message.type === 'utf8') {
console.log("Received message is: '" + message.utf8Data + "'");
}
});
console.log("sending SOMETHING");
connection.sendUTF("SOMETHING");
});
client.connect(uri, protocol);
}

const wsHostAndPort = process.env.WSHSTPRT || "ws://echo.websocket.org:80";
const wsProtocol = process.env.WSPRTCL || []; // [] for no protocol

console.log("connecting to: ",wsHostAndPort,"with protocol",wsProtocol);
connectToServer(wsHostAndPort,wsProtocol);

从 nodejs 作为客户端的连接

启动 python ws 服务器:
$ python3 ws_server.py

从 nodejs ws 客户端连接:
$ WSHSTPRT=ws://localhost:5001/ WSPRTCL="aProtocol" node app.js

客户端的输出是
connecting to:  ws://localhost:5001/ with protocol aProtocol
Connect Error: Error: Expected a Sec-WebSocket-Protocol header.

服务器终端的输出为:
request.headers:  Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Version: 13
Sec-Websocket-Key: +QjH5xejDI+OQZQ0OZcWEQ==
Host: localhost:5001
Sec-Websocket-Protocol: aProtocol


INFO: No protocol specified
INFO: protocol is OK
INFO: connection has been closed

在我看来,python服务器需要设置一个名为 "Sec-WebSocket-Protocol"与它从
客户。但我不知道该怎么做。我已经搜索了互联网
(主要是 flask-socketsgevent-websockets 论坛和问题
跟踪器)到目前为止没有任何运气。

我尝试了另一个简单的客户端, websocat .我这样调用它: $ websocat ws://localhost:5001 --protocol aProtocol我以交互方式提示了一些消息,它们被 python 服务器正确回显。
它之所以有效,是因为,我认为 websocat (不像nodejs' websocket )
不要期望在与
服务器。

但我需要使用需要 header 的 nodejs 客户端。
所以我的问题是:如何合并 "Sec-WebSocket-Protocol"python服务器握手响应中的 header ?

最佳答案

我知道这是一年多以前的事了,看起来你已经继续前进了,虽然看起来你快到了,只是 aProtocol需要替换为 subprotocol 服务器期望的。
或者,根据基础 gevent-websocket 完全省略那flask-websockets uses :

// Subprotocol (2nd parameter) often is not required at all
var ws = new WebSocket('ws://localhost:5001/api');

对于 future 的我或其他在这里绊倒的人,我希望以下内容有所帮助。
在 JavaScript 中将浏览器连接到 Node.JS apollo-server subscriptions ,我需要以下内容:
// Pasted into Firefox console
const token = '...'; // A bearer token, if auth is needed
const subprotocol = 'graphql-ws';
w = new WebSocket('ws://localhost:5000/graphql', subprotocol);
w.send(JSON.stringify({"type":"connection_init","payload":{"authToken":token}}));
然后我会看到 Sec-Websocket-Protocol header 应用:
Sec-Websocket-Protocol header
Message sent and ack received
否则,如果没有应用子协议(protocol), Sec-Websocket-Protocol header 未发送且控制消息可见,我会看到 Connection Closed: 1002 并且自然无法向 websocket 发送消息:
Connection Closed: 1002

关于python - 如何在 python websocket 服务器握手响应中设置 "Sec-WebSocket-Protocol" header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53106044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com