Skip to content

Commit d7aaef6

Browse files
knagaitsevevilebottnawi
authored andcommitted
refactor(server): encapsulate socket server implementation (#1904)
1 parent 87cfaa7 commit d7aaef6

File tree

7 files changed

+167
-61
lines changed

7 files changed

+167
-61
lines changed

lib/Server.js

+5-40
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const url = require('url');
1212
const http = require('http');
1313
const https = require('https');
1414
const ip = require('ip');
15-
const sockjs = require('sockjs');
1615
const semver = require('semver');
1716
const killable = require('killable');
1817
const chokidar = require('chokidar');
@@ -32,26 +31,7 @@ const createDomain = require('./utils/createDomain');
3231
const runBonjour = require('./utils/runBonjour');
3332
const routes = require('./utils/routes');
3433
const schema = require('./options.json');
35-
36-
// Workaround for sockjs@~0.3.19
37-
// sockjs will remove Origin header, however Origin header is required for checking host.
38-
// See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
39-
{
40-
// eslint-disable-next-line global-require
41-
const SockjsSession = require('sockjs/lib/transport').Session;
42-
const decorateConnection = SockjsSession.prototype.decorateConnection;
43-
SockjsSession.prototype.decorateConnection = function(req) {
44-
decorateConnection.call(this, req);
45-
const connection = this.connection;
46-
if (
47-
connection.headers &&
48-
!('origin' in connection.headers) &&
49-
'origin' in req.headers
50-
) {
51-
connection.headers.origin = req.headers.origin;
52-
}
53-
};
54-
}
34+
const SockJSServer = require('./servers/SockJSServer');
5535

5636
// Workaround for node ^8.6.0, ^9.0.0
5737
// DEFAULT_ECDH_CURVE is default to prime256v1 in these version
@@ -671,20 +651,9 @@ class Server {
671651
}
672652

673653
createSocketServer() {
674-
const socket = sockjs.createServer({
675-
// Use provided up-to-date sockjs-client
676-
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
677-
// Limit useless logs
678-
log: (severity, line) => {
679-
if (severity === 'error') {
680-
this.log.error(line);
681-
} else {
682-
this.log.debug(line);
683-
}
684-
},
685-
});
654+
this.socketServer = new SockJSServer(this);
686655

687-
socket.on('connection', (connection) => {
656+
this.socketServer.onConnection((connection) => {
688657
if (!connection) {
689658
return;
690659
}
@@ -736,10 +705,6 @@ class Server {
736705

737706
this._sendStats([connection], this.getStats(this._stats), true);
738707
});
739-
740-
socket.installHandlers(this.listeningApp, {
741-
prefix: this.sockPath,
742-
});
743708
}
744709

745710
listen(port, hostname, fn) {
@@ -762,7 +727,7 @@ class Server {
762727

763728
close(cb) {
764729
this.sockets.forEach((socket) => {
765-
socket.close();
730+
this.socketServer.close(socket);
766731
});
767732

768733
this.sockets = [];
@@ -923,7 +888,7 @@ class Server {
923888
// eslint-disable-next-line
924889
sockWrite(sockets, type, data) {
925890
sockets.forEach((socket) => {
926-
socket.write(JSON.stringify({ type, data }));
891+
this.socketServer.send(socket, JSON.stringify({ type, data }));
927892
});
928893
}
929894

lib/servers/BaseServer.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
// base class that users should extend if they are making their own
4+
// server implementation
5+
module.exports = class BaseServer {
6+
constructor(server) {
7+
this.server = server;
8+
}
9+
};

lib/servers/SockJSServer.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict';
2+
3+
/* eslint-disable
4+
class-methods-use-this,
5+
func-names
6+
*/
7+
const sockjs = require('sockjs');
8+
const BaseServer = require('./BaseServer');
9+
10+
// Workaround for sockjs@~0.3.19
11+
// sockjs will remove Origin header, however Origin header is required for checking host.
12+
// See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
13+
{
14+
// eslint-disable-next-line global-require
15+
const SockjsSession = require('sockjs/lib/transport').Session;
16+
const decorateConnection = SockjsSession.prototype.decorateConnection;
17+
SockjsSession.prototype.decorateConnection = function(req) {
18+
decorateConnection.call(this, req);
19+
const connection = this.connection;
20+
if (
21+
connection.headers &&
22+
!('origin' in connection.headers) &&
23+
'origin' in req.headers
24+
) {
25+
connection.headers.origin = req.headers.origin;
26+
}
27+
};
28+
}
29+
30+
module.exports = class SockJSServer extends BaseServer {
31+
// options has: error (function), debug (function), server (http/s server), path (string)
32+
constructor(server) {
33+
super(server);
34+
this.socket = sockjs.createServer({
35+
// Use provided up-to-date sockjs-client
36+
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
37+
// Limit useless logs
38+
log: (severity, line) => {
39+
if (severity === 'error') {
40+
this.server.log.error(line);
41+
} else {
42+
this.server.log.debug(line);
43+
}
44+
},
45+
});
46+
47+
this.socket.installHandlers(this.server.listeningApp, {
48+
prefix: this.server.sockPath,
49+
});
50+
}
51+
52+
send(connection, message) {
53+
connection.write(message);
54+
}
55+
56+
close(connection) {
57+
connection.close();
58+
}
59+
60+
// f should return the resulting connection
61+
onConnection(f) {
62+
this.socket.on('connection', f);
63+
}
64+
};

lib/servers/WebsocketServer.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
// const ws = require('ws');
4+
const BaseServer = require('./BaseServer');
5+
6+
// ws server implementation under construction
7+
// will need changes in the client as well to function
8+
module.exports = class WebsocketServer extends BaseServer {};

lib/servers/baseServer.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
// base class that users should extend if they are making their own
4+
// server implementation
5+
module.exports = class BaseServer {
6+
constructor(server) {
7+
this.server = server;
8+
}
9+
};

lib/servers/sockjsServer.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict';
2+
3+
/* eslint-disable
4+
class-methods-use-this,
5+
func-names
6+
*/
7+
const sockjs = require('sockjs');
8+
const BaseServer = require('./BaseServer');
9+
10+
// Workaround for sockjs@~0.3.19
11+
// sockjs will remove Origin header, however Origin header is required for checking host.
12+
// See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
13+
{
14+
// eslint-disable-next-line global-require
15+
const SockjsSession = require('sockjs/lib/transport').Session;
16+
const decorateConnection = SockjsSession.prototype.decorateConnection;
17+
SockjsSession.prototype.decorateConnection = function(req) {
18+
decorateConnection.call(this, req);
19+
const connection = this.connection;
20+
if (
21+
connection.headers &&
22+
!('origin' in connection.headers) &&
23+
'origin' in req.headers
24+
) {
25+
connection.headers.origin = req.headers.origin;
26+
}
27+
};
28+
}
29+
30+
module.exports = class SockJSServer extends BaseServer {
31+
// options has: error (function), debug (function), server (http/s server), path (string)
32+
constructor(server) {
33+
super(server);
34+
this.socket = sockjs.createServer({
35+
// Use provided up-to-date sockjs-client
36+
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
37+
// Limit useless logs
38+
log: (severity, line) => {
39+
if (severity === 'error') {
40+
this.server.log.error(line);
41+
} else {
42+
this.server.log.debug(line);
43+
}
44+
},
45+
});
46+
47+
this.socket.installHandlers(this.server.listeningApp, {
48+
prefix: this.server.sockPath,
49+
});
50+
}
51+
52+
send(connection, message) {
53+
connection.write(message);
54+
}
55+
56+
close(connection) {
57+
connection.close();
58+
}
59+
60+
// f should return the resulting connection
61+
onConnection(f) {
62+
this.socket.on('connection', f);
63+
}
64+
};

package-lock.json

+8-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)