ws4py.websocket: 正在关闭客户端长时间延迟的连接
ws4py.websocket: Closing connection from client long delay
我使用 ws4py.websocket 包创建了一个安全的 WebSocket 服务器。
一个 javascript 客户端连接到这个 Websocket 并向它发送一些 JSON 消息。
现在,当我的 JS 客户端关闭连接 (function disconnect
) 时,大约需要 30 秒才能调用服务器的 closed
函数
代码如下:
服务器
class ControlWebSocket(WebSocket):
def opened(self):
print("Client connected")
def closed(self, code, reason=None):
print("Connection closed [%d]" % (code))
def received_message(self, m):
#some business logic using 'm'
server = make_server('', 8999, server_class=WSGIServer, handler_class=WebSocketWSGIRequestHandler, app=WebSocketWSGIApplication(handler_cls=ControlWebSocket))
server.socket = ssl.wrap_socket (server.socket, certfile='./cert.pem', keyfile='key.pem', server_side=True)
server.initialize_websockets_manager()
server.serve_forever()
客户端
ws = new WebSocket("wss://192.168.42.1:8999/");
ws.onopen = function() {
console.log("Connected to WebSocket server");
};
ws.onmessage = function(e) {
//some business logic using e
};
ws.onclose = function() {
console.log("Disconnected from WebSocketServer");
};
function disconnect() {
console.log("Disconnecting from WebSocketServer");
ws.close();
}
关于为什么这么长时间关闭连接有什么线索吗?有没有什么方法可以更快地终止连接?
这是您的客户端问题。如果您查看 ws
模块。在顶部你有
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
然后你有下面的代码
if (!this._finalized) {
if (this._closeFrameReceived) this._socket.end();
//
// Ensure that the connection is cleaned up even when the closing
// handshake fails.
//
this._closeTimer = setTimeout(this._finalize, closeTimeout, true);
}
这是为了确保连接不会在 30 秒之前关闭,并给每一方足够的时间来清理连接。这次是 const
而不是 configurable
。但是,如果您希望立即终止,您可以在 ws.close()
之后添加一个 ws.finalize()
,它会立即断开连接
const WebSocket = require('ws');
let ws = new WebSocket("wss://127.0.0.1:8999/", {
rejectUnauthorized: false
});
ws.onopen = function() {
console.log("Connected to WebSocket server");
};
ws.onmessage = function(e) {
//some business logic using e
};
ws.onclose = function() {
console.log("Disconnected from WebSocketServer");
};
function disconnect() {
console.log("Disconnecting from WebSocketServer");
ws.close();
ws.finalize();
}
setTimeout(disconnect, 100)
编辑-1
深入挖掘后,ws4py
似乎有些东西不符合 rfc6455。
当您从 NodeJS 执行关闭时,它会发送一个 \x88\x80
的关闭帧,表示应该关闭连接并发送一个关闭帧。文件 ws4py/streaming.py
存在一些无法正确响应此帧的问题。它基本上期望读取更多数据并卡住等待相同的数据。这会导致连接从客户端以默认的 30 秒超时关闭。
所以这是您正在使用的 python 库中的错误。我使用 NodeJS 创建了一个客户端 WebSocket.server
它正确关闭了。
为什么不在 NodeJS 本身中使用服务器?在下面 link
有一个很好的例子可以做同样的事情
https://github.com/websockets/ws/blob/master/examples/ssl.js
此处代码供参考
'use strict';
const https = require('https');
const fs = require('fs');
const WebSocket = require('..');
const server = https.createServer({
cert: fs.readFileSync('../test/fixtures/certificate.pem'),
key: fs.readFileSync('../test/fixtures/key.pem')
});
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection (ws) {
ws.on('message', function message (msg) {
console.log(msg);
});
});
server.listen(function listening () {
//
// If the `rejectUnauthorized` option is not `false`, the server certificate
// is verified against a list of well-known CAs. An 'error' event is emitted
// if verification fails.
//
// The certificate used in this example is self-signed so `rejectUnauthorized`
// is set to `false`.
//
const ws = new WebSocket(`wss://localhost:${server.address().port}`, {
rejectUnauthorized: false
});
ws.on('open', function open () {
ws.send('All glory to WebSockets!');
});
});
我使用 ws4py.websocket 包创建了一个安全的 WebSocket 服务器。
一个 javascript 客户端连接到这个 Websocket 并向它发送一些 JSON 消息。
现在,当我的 JS 客户端关闭连接 (function disconnect
) 时,大约需要 30 秒才能调用服务器的 closed
函数
代码如下:
服务器
class ControlWebSocket(WebSocket):
def opened(self):
print("Client connected")
def closed(self, code, reason=None):
print("Connection closed [%d]" % (code))
def received_message(self, m):
#some business logic using 'm'
server = make_server('', 8999, server_class=WSGIServer, handler_class=WebSocketWSGIRequestHandler, app=WebSocketWSGIApplication(handler_cls=ControlWebSocket))
server.socket = ssl.wrap_socket (server.socket, certfile='./cert.pem', keyfile='key.pem', server_side=True)
server.initialize_websockets_manager()
server.serve_forever()
客户端
ws = new WebSocket("wss://192.168.42.1:8999/");
ws.onopen = function() {
console.log("Connected to WebSocket server");
};
ws.onmessage = function(e) {
//some business logic using e
};
ws.onclose = function() {
console.log("Disconnected from WebSocketServer");
};
function disconnect() {
console.log("Disconnecting from WebSocketServer");
ws.close();
}
关于为什么这么长时间关闭连接有什么线索吗?有没有什么方法可以更快地终止连接?
这是您的客户端问题。如果您查看 ws
模块。在顶部你有
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
然后你有下面的代码
if (!this._finalized) {
if (this._closeFrameReceived) this._socket.end();
//
// Ensure that the connection is cleaned up even when the closing
// handshake fails.
//
this._closeTimer = setTimeout(this._finalize, closeTimeout, true);
}
这是为了确保连接不会在 30 秒之前关闭,并给每一方足够的时间来清理连接。这次是 const
而不是 configurable
。但是,如果您希望立即终止,您可以在 ws.close()
之后添加一个 ws.finalize()
,它会立即断开连接
const WebSocket = require('ws');
let ws = new WebSocket("wss://127.0.0.1:8999/", {
rejectUnauthorized: false
});
ws.onopen = function() {
console.log("Connected to WebSocket server");
};
ws.onmessage = function(e) {
//some business logic using e
};
ws.onclose = function() {
console.log("Disconnected from WebSocketServer");
};
function disconnect() {
console.log("Disconnecting from WebSocketServer");
ws.close();
ws.finalize();
}
setTimeout(disconnect, 100)
编辑-1
深入挖掘后,ws4py
似乎有些东西不符合 rfc6455。
当您从 NodeJS 执行关闭时,它会发送一个 \x88\x80
的关闭帧,表示应该关闭连接并发送一个关闭帧。文件 ws4py/streaming.py
存在一些无法正确响应此帧的问题。它基本上期望读取更多数据并卡住等待相同的数据。这会导致连接从客户端以默认的 30 秒超时关闭。
所以这是您正在使用的 python 库中的错误。我使用 NodeJS 创建了一个客户端 WebSocket.server
它正确关闭了。
为什么不在 NodeJS 本身中使用服务器?在下面 link
有一个很好的例子可以做同样的事情https://github.com/websockets/ws/blob/master/examples/ssl.js
此处代码供参考
'use strict';
const https = require('https');
const fs = require('fs');
const WebSocket = require('..');
const server = https.createServer({
cert: fs.readFileSync('../test/fixtures/certificate.pem'),
key: fs.readFileSync('../test/fixtures/key.pem')
});
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection (ws) {
ws.on('message', function message (msg) {
console.log(msg);
});
});
server.listen(function listening () {
//
// If the `rejectUnauthorized` option is not `false`, the server certificate
// is verified against a list of well-known CAs. An 'error' event is emitted
// if verification fails.
//
// The certificate used in this example is self-signed so `rejectUnauthorized`
// is set to `false`.
//
const ws = new WebSocket(`wss://localhost:${server.address().port}`, {
rejectUnauthorized: false
});
ws.on('open', function open () {
ws.send('All glory to WebSockets!');
});
});