redux-cluster-ws 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FUNDING.yml +7 -0
- package/LICENSE +21 -21
- package/README.md +394 -90
- package/dist/cjs/client.d.ts +43 -0
- package/dist/cjs/client.js +276 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/server.d.ts +31 -0
- package/dist/cjs/server.js +295 -0
- package/dist/cjs/server.js.map +1 -0
- package/dist/cjs/types.d.ts +83 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +17 -0
- package/dist/cjs/utils.js +75 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/client.d.ts +43 -0
- package/dist/esm/client.js +282 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/server.d.ts +31 -0
- package/dist/esm/server.js +299 -0
- package/dist/esm/server.js.map +1 -0
- package/dist/esm/types.d.ts +83 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +17 -0
- package/dist/esm/utils.js +69 -0
- package/dist/esm/utils.js.map +1 -0
- package/eslint.config.js +143 -0
- package/examples/browser-example.cjs +350 -0
- package/examples/browser.html +255 -0
- package/examples/client.cjs +155 -0
- package/examples/cross-library-browser.html +655 -0
- package/examples/cross-library-client.cjs +190 -0
- package/examples/cross-library-server.cjs +213 -0
- package/examples/server.cjs +96 -0
- package/package.json +96 -23
- package/client.js +0 -192
- package/index.js +0 -12
- package/server.js +0 -175
- package/test.auto.proc1.js +0 -100
- package/test.auto.proc2.js +0 -74
- package/test.visual.client.html +0 -37
- package/test.visual.client.js +0 -63
- package/test.visual.server.js +0 -66
- package/umd/ReduxCluster.js +0 -18
- package/webpack-src.js +0 -6
- package/webpack.config.js +0 -25
package/client.js
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster-WS
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* Websocket (socket.io) Client wrapper for redux-cluster
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
var Crypto = require('crypto-browserify'),
|
|
12
|
-
SocketIOClient = require('socket.io-client'),
|
|
13
|
-
Redux = require('redux'),
|
|
14
|
-
Lodash = require('lodash');
|
|
15
|
-
|
|
16
|
-
var ReduxClusterModule = {}; //модуль
|
|
17
|
-
Object.assign(ReduxClusterModule, Redux); //копирую свойства Redux
|
|
18
|
-
var reducers = {}; //список редьюсеров (хэш собирается по имени редьюсера для совместимости различных ОС, т.к. hasher(<function>.toString()) для разных ос дает разные суммы)
|
|
19
|
-
|
|
20
|
-
//хэширование паролей
|
|
21
|
-
function hasher(data){
|
|
22
|
-
if(typeof(data) === 'string'){
|
|
23
|
-
const hash = Crypto.createHash('sha1');
|
|
24
|
-
hash.update(data);
|
|
25
|
-
return(hash.digest('hex'));
|
|
26
|
-
} else
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
//функция замены "." на "_" и обратно
|
|
31
|
-
function replacer(data_val, value_val){
|
|
32
|
-
if(typeof(data_val) === 'string'){
|
|
33
|
-
if(value_val){
|
|
34
|
-
return data_val.replace(/\./gi,"_");
|
|
35
|
-
} else {
|
|
36
|
-
return data_val.replace(/\_/gi,".");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function ReduxCluster(_reducer){
|
|
42
|
-
let self = this;
|
|
43
|
-
self.stderr = console.error; //callback для ошибок
|
|
44
|
-
self.role = []; //роль
|
|
45
|
-
self.mode = "action"; //тип синхронизации по умолчанию
|
|
46
|
-
self.connected = true; //статус соединения
|
|
47
|
-
self.resync = 1000; //количество действий для пересинхронизации
|
|
48
|
-
self.RCHash = hasher(_reducer.name); //создаю метку текущего редьюсера для каждого экземпляра
|
|
49
|
-
self.version = require('./package.json').version; //версия пакета
|
|
50
|
-
self.homepage = require('./package.json').homepage; //домашняя страница пакета
|
|
51
|
-
self.altReducer = _reducer; //оригинальный редьюсер
|
|
52
|
-
if(typeof(reducers[_reducer.name]) === 'undefined'){
|
|
53
|
-
reducers[_reducer.name] = self.RCHash;
|
|
54
|
-
} else {
|
|
55
|
-
throw new Error("Please don't use a reducer with the same name!");
|
|
56
|
-
}
|
|
57
|
-
try{
|
|
58
|
-
let _d = self.altReducer(undefined, {}); //получаю значение state при старте
|
|
59
|
-
if(typeof(_d) === 'object'){
|
|
60
|
-
self.defaulstate = _d;
|
|
61
|
-
} else {
|
|
62
|
-
throw new Error('The returned value is not an object.');
|
|
63
|
-
}
|
|
64
|
-
} catch(e){
|
|
65
|
-
self.defaulstate = {};
|
|
66
|
-
};
|
|
67
|
-
self.newReducer = function(state=self.defaulstate, action){ //собственный редьюсер
|
|
68
|
-
if (action.type === 'REDUX_CLUSTER_SYNC'){
|
|
69
|
-
let state_new = Lodash.clone(action.payload);
|
|
70
|
-
return state_new;
|
|
71
|
-
} else {
|
|
72
|
-
return self.altReducer(state, action);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
Object.assign(self, Redux.createStore(self.newReducer)); //создаю хранилище с собственным редьюсером
|
|
76
|
-
delete self.replaceReducer; //удаляю замену редьюсера
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function createWSClient(store, config){ //функция создания клиента
|
|
80
|
-
let self = this;
|
|
81
|
-
if(typeof(config) !== 'object'){
|
|
82
|
-
throw new Error('Argument requires configuration object!');
|
|
83
|
-
} else if(typeof(config.host) !== 'string') {
|
|
84
|
-
throw new Error('Config requires server address!');
|
|
85
|
-
} else if((typeof(config.port) !== 'string') && (typeof(config.port) !== 'number')) {
|
|
86
|
-
config.port = 10002;
|
|
87
|
-
}
|
|
88
|
-
self.store = store;
|
|
89
|
-
if(!((typeof(config.login) === 'string') || (self.store && self.store.client && self.store.client.login))) {
|
|
90
|
-
throw new Error('Config requires login for server authorization!');
|
|
91
|
-
} else if(!((typeof(config.password) === 'string') || (self.store && self.store.client && self.store.client.password))) {
|
|
92
|
-
throw new Error('Config requires password for server authorization!');
|
|
93
|
-
}
|
|
94
|
-
self.store.dispatchNEW = self.store.dispatch; //переопределяю dispatch
|
|
95
|
-
delete self.store.dispatch;
|
|
96
|
-
self.config = Object.assign(config);
|
|
97
|
-
if(self.store && self.store.client){ //подтягиваю логин и пароль из store (для реализации кастомной авторизации)
|
|
98
|
-
if(self.store.client.login){ self.login = self.store.client.login; }
|
|
99
|
-
if(self.store.client.password){ self.password = self.store.client.password; }
|
|
100
|
-
} else {
|
|
101
|
-
self.login = hasher("REDUX_CLUSTER"+self.config.login);
|
|
102
|
-
self.password = hasher("REDUX_CLUSTER"+self.config.password);
|
|
103
|
-
}
|
|
104
|
-
self.reconnect = function(){
|
|
105
|
-
try {
|
|
106
|
-
let socket;
|
|
107
|
-
if(self.config.host.toLowerCase().indexOf('https://') !== -1){
|
|
108
|
-
socket = new SocketIOClient.connect(self.config.host + ':' + self.config.port, { secure: true, transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
109
|
-
} else {
|
|
110
|
-
socket = new SocketIOClient.connect(self.config.host + ':' + self.config.port, {transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
111
|
-
}
|
|
112
|
-
self.socket = socket;
|
|
113
|
-
socket.on('connect_error', (error) => {
|
|
114
|
-
if(error.description && error.description.message){
|
|
115
|
-
let err = error.description;
|
|
116
|
-
self.store.stderr('ReduxCluster.createWSClient connect error: '+error.message+' ->'+err.message);
|
|
117
|
-
} else {
|
|
118
|
-
self.store.stderr('ReduxCluster.createWSClient connect error: '+error.message);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
socket.on('error', (error) => {
|
|
122
|
-
if(error.description && error.description.message){
|
|
123
|
-
let err = error.description;
|
|
124
|
-
self.store.stderr('ReduxCluster.createWSClient client error: '+error.message+' ->'+err.message);
|
|
125
|
-
} else {
|
|
126
|
-
self.store.stderr('ReduxCluster.createWSClient client error: '+error.message);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
socket.on('connect', () => {
|
|
130
|
-
socket.emit('RCMSG', {_msg:'REDUX_CLUSTER_SOCKET_AUTH', _hash:self.store.RCHash, _login:self.login, _password:self.password}); //авторизация в сокете
|
|
131
|
-
});
|
|
132
|
-
socket.on('RCMSG', function (data) {
|
|
133
|
-
if(data._hash === self.store.RCHash){
|
|
134
|
-
switch(data._msg){
|
|
135
|
-
case 'REDUX_CLUSTER_MSGTOWORKER':
|
|
136
|
-
self.store.dispatchNEW(data._action);
|
|
137
|
-
break;
|
|
138
|
-
case 'REDUX_CLUSTER_SOCKET_AUTHSTATE':
|
|
139
|
-
if(data._value === true){
|
|
140
|
-
socket.emit('RCMSG', {_msg:'REDUX_CLUSTER_START', _hash:self.store.RCHash}); //синхронизирую хранилище
|
|
141
|
-
self.store.connected = true;
|
|
142
|
-
}else{
|
|
143
|
-
if(data._banned)
|
|
144
|
-
socket.disconnect(new Error('your ip is locked for 3 hours'));
|
|
145
|
-
else
|
|
146
|
-
socket.disconnect(new Error('authorization failed'));
|
|
147
|
-
}
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
} catch(err){
|
|
153
|
-
self.store.stderr('ReduxCluster.createWSClient client error: '+err.message)
|
|
154
|
-
self.store.connected = false;
|
|
155
|
-
setTimeout(self.reconnect, 10000);
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
self.store.dispatch = function(_data){
|
|
159
|
-
try{
|
|
160
|
-
self.socket.emit('RCMSG', {_msg:'REDUX_CLUSTER_MSGTOMASTER', _hash:self.store.RCHash, _action:_data});
|
|
161
|
-
} catch(err){
|
|
162
|
-
self.store.stderr('ReduxCluster.createWSClient write error: '+err.message);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
self.reconnect();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function createStore(_reducer){ //функция создания хранилища
|
|
169
|
-
let _ReduxCluster = new ReduxCluster(_reducer); //создаю экземпляр хранилища
|
|
170
|
-
_ReduxCluster.createWSClient = function(_settings){ //подключаю объект создания клиента
|
|
171
|
-
if(_ReduxCluster.role.indexOf("client") === -1) { _ReduxCluster.role.push("client"); } else {
|
|
172
|
-
throw new Error('One storage cannot be connected to two servers at the same time.');
|
|
173
|
-
}
|
|
174
|
-
_ReduxCluster.connected = false;
|
|
175
|
-
return new createWSClient(_ReduxCluster, _settings);
|
|
176
|
-
}
|
|
177
|
-
return _ReduxCluster;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
ReduxClusterModule.createStore = createStore; //переопределяю функцию создания хранилища
|
|
181
|
-
|
|
182
|
-
ReduxClusterModule.functions = {
|
|
183
|
-
replacer: replacer,
|
|
184
|
-
hasher: hasher,
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
ReduxClusterModule.Lodash = Lodash;
|
|
188
|
-
ReduxClusterModule.SocketIOClient = SocketIOClient;
|
|
189
|
-
ReduxClusterModule.Crypto = Crypto;
|
|
190
|
-
ReduxClusterModule.Redux = Redux;
|
|
191
|
-
|
|
192
|
-
module.exports = ReduxClusterModule;
|
package/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster-WS
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* Websocket (socket.io) Client and Server wrapper for redux-cluster
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
module.exports.server = require('./server.js');
|
|
12
|
-
module.exports.client = require('./client.js');
|
package/server.js
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster-WS
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* Websocket (socket.io) Server wrapper for redux-cluster
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
var Http = require('http'),
|
|
12
|
-
Https = require('https'),
|
|
13
|
-
SocketIO = require('socket.io'),
|
|
14
|
-
Fs = require('fs'),
|
|
15
|
-
Crypto = require('crypto'),
|
|
16
|
-
ReduxCluster = require('redux-cluster');
|
|
17
|
-
|
|
18
|
-
function ReduxClusterWsWrapper(store){
|
|
19
|
-
let self = this;
|
|
20
|
-
self.store = store; //постоянная ссылка на магазин
|
|
21
|
-
self.uid = ReduxCluster.functions.generateUID();
|
|
22
|
-
self.ip2ban = {}; //база данных блокнутых ip
|
|
23
|
-
self.ip2banAttemp = 15; //количество попыток ввода пароля
|
|
24
|
-
self.ip2banTimeout = 10800000; //время блокировки в мс, при срабатывании лимита попыток
|
|
25
|
-
self.database = {}; //база данных авторизации
|
|
26
|
-
self.sockets = {}; //авторизованные сокеты
|
|
27
|
-
self.timeout = 30000;
|
|
28
|
-
self.config = {host: '0.0.0.0', port: 10002}; //дефолтные настройки сервера
|
|
29
|
-
if((store instanceof ReduxCluster.createStore)) { //проверяю переданный объект
|
|
30
|
-
throw new Error('Argument requires redux-cluster store!');
|
|
31
|
-
} else if (store.version < '1.5'){
|
|
32
|
-
throw new Error('Please update you redux-cluster library up to version 1.5.0 or great! '+self.store.homepage);
|
|
33
|
-
}
|
|
34
|
-
store.createWSServer = function(config){
|
|
35
|
-
self.ip2banGCStart = setInterval(function(){
|
|
36
|
-
for(const key in self.ip2ban){
|
|
37
|
-
if((self.ip2ban[key].time+self.ip2banTimeout) < Date.now()){
|
|
38
|
-
delete self.ip2ban[key];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}, 60000);
|
|
42
|
-
self.ip2banGCStop = function(){ clearInterval(self.ip2banGCStart); }
|
|
43
|
-
self.sendtoall = function(_message){
|
|
44
|
-
if(self.io instanceof SocketIO){
|
|
45
|
-
if(typeof(_message) === 'object'){
|
|
46
|
-
for(const uid in self.sockets){
|
|
47
|
-
try{
|
|
48
|
-
if(self.sockets[uid] && (typeof(self.sockets[uid].emit) === 'function'))
|
|
49
|
-
self.sockets[uid].emit("RCMSG", _message);
|
|
50
|
-
} catch(err){
|
|
51
|
-
self.store.stderr('ReduxCluster.createWSServer write error: '+err.message);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
for(const uid in self.sockets){
|
|
56
|
-
try{
|
|
57
|
-
if(self.sockets[uid] && (typeof(self.sockets[uid].emit) === 'function'))
|
|
58
|
-
self.sockets[uid].emit("RCMSG", {_msg:"REDUX_CLUSTER_MSGTOWORKER", _hash:self.store.RCHash, _action:{type:"REDUX_CLUSTER_SYNC", payload:self.store.getState()}});
|
|
59
|
-
} catch(err){
|
|
60
|
-
self.store.stderr('ReduxCluster.createWSServer write error: '+err.message);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
self.unsubscribe = self.store.subscribe(function(){ //подписываю сокет на изменения Redux только в режиме snapshot
|
|
67
|
-
if(self.store.mode === "snapshot")
|
|
68
|
-
self.sendtoall();
|
|
69
|
-
});
|
|
70
|
-
self.store.allsock[self.uid] = self;
|
|
71
|
-
if(self.store.role.indexOf("server") === -1) { self.store.role.push("server"); }
|
|
72
|
-
if(typeof(config) === 'object'){
|
|
73
|
-
self.config = Object.assign(config);
|
|
74
|
-
}
|
|
75
|
-
if(typeof(self.config.logins) === 'object')
|
|
76
|
-
for(const login in self.config.logins){ self.database[ReduxCluster.functions.hasher("REDUX_CLUSTER"+login)] = ReduxCluster.functions.hasher("REDUX_CLUSTER"+self.config.logins[login]); }
|
|
77
|
-
if(typeof(self.config.server) === 'undefined'){
|
|
78
|
-
if(self.config.ssl && self.config.ssl.crt && self.config.ssl.ca && self.config.ssl.key){ //формирую сертификат сервера
|
|
79
|
-
self.ssl = {
|
|
80
|
-
key: ''+Fs.readFileSync(self.config.ssl.key),
|
|
81
|
-
cert: Fs.readFileSync(self.config.ssl.crt) + '\n' + Fs.readFileSync(self.config.ssl.ca)
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
if(self.ssl){
|
|
85
|
-
self.server = new Https.createServer(ssl, undefined).setTimeout(self.timeout).listen(self.config.port, self.config.host);
|
|
86
|
-
self.io = new SocketIO(self.server, { log: true ,pingTimeout: 7200000, pingInterval: 25000, secure:true, transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
87
|
-
} else{
|
|
88
|
-
self.server = new Http.createServer(undefined).setTimeout(self.timeout).listen(self.config.port, self.config.host);
|
|
89
|
-
self.io = new SocketIO(self.server, { log: true ,pingTimeout: 7200000, pingInterval: 25000, transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
90
|
-
}
|
|
91
|
-
} else if (self.config.server instanceof Http.Server){
|
|
92
|
-
self.server = self.config.server;
|
|
93
|
-
self.io = new SocketIO(self.server, { log: true ,pingTimeout: 7200000, pingInterval: 25000, transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
94
|
-
} else if (self.config.server instanceof Https.Server){
|
|
95
|
-
self.server = self.config.server;
|
|
96
|
-
self.io = new SocketIO(self.server, { log: true ,pingTimeout: 7200000, pingInterval: 25000, secure:true, transports: ['websocket'], path: "/redux-cluster-"+self.store.RCHash});
|
|
97
|
-
} else {
|
|
98
|
-
throw new Error('Server instanse is not supported library! Please use http/https native library.');
|
|
99
|
-
}
|
|
100
|
-
self.io.engine.generateId = ReduxCluster.functions.generateUID;
|
|
101
|
-
self.io.sockets.on('connection', function (socket) {
|
|
102
|
-
try{
|
|
103
|
-
let thisSocketAddressArr = self.io.sockets.sockets[socket.id].handshake.address.split(':');
|
|
104
|
-
let _i2bTest = ReduxCluster.functions.replacer(thisSocketAddressArr[thisSocketAddressArr.length-1], true);
|
|
105
|
-
if((typeof(_i2bTest) === 'undefined') || (typeof(self.ip2ban[_i2bTest]) === 'undefined') || ((typeof(self.ip2ban[_i2bTest]) === 'object') && ((self.ip2ban[_i2bTest].count < self.ip2banAttemp) || ((self.ip2ban[_i2bTest].time+self.ip2banTimeout) < Date.now())))){
|
|
106
|
-
socket.on('RCMSG', function(data){
|
|
107
|
-
if(data._hash === self.store.RCHash){ //проверяю что сообщение привязано к текущему хранилищу
|
|
108
|
-
switch(data._msg){
|
|
109
|
-
case 'REDUX_CLUSTER_MSGTOMASTER': //получаю диспатчер от клиента
|
|
110
|
-
if((typeof(socket.id) !== 'undefined') && (typeof(self.sockets[socket.id]) !== 'undefined')){
|
|
111
|
-
if(data._action.type === 'REDUX_CLUSTER_SYNC')
|
|
112
|
-
throw new Error("Please don't use REDUX_CLUSTER_SYNC action type!");
|
|
113
|
-
self.store.dispatch(data._action);
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
case 'REDUX_CLUSTER_START': //получаю метку, что клиент запущен
|
|
117
|
-
if((typeof(socket.id) !== 'undefined') && (typeof(self.sockets[socket.id]) !== 'undefined')){
|
|
118
|
-
self.sockets[socket.id].emit('RCMSG', {_msg:"REDUX_CLUSTER_MSGTOWORKER", _hash:self.store.RCHash, _action:{type:"REDUX_CLUSTER_SYNC", payload:self.store.getState()}});
|
|
119
|
-
}
|
|
120
|
-
break;
|
|
121
|
-
case 'REDUX_CLUSTER_SOCKET_AUTH':
|
|
122
|
-
if( (typeof(data._login) !== 'undefined') &&
|
|
123
|
-
(typeof(data._password) !== 'undefined') &&
|
|
124
|
-
(typeof(self.database[data._login]) !== 'undefined') &&
|
|
125
|
-
(self.database[data._login] === data._password)){
|
|
126
|
-
self.sockets[socket.id] = socket;
|
|
127
|
-
if((typeof(_i2bTest) === 'string') && (typeof(self.ip2ban[_i2bTest]) === 'object')) { delete self.ip2ban[_i2bTest]; } //если логин присутствует в таблице забаненных удаляю
|
|
128
|
-
self.sockets[socket.id].emit('RCMSG', {_msg:"REDUX_CLUSTER_SOCKET_AUTHSTATE", _hash:self.store.RCHash, _value:true});
|
|
129
|
-
} else {
|
|
130
|
-
if(typeof(_i2bTest) === 'string') {
|
|
131
|
-
let _tempCount = 0;
|
|
132
|
-
if(typeof(self.ip2ban[_i2bTest]) === 'object'){
|
|
133
|
-
_tempCount = self.ip2ban[_i2bTest].count;
|
|
134
|
-
if(_tempCount >= self.ip2banAttemp) { _tempCount = 0; } //по таймауту сбрасываю счетчик попыток
|
|
135
|
-
}
|
|
136
|
-
self.ip2ban[_i2bTest] = {time: Date.now(), count:_tempCount+1};
|
|
137
|
-
}
|
|
138
|
-
socket.emit('RCMSG', {_msg:"REDUX_CLUSTER_SOCKET_AUTHSTATE", _hash:self.store.RCHash, _value:false});
|
|
139
|
-
if(typeof(socket.disconnect) === 'function'){
|
|
140
|
-
socket.disconnect();
|
|
141
|
-
}
|
|
142
|
-
if((typeof(socket.id) !== 'undefined') && (typeof(self.sockets[socket.id]) !== 'undefined')){
|
|
143
|
-
delete self.sockets[socket.id];
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
} else {
|
|
151
|
-
socket.emit('RCMSG', {_msg:"REDUX_CLUSTER_SOCKET_AUTHSTATE", _hash:self.store.RCHash, _value:false, _banned: true});
|
|
152
|
-
if(typeof(socket.disconnect) === 'function'){
|
|
153
|
-
socket.disconnect();
|
|
154
|
-
}
|
|
155
|
-
if((typeof(socket.id) !== 'undefined') && (typeof(self.sockets[socket.id]) !== 'undefined')){
|
|
156
|
-
delete self.sockets[socket.id];
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
} catch(err){
|
|
160
|
-
self.store.stderr('ReduxCluster.createWSServer socket error: '+err.message);
|
|
161
|
-
if(typeof(socket.disconnect) === 'function'){
|
|
162
|
-
socket.disconnect();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
socket.on('error', function(err){
|
|
166
|
-
self.store.stderr('ReduxCluster.createWSServer read error: '+err.message);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
module.exports = function(store){
|
|
173
|
-
new ReduxClusterWsWrapper(store);
|
|
174
|
-
return store;
|
|
175
|
-
};
|
package/test.auto.proc1.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster Test
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* standart test (cluster IPC channel)
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
var ReduxCluster = require('redux-cluster'),
|
|
12
|
-
Cluster = require('cluster'),
|
|
13
|
-
Lodash = require('lodash'),
|
|
14
|
-
Colors = require('colors');
|
|
15
|
-
|
|
16
|
-
function editProcessStorage(state = {versions:[]}, action){
|
|
17
|
-
try {
|
|
18
|
-
switch (action.type){
|
|
19
|
-
case 'TASK':
|
|
20
|
-
var state_new = Lodash.clone(state);
|
|
21
|
-
if(state_new.versions.length > 500){
|
|
22
|
-
state_new.versions.splice(0,100);
|
|
23
|
-
}
|
|
24
|
-
state_new.versions.push(action.payload.version);
|
|
25
|
-
return state_new;
|
|
26
|
-
break;
|
|
27
|
-
default:
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
} catch(e){
|
|
31
|
-
}
|
|
32
|
-
var state_new = Lodash.clone(state);
|
|
33
|
-
return state_new;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function editProcessStorage2(state = {versions:[]}, action){
|
|
37
|
-
try {
|
|
38
|
-
switch (action.type){
|
|
39
|
-
case 'UPDATE':
|
|
40
|
-
var state_new = Lodash.clone(state);
|
|
41
|
-
state_new.versions = action.payload.versions;
|
|
42
|
-
return state_new;
|
|
43
|
-
break;
|
|
44
|
-
default:
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
} catch(e){
|
|
48
|
-
}
|
|
49
|
-
var state_new = Lodash.clone(state);
|
|
50
|
-
return state_new;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var Test = ReduxCluster.createStore(editProcessStorage);
|
|
55
|
-
require('./index.js').server(Test);
|
|
56
|
-
Test.mode = "snapshot";
|
|
57
|
-
var Test2 = ReduxCluster.createStore(editProcessStorage2);
|
|
58
|
-
require('./index.js').server(Test2);
|
|
59
|
-
Test2.mode = 'snapshot';
|
|
60
|
-
|
|
61
|
-
if(Cluster.isMaster){
|
|
62
|
-
Test.backup({count:1, path:"./test1.backup", key:"test"}).finally(function(){
|
|
63
|
-
Test.createWSServer({host: "0.0.0.0", port: 8888, logins:{test:'123456'}});
|
|
64
|
-
Test2.createClient({host: "localhost", port: 8889, login:"test2", password:'123456'});
|
|
65
|
-
|
|
66
|
-
setTimeout(function(){Cluster.fork();}, i*20000);
|
|
67
|
-
|
|
68
|
-
Test.dispatch({type:'TASK', payload: {version:'MasterTest0'}});
|
|
69
|
-
var i = 0;
|
|
70
|
-
setInterval(function(){
|
|
71
|
-
Test.dispatch({type:'TASK', payload: {version:'MasterTest'+i}});
|
|
72
|
-
i++;
|
|
73
|
-
}, 1021);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
} else {
|
|
77
|
-
|
|
78
|
-
Test.dispatch({type:'TASK', payload: {version:'WorkerTest0'}});
|
|
79
|
-
var i = 0;
|
|
80
|
-
setInterval(function(){
|
|
81
|
-
Test.dispatch({type:'TASK', payload: {version:'WorkerTest'+i}});
|
|
82
|
-
i++;
|
|
83
|
-
}, 505, i);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if(!Cluster.isMaster){
|
|
87
|
-
var ok = 0;
|
|
88
|
-
var bad = 0;
|
|
89
|
-
setInterval(function(){
|
|
90
|
-
if(Lodash.isEqual(Test.getState().versions, Test2.getState().versions)){
|
|
91
|
-
ok++;
|
|
92
|
-
console.log(Colors.green("ok-"+ok+'|'+parseInt((ok*100/(ok+bad)), 10)+'%'));
|
|
93
|
-
}else {
|
|
94
|
-
bad++;
|
|
95
|
-
console.log(Colors.red("bad-"+bad+'|'+parseInt((bad*100/(ok+bad)), 10)+'%'));
|
|
96
|
-
console.log(Test.getState().versions.length+' | '+Test2.getState().versions.length)
|
|
97
|
-
console.log(Test.getState().versions[Test.getState().versions.length-1]+' | '+ Test2.getState().versions[Test2.getState().versions.length-1] );
|
|
98
|
-
}
|
|
99
|
-
}, 1030);
|
|
100
|
-
}
|
package/test.auto.proc2.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster Test
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* standart test (cluster IPC channel)
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
var ReduxCluster = require('redux-cluster'),
|
|
12
|
-
ReduxClusterWS = require('./client.js'),
|
|
13
|
-
Cluster = require('cluster'),
|
|
14
|
-
Lodash = require('lodash'),
|
|
15
|
-
Colors = require('colors');
|
|
16
|
-
|
|
17
|
-
function editProcessStorage(state = {versions:[]}, action){
|
|
18
|
-
try {
|
|
19
|
-
switch (action.type){
|
|
20
|
-
case 'TASK':
|
|
21
|
-
var state_new = Lodash.clone(state);
|
|
22
|
-
if(state_new.versions.length > 500){
|
|
23
|
-
state_new.versions.splice(0,100);
|
|
24
|
-
}
|
|
25
|
-
state_new.versions.push(action.payload.version);
|
|
26
|
-
return state_new;
|
|
27
|
-
break;
|
|
28
|
-
default:
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
} catch(e){
|
|
32
|
-
}
|
|
33
|
-
var state_new = Lodash.clone(state);
|
|
34
|
-
return state_new;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function editProcessStorage2(state = {versions:[]}, action){
|
|
38
|
-
try {
|
|
39
|
-
switch (action.type){
|
|
40
|
-
case 'UPDATE':
|
|
41
|
-
var state_new = Lodash.clone(state);
|
|
42
|
-
state_new.versions = action.payload.versions;
|
|
43
|
-
return state_new;
|
|
44
|
-
break;
|
|
45
|
-
default:
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
} catch(e){
|
|
49
|
-
}
|
|
50
|
-
var state_new = Lodash.clone(state);
|
|
51
|
-
return state_new;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
var Test = ReduxClusterWS.createStore(editProcessStorage);
|
|
56
|
-
Test.mode = "action";
|
|
57
|
-
var Test2 = ReduxCluster.createStore(editProcessStorage2);
|
|
58
|
-
Test2.mode = "snapshot";
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Test2.backup({count:1, path:"./test2.backup", key:"test"}).finally(function(){
|
|
62
|
-
Test.createWSClient({host: "http://localhost", port: 8888, login:"test", password:'123456'});
|
|
63
|
-
Test.dispatch({type:'TASK', payload: {version:'MasterRemote0'}});
|
|
64
|
-
var i = 0;
|
|
65
|
-
setInterval(function(){
|
|
66
|
-
Test.dispatch({type:'TASK', payload: {version:'MasterRemote'+i}});
|
|
67
|
-
i++;
|
|
68
|
-
}, 1010);
|
|
69
|
-
|
|
70
|
-
Test2.createServer({host: "0.0.0.0", port: 8889, logins:{test2:'123456'}});
|
|
71
|
-
Test.subscribe(function(){
|
|
72
|
-
Test2.dispatch({type:'UPDATE', payload: {versions:Test.getState().versions}});
|
|
73
|
-
});
|
|
74
|
-
});
|
package/test.visual.client.html
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
<html>
|
|
2
|
-
<head>
|
|
3
|
-
<meta charset=utf-8 />
|
|
4
|
-
<script src="./umd/ReduxCluster.js"></script>
|
|
5
|
-
</head>
|
|
6
|
-
<body>
|
|
7
|
-
<script>
|
|
8
|
-
function editProcessStorage(state = {version:''}, action){
|
|
9
|
-
try {
|
|
10
|
-
switch (action.type){
|
|
11
|
-
case 'TASK':
|
|
12
|
-
var state_new = Object.assign(state);
|
|
13
|
-
state_new.version = action.payload.version;
|
|
14
|
-
return state_new;
|
|
15
|
-
break;
|
|
16
|
-
default:
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
} catch(e){
|
|
20
|
-
}
|
|
21
|
-
var state_new = Object.assign(state);
|
|
22
|
-
return state_new;
|
|
23
|
-
}
|
|
24
|
-
var Test = ReduxCluster.createStore(editProcessStorage);
|
|
25
|
-
Test.createWSClient({host: "http://localhost", port: 8888, login:"test2", password:'123456'});
|
|
26
|
-
Test.subscribe(function(){
|
|
27
|
-
console.log(Test.getState());
|
|
28
|
-
});
|
|
29
|
-
Test.dispatch({type:'TASK', payload: {version:'OneRemoteMasterTest0'}});
|
|
30
|
-
var i = 0;
|
|
31
|
-
setInterval(function(){
|
|
32
|
-
Test.dispatch({type:'TASK', payload: {version:'OneRemoteMasterTest'+i}});
|
|
33
|
-
i++;
|
|
34
|
-
}, 1100);
|
|
35
|
-
</script>
|
|
36
|
-
</body>
|
|
37
|
-
</html>
|
package/test.visual.client.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redux-Cluster Test
|
|
3
|
-
* (c) 2018 by Siarhei Dudko.
|
|
4
|
-
*
|
|
5
|
-
* standart test, include test Socket IPC and TCP (remote) client
|
|
6
|
-
* LICENSE MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict"
|
|
10
|
-
|
|
11
|
-
var ReduxClusterWS = require('./client.js'),
|
|
12
|
-
Cluster = require('cluster'),
|
|
13
|
-
Lodash = require('lodash');
|
|
14
|
-
|
|
15
|
-
var Test = ReduxClusterWS.createStore(editProcessStorage);
|
|
16
|
-
|
|
17
|
-
if(Cluster.isMaster){
|
|
18
|
-
Test.createWSClient({host: "http://localhost", port: 8888, login:"test2", password:'123456'});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function editProcessStorage(state = {version:''}, action){
|
|
22
|
-
try {
|
|
23
|
-
switch (action.type){
|
|
24
|
-
case 'TASK':
|
|
25
|
-
var state_new = Lodash.clone(state);
|
|
26
|
-
state_new.version = action.payload.version;
|
|
27
|
-
return state_new;
|
|
28
|
-
break;
|
|
29
|
-
default:
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
} catch(e){
|
|
33
|
-
}
|
|
34
|
-
var state_new = Lodash.clone(state);
|
|
35
|
-
return state_new;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
Test.subscribe(function(){
|
|
39
|
-
if(Cluster.isMaster){
|
|
40
|
-
var name = 'm';
|
|
41
|
-
} else {
|
|
42
|
-
var name = Cluster.worker.id;
|
|
43
|
-
}
|
|
44
|
-
console.log(' S1 | ' + name + ' | ' + JSON.stringify(Test.getState()));
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
if(Cluster.isMaster){
|
|
48
|
-
for(var i=0; i < 2; i++){
|
|
49
|
-
//setTimeout(function(){Cluster.fork();}, i*10000);
|
|
50
|
-
}
|
|
51
|
-
Test.dispatch({type:'TASK', payload: {version:'OneRemoteMasterTest0'}});
|
|
52
|
-
var i = 0;
|
|
53
|
-
setInterval(function(){
|
|
54
|
-
Test.dispatch({type:'TASK', payload: {version:'OneRemoteMasterTest'+i}});
|
|
55
|
-
i++;
|
|
56
|
-
}, 1100);
|
|
57
|
-
} else {
|
|
58
|
-
var i = 0;
|
|
59
|
-
setInterval(function(){
|
|
60
|
-
Test.dispatch({type:'TASK', payload: {version:'OneRemoteWorkerTest'+i}});
|
|
61
|
-
i++;
|
|
62
|
-
}, 2200+(Cluster.worker.id*1500), i);
|
|
63
|
-
}
|