Merge pull request #3333 from tobiasoort/dev

Implemented support for Websocket Subprotocols in WS Client Node.
This commit is contained in:
Nick O'Leary 2022-01-12 09:31:55 +00:00 committed by GitHub
commit e26bae8027
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 51 additions and 10 deletions

View File

@ -177,7 +177,8 @@
path: {value:"",required:true,validate:RED.validators.regex(/^((?!\/debug\/ws).)*$/)}, path: {value:"",required:true,validate:RED.validators.regex(/^((?!\/debug\/ws).)*$/)},
tls: {type:"tls-config",required: false}, tls: {type:"tls-config",required: false},
wholemsg: {value:"false"}, wholemsg: {value:"false"},
hb: {value: "", validate: RED.validators.number(/*blank allowed*/true) } hb: {value: "", validate: RED.validators.number(/*blank allowed*/true) },
subprotocol: {value:"",required: false}
}, },
inputs:0, inputs:0,
outputs:0, outputs:0,
@ -265,7 +266,10 @@
<label for="node-config-input-tls" data-i18n="httpin.tls-config"></label> <label for="node-config-input-tls" data-i18n="httpin.tls-config"></label>
<input type="text" id="node-config-input-tls"> <input type="text" id="node-config-input-tls">
</div> </div>
<div class="form-row">
<label for="node-config-input-subprotocol"><i class="fa fa-tag"></i> <span data-i18n="websocket.label.subprotocol"></span></label>
<input type="text" id="node-config-input-subprotocol">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label> <label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label>
<select type="text" id="node-config-input-wholemsg" style="width: 70%;"> <select type="text" id="node-config-input-wholemsg" style="width: 70%;">

View File

@ -46,6 +46,12 @@ module.exports = function(RED) {
// Store local copies of the node configuration (as defined in the .html) // Store local copies of the node configuration (as defined in the .html)
node.path = n.path; node.path = n.path;
if (typeof n.subprotocol === "string") {
// Split the string on comma and trim each result
node.subprotocol = n.subprotocol.split(",").map(v => v.trim())
} else {
node.subprotocol = [];
}
node.wholemsg = (n.wholemsg === "true"); node.wholemsg = (n.wholemsg === "true");
node._inputNodes = []; // collection of nodes that want to receive events node._inputNodes = []; // collection of nodes that want to receive events
@ -92,7 +98,7 @@ module.exports = function(RED) {
tlsNode.addTLSOptions(options); tlsNode.addTLSOptions(options);
} }
} }
var socket = new ws(node.path,options); var socket = new ws(node.path,node.subprotocol,options);
socket.setMaxListeners(0); socket.setMaxListeners(0);
node.server = socket; // keep for closing node.server = socket; // keep for closing
handleConnection(socket); handleConnection(socket);

View File

@ -499,7 +499,8 @@
"label": { "label": {
"type": "Typ", "type": "Typ",
"path": "Pfad", "path": "Pfad",
"url": "URL" "url": "URL",
"subprotocol": "Subprotokoll"
}, },
"listenon": "Lauschen (listen on)", "listenon": "Lauschen (listen on)",
"connectto": "Verbinden mit", "connectto": "Verbinden mit",

View File

@ -530,7 +530,8 @@
"label": { "label": {
"type": "Type", "type": "Type",
"path": "Path", "path": "Path",
"url": "URL" "url": "URL",
"subprotocol": "Subprotocol"
}, },
"listenon": "Listen on", "listenon": "Listen on",
"connectto": "Connect to", "connectto": "Connect to",

View File

@ -530,7 +530,8 @@
"label": { "label": {
"type": "種類", "type": "種類",
"path": "パス", "path": "パス",
"url": "URL" "url": "URL",
"subprotocol": "サブプロトコル"
}, },
"listenon": "待ち受け", "listenon": "待ち受け",
"connectto": "接続", "connectto": "接続",

View File

@ -433,7 +433,8 @@
"label": { "label": {
"type": "종류", "type": "종류",
"path": "패스", "path": "패스",
"url": "URL" "url": "URL",
"subprotocol": "서브 프로토콜"
}, },
"listenon": "대기", "listenon": "대기",
"connectto": "접속", "connectto": "접속",

View File

@ -461,7 +461,8 @@
"label": { "label": {
"type": "Тип", "type": "Тип",
"path": "Путь", "path": "Путь",
"url": "URL" "url": "URL",
"subprotocol": "Подпротокол"
}, },
"listenon": "Слушать на ...", "listenon": "Слушать на ...",
"connectto": "Присоединиться к ...", "connectto": "Присоединиться к ...",

View File

@ -454,7 +454,8 @@
"label": { "label": {
"type": "类型", "type": "类型",
"path": "路径", "path": "路径",
"url": "URL" "url": "URL",
"subprotocol": "子协议"
}, },
"listenon": "监听", "listenon": "监听",
"connectto": "连接", "connectto": "连接",

View File

@ -458,7 +458,8 @@
"label": { "label": {
"type": "類型", "type": "類型",
"path": "路徑", "path": "路徑",
"url": "URL" "url": "URL",
"subprotocol": "子协议"
}, },
"listenon": "監聽", "listenon": "監聽",
"connectto": "連接", "connectto": "連接",

View File

@ -366,6 +366,18 @@ describe('websocket Node', function() {
}); });
}); });
it('should handle protocol property', function(done) {
var flow = [
{ id: "server", type: "websocket-listener", path: "/ws" },
{ id: "n1", type: "websocket-client", path: getWsUrl("/ws") },
{ id: "n2", type: "websocket-client", path: getWsUrl("/ws"), subprotocol: "testprotocol1, testprotocol2" }];
helper.load(websocketNode, flow, function() {
helper.getNode("n1").should.have.property("subprotocol", []);
helper.getNode("n2").should.have.property("subprotocol", ["testprotocol1","testprotocol2"]);
done();
});
});
it('should connect to server', function(done) { it('should connect to server', function(done) {
var flow = [ var flow = [
{ id: "server", type: "websocket-listener", path: "/ws" }, { id: "server", type: "websocket-listener", path: "/ws" },
@ -378,6 +390,18 @@ describe('websocket Node', function() {
}); });
}); });
it('should initiate with subprotocol', function(done) {
var flow = [
{ id: "server", type: "websocket-listener", path: "/ws" },
{ id: "n2", type: "websocket-client", path: getWsUrl("/ws"), subprotocol: "testprotocol" }];
helper.load(websocketNode, flow, function() {
getSocket('server').on('connection', function (sock) {
sock.should.have.property("protocol", "testprotocol")
done();
});
});
});
it('should close on delete', function(done) { it('should close on delete', function(done) {
var flow = [ var flow = [
{ id: "server", type: "websocket-listener", path: "/ws" }, { id: "server", type: "websocket-listener", path: "/ws" },