no classification
no tag
no datas
posted on 2024-11-07 20:04 read(69) comment(0) like(23) collect(3)
I created a secure WebSocket server using the ws4py.websocket package.
A javascript client connects to this Websocket and sends some JSON messages to it.
Now when my JS client closes the connection (function disconnect
), it takes about 30 secondes before the server's closed
function gets called
Here's the code:
Server
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()
Client
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();
}
Any clues on why this is so long to close the connection ? Are there any ways to terminate the connection faster ?
This your client side issue. If you look in the ws
module. At the top you have
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
And then you have below code
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);
}
Which is to ensure the connection doesn't close before 30 second and gives each party enough time to cleanup the connection. This time is a const
and not configurable
as such. But if you want the termination to happen instantly you can add a ws.finalize()
after ws.close()
and it would disconnect immediately
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)
Edit-1
After digging deeper it seems the ws4py
has some stuff not in accordance to rfc6455.
When you do a close from NodeJS, it sends a close frame of \x88\x80
which indicates that connection should be closed and a close frame should be sent. The file ws4py/streaming.py
has some issues where it doesn't respond to this frame properly. It basically expects more data to be read and gets stuck waiting for the same. This cause the connection to be closed from the client side with the default 30 second timeout.
So this is a bug in the python library which you are using. I created a client using NodeJS WebSocket.server
it closed properly.
Why don't you use the Server in NodeJS itself? There is a great example for doing the same at below link
https://github.com/websockets/ws/blob/master/examples/ssl.js
code here for reference
'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!');
});
});
Author:qs
link:http://www.pythonblackhole.com/blog/article/246860/65dd8bfc1cd20e12accd/
source:python black hole net
Please indicate the source for any form of reprinting. If any infringement is discovered, it will be held legally responsible.
name:
Comment content: (supports up to 255 characters)
Copyright © 2018-2021 python black hole network All Rights Reserved All rights reserved, and all rights reserved.京ICP备18063182号-7
For complaints and reports, and advertising cooperation, please contact vgs_info@163.com or QQ3083709327
Disclaimer: All articles on the website are uploaded by users and are only for readers' learning and communication use, and commercial use is prohibited. If the article involves pornography, reactionary, infringement and other illegal information, please report it to us and we will delete it immediately after verification!