Skip to content

Commit 36284e5

Browse files
feat: add support of multiple servers
1 parent e6e4969 commit 36284e5

12 files changed

Lines changed: 178 additions & 125 deletions

File tree

cli/index.cli.js

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
const program = require('commander');
44
const colors = require('colors');
5-
const path = require('path');
65

7-
const httpServer = require('http-server');
8-
const apiServer = require('../src/server');
6+
const server = require('../src/server');
97

108
program
119
.option('-e, --entry [entryFile]', 'Specify path to entry point file. E.g. `./src/app.js`')
@@ -26,16 +24,13 @@ if (!program.entry && !program.dir) {
2624
process.exit();
2725
}
2826

29-
// TODO: refactor as in index.dev
30-
apiServer.run({
31-
entryFile: program.entry,
32-
projectDir: program.dir,
33-
webpackConfigFile: program.webpack,
34-
clientPort: program.port
35-
});
36-
37-
httpServer
38-
.createServer({ root: path.resolve(__dirname, '../src/public/dist/local') })
39-
.listen(program.port, '127.0.0.1', () => {
40-
console.log(`Go to "Codecrumbs" client http://localhost:${program.port} `);
41-
});
27+
server.setup(
28+
{
29+
projectNameAlias: undefined, // TODO: add param for this
30+
entryPoint: program.entry,
31+
projectDir: program.dir,
32+
webpackConfigPath: program.webpack,
33+
clientPort: program.port
34+
},
35+
false
36+
);

index.dev.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
},
1010
"scripts": {
1111
"start": "yarn client-dev & yarn server-dev",
12-
"start:demo": "node ./index.dev.js",
12+
"start:demo": "node src/index.dev.js",
1313
"client-dev": "cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev",
14-
"server-dev": "nodemon ./index.dev.js",
15-
"server-debug": "nodemon --inspect ./index.dev.js",
14+
"server-dev": "nodemon src/index.dev.js",
15+
"server-debug": "nodemon --inspect src/index.dev.js",
1616
"build": "cd src/public && webpack --config webpack.prod.js --progress --colors",
1717
"start:standalone": "cd src/public/dist/standalone && http-server",
1818
"pretty": "prettier --write \"./src/public/js/**/*.js\""

src/index.dev.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const server = require('../src/server');
2+
3+
const projectNameAlias = 'react-todo-example';
4+
const projectDir = `example-project/src`;
5+
const entryPoint = `example-project/src/index.js`;
6+
const webpackConfigPath = `example-project/webpack.config.js`;
7+
const clientPort = 2018;
8+
9+
const isDev = true;
10+
server.setup({ projectNameAlias, projectDir, entryPoint, webpackConfigPath, clientPort }, isDev);

src/public/dist/local/bundle/main.bundle.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46886,10 +46886,10 @@ module.exports = function(originalModule) {
4688646886
/*!**********************************************************!*\
4688746887
!*** /Users/bliashenko/Learning/codecrumbs/package.json ***!
4688846888
\**********************************************************/
46889-
/*! exports provided: name, version, author, license, repository, scripts, bin, dependencies, devDependencies, nodemonConfig, default */
46889+
/*! exports provided: name, version, author, license, repository, scripts, bin, dependencies, devDependencies, nodemonConfig, husky, default */
4689046890
/***/ (function(module) {
4689146891

46892-
module.exports = {"name":"codecrumbs","version":"1.0.12-alpha","author":"Bohdan Liashenko","license":"BSD-3-Clause","repository":{"type":"git","url":"https://github.com/Bogdan-Lyashenko/codecrumbs.git"},"scripts":{"start":"yarn client-dev & yarn server-dev","start:demo":"node ./index.dev.js","client-dev":"cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev","server-dev":"nodemon ./index.dev.js","server-debug":"nodemon --inspect ./index.dev.js","build":"cd src/public && webpack --config webpack.prod.js --progress --colors","start:standalone":"cd src/public/dist/standalone && http-server","pretty":"prettier --write \"./src/public/js/**/*.js\""},"bin":{"codecrumbs":"./cli/index.cli.js"},"dependencies":{"@babel/parser":"^7.1.2","@babel/polyfill":"^7.0.0","@babel/traverse":"^7.1.0","antd":"^3.9.2","chokidar":"^2.0.3","classnames":"^2.2.6","colors":"^1.3.2","commander":"^2.19.0","copy-text-to-clipboard":"^1.0.4","d3-flextree":"^2.1.1","directory-tree":"^2.1.0","file-saver":"^2.0.0","http-server":"^0.11.1","js2flowchart":"^1.1.7","lodash":"^4.17.10","lodash.debounce":"^4.0.8","madge":"^3.3.0","portscanner":"^2.2.0","react":"^16.7.0","react-dom":"^16.7.0","react-draggable":"^3.0.5","react-redux":"^5.0.7","react-syntax-highlighter":"8.0.1","redux":"^4.0.0","redux-persist":"^5.10.0","redux-saga":"^0.16.0","redux-thunk":"^2.2.0","reselect":"^4.0.0","websocket":"^1.0.26"},"devDependencies":{"@babel/core":"^7.1.2","@babel/plugin-syntax-dynamic-import":"^7.2.0","@babel/preset-env":"^7.1.0","@babel/preset-react":"^7.0.0","babel-loader":"^8.0.4","babel-plugin-import":"^1.9.1","css-loader":"^0.28.11","node-sass":"^4.9.3","nodemon":"^1.18.7","prettier":"^1.14.0","sass-loader":"^7.1.0","style-loader":"^0.21.0","webpack":"^4.20.2","webpack-bundle-analyzer":"^3.0.3","webpack-cli":"^3.1.2","webpack-merge":"^4.1.5"},"nodemonConfig":{"ignore":["src/public/**/*.*"],"delay":"2500"}};
46892+
module.exports = {"name":"codecrumbs","version":"1.0.12-alpha","author":"Bohdan Liashenko","license":"BSD-3-Clause","repository":{"type":"git","url":"https://github.com/Bogdan-Lyashenko/codecrumbs.git"},"scripts":{"start":"yarn client-dev & yarn server-dev","start:demo":"node ./index.dev.js","client-dev":"cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev","server-dev":"nodemon ./index.dev.js","server-debug":"nodemon --inspect ./index.dev.js","build":"cd src/public && webpack --config webpack.prod.js --progress --colors","start:standalone":"cd src/public/dist/standalone && http-server","pretty":"prettier --write \"./src/public/js/**/*.js\""},"bin":{"codecrumbs":"./cli/index.cli.js"},"dependencies":{"@babel/parser":"^7.1.2","@babel/polyfill":"^7.0.0","@babel/traverse":"^7.1.0","antd":"^3.9.2","chokidar":"^2.0.3","classnames":"^2.2.6","colors":"^1.3.2","commander":"^2.19.0","copy-text-to-clipboard":"^1.0.4","d3-flextree":"^2.1.1","directory-tree":"^2.1.0","file-saver":"^2.0.0","http-server":"^0.11.1","js2flowchart":"^1.1.7","lodash":"^4.17.10","lodash.debounce":"^4.0.8","madge":"^3.3.0","portscanner":"^2.2.0","react":"^16.7.0","react-dom":"^16.7.0","react-draggable":"^3.0.5","react-redux":"^5.0.7","react-syntax-highlighter":"8.0.1","redux":"^4.0.0","redux-persist":"^5.10.0","redux-saga":"^0.16.0","redux-thunk":"^2.2.0","reselect":"^4.0.0","websocket":"^1.0.26"},"devDependencies":{"@babel/core":"^7.1.2","@babel/plugin-syntax-dynamic-import":"^7.2.0","@babel/preset-env":"^7.1.0","@babel/preset-react":"^7.0.0","@commitlint/cli":"^7.3.2","@commitlint/config-conventional":"^7.3.1","babel-loader":"^8.0.4","babel-plugin-import":"^1.9.1","css-loader":"^0.28.11","husky":"^1.3.1","node-sass":"^4.9.3","nodemon":"^1.18.7","prettier":"^1.14.0","sass-loader":"^7.1.0","style-loader":"^0.21.0","webpack":"^4.20.2","webpack-bundle-analyzer":"^3.0.3","webpack-cli":"^3.1.2","webpack-merge":"^4.1.5"},"nodemonConfig":{"ignore":["src/public/**/*.*"],"delay":"2500"},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}}};
4689346893

4689446894
/***/ }),
4689546895

