Skip to content
This repository was archived by the owner on Feb 11, 2020. It is now read-only.

Commit f1c814a

Browse files
authored
Merge pull request #606 from namgk/master
mqtt over websocket on different path
2 parents 9e451ae + 5d27802 commit f1c814a

6 files changed

+218
-16
lines changed

lib/options.js

-7
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,6 @@ function validate(opts, validationOptions) {
258258

259259
var result = validator.validate(opts, '/Options', validationOptions);
260260

261-
// check empty interfaces
262-
if (opts.hasOwnProperty('interfaces')) {
263-
if (opts.interfaces.length === 0) {
264-
result.addError('no interfaces were defined');
265-
}
266-
}
267-
268261
// check required credentials
269262
if (opts.hasOwnProperty('interfaces')) {
270263
var hasCredentials = opts.hasOwnProperty('credentials');

lib/server.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ function Server(opts, callback) {
162162
// initialize servers list
163163
this.servers = [];
164164

165+
165166
steed.series([
166167

167168
// steed.series: wait for ascoltatore
@@ -236,7 +237,6 @@ function Server(opts, callback) {
236237
}
237238
});
238239

239-
240240
that.on("clientConnected", function(client) {
241241
if(that.modernOpts.publishNewClient) {
242242
that.publish({
@@ -609,10 +609,17 @@ Server.prototype.close = function(callback) {
609609
*
610610
* @api public
611611
* @param {HttpServer} server
612+
* @param {String} path
612613
*/
613-
Server.prototype.attachHttpServer = function(server) {
614+
Server.prototype.attachHttpServer = function(server, path) {
614615
var that = this;
615-
ws.createServer({ server: server }, function(stream) {
616+
617+
var opt = { server: server };
618+
if (path) {
619+
opt.path = path;
620+
}
621+
622+
ws.createServer(opt, function(stream) {
616623
var conn = new Connection(stream);
617624
new Client(conn, that);
618625
});

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"author": "Matteo Collina <hello@matteocollina.com>",
4949
"license": "MIT",
5050
"devDependencies": {
51+
"browserify": "~13.0.0",
5152
"chai": "^3.5.0",
5253
"coveralls": "~2.11.1",
5354
"dox-foundation": "~0.5.4",
@@ -62,9 +63,9 @@
6263
"sinon-chai": "~2.8.0",
6364
"supertest": "~1.2.0",
6465
"tmp": "0.0.24",
65-
"browserify": "~13.0.0",
6666
"uglify-js": "^2.4.16",
67-
"underscore": "^1.7.0"
67+
"underscore": "^1.7.0",
68+
"ws": "^1.0.1"
6869
},
6970
"dependencies": {
7071
"array-from": "^2.1.1",

test/abstract_server.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ module.exports = function(moscaSettings, createConnection) {
4141
});
4242

4343
function finish () {
44-
client.removeListener('error', finish)
45-
client.stream.removeListener('close', finish)
46-
done()
44+
client.removeListener('error', finish);
45+
client.stream.removeListener('close', finish);
46+
done();
4747
}
4848
}
4949

test/server.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ describe("mosca.Server", function() {
174174
// Simulate a situation that it takes same time to do authorizeSubscribe.
175175
this.instance.authorizeSubscribe = function(client, topic, callback) {
176176
setTimeout(function(){
177-
callback(null, true)
177+
callback(null, true);
178178
}, 300);
179179
};
180180

test/server_websocket_attach.js

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
var mqtt = require('mqtt');
2+
var websocket = require('ws');
3+
var http = require('http');
4+
5+
var port = nextPort();
6+
var path = '/test';
7+
var mqttPath = '/mqttws';
8+
var mqttTopic = 'atopic';
9+
var ping = 'ping';
10+
var pong = 'pong';
11+
12+
describe("mosca.Server - Mqtt-over-WS attached to existing http server", function() {
13+
var server, mqttServ;
14+
15+
beforeEach(function(){
16+
server = http.createServer();
17+
mqttServ = new mosca.Server({interfaces:[]});
18+
});
19+
20+
afterEach(function(){
21+
server.close();
22+
});
23+
24+
it("should not occupy 1883 port while attached to http server", function(done) {
25+
mqttServ.attachHttpServer(server);
26+
server.listen(1883, done);
27+
});
28+
29+
it("should be able to do mqtt over WebSocket", function(done) {
30+
mqttServ.attachHttpServer(server);
31+
server.listen(port, function(){
32+
var client = mqtt.connect('ws://localhost:' + port);
33+
client.subscribe(mqttTopic);
34+
client.on("message", function(topic, payload) {
35+
expect(topic).to.equal(mqttTopic);
36+
expect(payload.toString()).to.equal(ping);
37+
done();
38+
});
39+
client.publish(mqttTopic, ping);
40+
});
41+
});
42+
43+
it("should be able to do mqtt over WebSocket on specific path", function(done) {
44+
mqttServ.attachHttpServer(server, mqttPath);
45+
server.listen(port, function(){
46+
var client = mqtt.connect('ws://localhost:' + port + mqttPath);
47+
client.subscribe(mqttTopic);
48+
client.on("message", function(topic, payload) {
49+
expect(topic).to.equal(mqttTopic);
50+
expect(payload.toString()).to.equal(ping);
51+
done();
52+
});
53+
client.publish(mqttTopic, ping);
54+
});
55+
});
56+
57+
it("should not be able to do mqtt over WebSocket on different path", function(done) {
58+
mqttServ.attachHttpServer(server, mqttPath);
59+
server.listen(port, function(){
60+
var client = mqtt.connect('ws://localhost:' + port + '/junk');
61+
client.subscribe(mqttTopic);
62+
var failed = false;// ensuring done is called once
63+
client.on("message", function(topic, payload) {
64+
failed = true;
65+
done(failed);
66+
});
67+
client.publish(mqttTopic, ping);
68+
setTimeout(function(){
69+
if (!failed){
70+
done();
71+
}
72+
}, 3000);
73+
});
74+
});
75+
76+
it("should not be able to do mqtt over WebSocket on root path", function(done) {
77+
mqttServ.attachHttpServer(server, mqttPath);
78+
server.listen(port, function(){
79+
var client = mqtt.connect('ws://localhost:' + port);
80+
client.subscribe(mqttTopic);
81+
var failed = false;
82+
client.on("message", function(topic, payload) {
83+
failed = true;
84+
done(failed);
85+
});
86+
client.publish(mqttTopic, ping);
87+
setTimeout(function(){
88+
if (!failed){
89+
done();
90+
}
91+
}, 2000);
92+
});
93+
});
94+
});
95+
96+
describe("mosca.Server - Websocket and Mqtt-over-WS attached to the same http server", function() {
97+
var server, mqttServ, wss;
98+
99+
beforeEach(function(){
100+
server = http.createServer();
101+
mqttServ = new mosca.Server({interfaces:[]});
102+
103+
wss = new websocket.Server({
104+
server: server,
105+
path: path,
106+
perMessageDeflate: false
107+
});
108+
});
109+
110+
afterEach(function(){
111+
server.close();
112+
});
113+
114+
it("ws client should not connect when mqtt is attached to http server without path", function(done) {
115+
mqttServ.attachHttpServer(server);
116+
server.listen(port, function(){
117+
var ws = new websocket('ws://localhost:' + port + path, {
118+
perMessageDeflate: false
119+
});
120+
121+
ws.on('error', function(e) {
122+
expect(e).to.not.be.undefined;
123+
done();
124+
});
125+
});
126+
});
127+
128+
it("ws client should be able to connect when specific path is used", function(done) {
129+
mqttServ.attachHttpServer(server, mqttPath);
130+
wss.on('connection', function(conn){
131+
conn.on('message', function(msg){
132+
expect(msg).to.equal(ping);
133+
conn.send(pong);
134+
});
135+
});
136+
137+
server.listen(port, function(){
138+
var ws = new websocket('ws://localhost:' + port + path, {
139+
perMessageDeflate: false
140+
});
141+
142+
ws.on('open', function(){
143+
ws.send(ping);
144+
});
145+
146+
ws.on('message', function(msg){
147+
expect(msg).to.equal(pong);
148+
done();
149+
});
150+
});
151+
});
152+
153+
it("mqtt client should be able to connect as well", function(done) {
154+
mqttServ.attachHttpServer(server, mqttPath);
155+
server.listen(port, function(){
156+
var client = mqtt.connect('ws://localhost:' + port + mqttPath);
157+
client.subscribe(mqttTopic);
158+
client.on("message", function(topic, payload) {
159+
expect(topic).to.equal(mqttTopic);
160+
expect(payload.toString()).to.equal(ping);
161+
done();
162+
});
163+
client.publish(mqttTopic, ping);
164+
});
165+
});
166+
167+
it("both ws and mqtt client should be able to connect at the same time", function(done) {
168+
mqttServ.attachHttpServer(server, mqttPath);
169+
wss.on('connection', function(conn){
170+
conn.on('message', function(msg){
171+
expect(msg).to.equal(ping);
172+
conn.send(pong);
173+
});
174+
});
175+
176+
server.listen(port, function(){
177+
var client = mqtt.connect('ws://localhost:' + port + mqttPath);
178+
var ws = new websocket('ws://localhost:' + port + path, {
179+
perMessageDeflate: false
180+
});
181+
182+
client.on('connect', function () {
183+
client.subscribe(mqttTopic);
184+
setTimeout(function(){// wait for ws to connect
185+
ws.send(ping);
186+
}, 2000);
187+
});
188+
189+
ws.on('message', function(msg){
190+
expect(msg).to.equal(pong);
191+
client.publish(mqttTopic, ping);
192+
});
193+
194+
client.on("message", function(topic, payload) {
195+
expect(topic).to.equal(mqttTopic);
196+
expect(payload.toString()).to.equal(ping);
197+
done();
198+
});
199+
});
200+
});
201+
});

0 commit comments

Comments
 (0)