@@ -47677,6 +47677,14 @@ var createConnection = function createConnection(onMessage) {
4767747677
var route = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "ws://127.0.0.1:".concat(SERVER_PORT, "/");
4767847678
var ws = new WebSocket(route);
4767947679

47680+
ws.onopen = function () {
47681+
return console.log("Client connected to ".concat(route));
47682+
};
47683+
47684+
ws.onerror = function (error) {
47685+
return console.log("Connection error: ".concat(error));
47686+
};
47687+
4768047688
ws.onmessage = function (event) {
4768147689
onMessage(JSON.parse(event.data));
4768247690
};

src/public/js/core/dataBus/connection.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@ const { SERVER_PORT } = require('../../../../shared/constants');
33
export const createConnection = (onMessage, route = `ws://127.0.0.1:${SERVER_PORT}/`) => {
44
const ws = new WebSocket(route);
55

6-
ws.onopen = () => {
7-
// connection is opened and ready to use
8-
};
9-
10-
ws.onerror = error => {
11-
// an error occurred when sending/receiving data
12-
};
6+
ws.onopen = () => console.log(`Client connected to ${route}`);
7+
ws.onerror = error => console.log(`Connection error: ${error}`);
138

149
ws.onmessage = event => {
1510
onMessage(JSON.parse(event.data));

src/public/js/core/dataBus/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class DataBusContainer extends React.Component {
2222
}
2323

2424
setupLocal() {
25-
createConnection(({ type, data }) => this.onSocketEvent(type, data));
25+
createConnection(this.onSocketEvent.bind(this));
2626
}
2727

2828
handleInitSyncEvent(dataBody) {
@@ -35,7 +35,10 @@ class DataBusContainer extends React.Component {
3535
setChangedSourceData(dataBody);
3636
}
3737

38-
onSocketEvent(type, data) {
38+
onSocketEvent(event) {
39+
// TODO: pass sourceProjectId to action name
40+
const { type, data, sourceProjectId, sourceProjectName } = event;
41+
3942
switch (type) {
4043
case SOCKET_EVENT_TYPE.INIT_SOURCE_FILES_SYNC:
4144
return this.handleInitSyncEvent(data);

src/server/index.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@ const httpServer = require('http-server');
33

44
const { SERVER_PORT } = require('../shared/constants');
55
const mediator = require('./mediator');
6-
const sourceServer = require('./instance');
6+
const sourceWatcher = require('./source-watcher');
77

8-
const PORT_IN_USE = 'open';
9-
const HOST = '127.0.0.1';
8+
const setup = (
9+
{ projectNameAlias, projectDir, entryPoint, webpackConfigPath, clientPort },
10+
isDev
11+
) => {
12+
const PORT_IN_USE = 'open';
13+
const HOST = '127.0.0.1';
1014

11-
const setup = ({ projectDir, entryFile, webpackConfigFile, clientPort }, isDev) => {
1215
Promise.all([
1316
portscanner.checkPortStatus(clientPort, HOST).then(status => {
1417
if (status !== PORT_IN_USE) {
1518
/**
1619
* socket+http server for data exchange between browser and source servers
1720
*/
18-
mediator.run({ port: SERVER_PORT });
21+
mediator.run({ port: SERVER_PORT, clientPort });
1922
}
2023
}),
2124
portscanner.checkPortStatus(clientPort, HOST).then(status => {
@@ -31,18 +34,22 @@ const setup = ({ projectDir, entryFile, webpackConfigFile, clientPort }, isDev)
3134
}
3235
})
3336
]).then(() => {
34-
//sourceServer instances are same socket "client" as browser client
35-
//to communicate they need to send message to all, and filter by type
36-
3737
/**
3838
* source server instance (one per source code project)
3939
*/
40-
sourceServer.run(`${HOST}:${SERVER_PORT}`, {
41-
projectDir,
42-
entryFile,
43-
webpackConfigFile,
44-
clientPort
45-
});
40+
sourceWatcher.run(
41+
{
42+
mediatorEndPoint: `${HOST}:${SERVER_PORT}`,
43+
sourceProjectId: `source-project-${Date.now()}`,
44+
sourceProjectName: `project-${projectNameAlias || projectDir}`
45+
},
46+
{
47+
projectDir,
48+
entryPoint,
49+
webpackConfigPath,
50+
clientPort
51+
}
52+
);
4653
});
4754
};
4855

src/server/instance.js

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/server/mediator.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,46 @@ const WebSocketServer = require('websocket').server;
22
const http = require('http');
33

44
// instances should run on many ports but then send data to mediator and mediator to client
5-
const run = ({ port }) => {
5+
const run = ({ port, clientPort }) => {
66
const httpServer = http.createServer((request, response) => {
7-
console.log('http call to mediator', request.url);
7+
// TODO: refactor this to work with sockets instead
88
});
99

10-
httpServer.listen(port, () => {
11-
console.log(`Mediator server is listening: ${port}.`);
12-
});
10+
httpServer.listen(port, () => console.log(`Mediator server is listening: ${port}.`));
11+
12+
let clientInstance = null;
13+
const sendToClient = event => clientInstance && clientInstance.sendUTF(event);
14+
const sourceWatcherInstances = [];
15+
const sendToSourceWatchers = event => sourceWatcherInstances.forEach(l => l.sendUTF(event));
1316

1417
const webSocketServer = new WebSocketServer({ httpServer });
1518
webSocketServer.on('request', request => {
1619
const connection = request.accept(null, request.origin);
17-
18-
console.log('some client connects to mediator');
19-
20-
connection.on('message', message => {
21-
if (message.type === 'utf8') {
22-
//console.log('mediator received msg', message.utf8Data)
23-
}
20+
const isClient = request.origin && request.origin.includes(`:${clientPort}`);
21+
22+
if (isClient) {
23+
clientInstance = connection;
24+
console.log('Client connected. Sending source...');
25+
sendToSourceWatchers(
26+
JSON.stringify({
27+
type: 'CLIENT_CONNECTED'
28+
})
29+
);
30+
} else {
31+
sourceWatcherInstances.push(connection);
32+
}
33+
34+
connection.on('message', ({ utf8Data }) => {
35+
const sendAnswer = isClient ? sendToSourceWatchers : sendToClient;
36+
sendAnswer(utf8Data);
2437
});
2538

26-
connection.on('close', connection => {
27-
// close user connection
39+
connection.on('close', () => {
40+
const sourceWatcherIndex = sourceWatcherInstances.findIndex(watcher => !watcher.connected);
41+
if (sourceWatcherIndex !== -1) {
42+
sourceWatcherInstances.splice(sourceWatcherIndex, 1);
43+
}
2844
});
29-
30-
connection.sendUTF(
31-
JSON.stringify({
32-
type: 'connected!'
33-
})
34-
);
3545
});
3646
};
3747

0 commit comments

Comments
 (0)