mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-07-30 22:22:02 +08:00

Update style to some files with clang-format using Google style Add Script to parse all embedded js/css files and format them using prettier based on .prettierrc config file Update style to embedded js/css files with prettier
687 lines
22 KiB
JavaScript
687 lines
22 KiB
JavaScript
const express = require('express');
|
|
const chalk = require('chalk');
|
|
let path = require('path');
|
|
const fs = require('fs');
|
|
const port = 8080;
|
|
/*
|
|
* Web Server for development
|
|
* Web Socket server for development
|
|
*/
|
|
const wscolor = chalk.cyan;
|
|
const expresscolor = chalk.green;
|
|
const commandcolor = chalk.white;
|
|
const WebSocket = require('ws');
|
|
let currentID = 0;
|
|
const app = express();
|
|
const fileUpload = require('express-fileupload');
|
|
let serverpath = path.normalize(__dirname + '/../server/public/');
|
|
let sdpath = path.normalize(__dirname + '/../server/sd/');
|
|
|
|
let WebSocketServer = require('ws').Server,
|
|
wss = new WebSocketServer({
|
|
port: 81,
|
|
handleProtocols: function (protocol) {
|
|
console.log('protocol received from client ' + protocol);
|
|
return 'webui-v3';
|
|
return null;
|
|
},
|
|
});
|
|
app.use(fileUpload({ preserveExtension: true, debug: false }));
|
|
app.listen(port, () =>
|
|
console.log(expresscolor(`[express] Listening on port ${port}!`))
|
|
);
|
|
|
|
//app.use(express.urlencoded({ extended: false }));
|
|
|
|
function SendBinary(text) {
|
|
const array = new Uint8Array(text.length);
|
|
for (let i = 0; i < array.length; ++i) {
|
|
array[i] = text.charCodeAt(i);
|
|
}
|
|
wss.clients.forEach(function each(client) {
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
client.send(array);
|
|
}
|
|
});
|
|
}
|
|
|
|
app.post('/login', function (req, res) {
|
|
res.send('');
|
|
return;
|
|
});
|
|
|
|
app.get('/config', function (req, res) {
|
|
res.send(
|
|
'chip id: 56398\nCPU Freq: 240 Mhz<br/>' +
|
|
'CPU Temp: 58.3 C<br/>' +
|
|
'free mem: 212.36 KB<br/>' +
|
|
'SDK: v3.2.3-14-gd3e562907<br/>' +
|
|
'flash size: 4.00 MB<br/>' +
|
|
'size for update: 1.87 MB<br/>' +
|
|
'FS type: LittleFS<br/>' +
|
|
'FS usage: 104.00 KB/192.00 KB<br/>' +
|
|
'baud: 115200<br/>' +
|
|
'sleep mode: none<br/>' +
|
|
'wifi: ON<br/>' +
|
|
'hostname: esp3d<br/>' +
|
|
'HTTP port: 80<br/>' +
|
|
'Telnet port: 23<br/>' +
|
|
'WebDav port: 8383<br/>' +
|
|
'sta: ON<br/>' +
|
|
'mac: 80:7D:3A:C4:4E:DC<br/>' +
|
|
'SSID: WIFI_OFFICE_A2G<br/>' +
|
|
'signal: 100 %<br/>' +
|
|
'phy mode: 11n<br/>' +
|
|
'channel: 11<br/>' +
|
|
'ip mode: dhcp<br/>' +
|
|
'ip: 192.168.1.61<br/>' +
|
|
'gw: 192.168.1.1<br/>' +
|
|
'msk: 255.255.255.0<br/>' +
|
|
'DNS: 192.168.1.1<br/>' +
|
|
'ap: OFF<br/>' +
|
|
'mac: 80:7D:3A:C4:4E:DD<br/>' +
|
|
'serial: ON<br/>' +
|
|
'notification: OFF<br/>' +
|
|
'Target Fw: repetier<br/>' +
|
|
'FW ver: 3.0.0.a91<br/>' +
|
|
'FW arch: ESP32 '
|
|
);
|
|
return;
|
|
});
|
|
|
|
app.get('/command', function (req, res) {
|
|
console.log(commandcolor(`[server]/command params: ${req.query.cmd}`));
|
|
let url = req.query.cmd;
|
|
if (url.startsWith('[ESP800]json')) {
|
|
res.json({
|
|
cmd: '800',
|
|
status: 'ok',
|
|
data: {
|
|
FWVersion: '3.0.0.a28',
|
|
FWTarget: 40,
|
|
SDConnection: 'none',
|
|
Authentication: 'Disabled',
|
|
WebCommunication: 'Synchronous',
|
|
WebSocketIP: 'localhost',
|
|
WebSocketPort: '81',
|
|
Hostname: 'esp3d',
|
|
WiFiMode: 'STA',
|
|
WebUpdate: 'Enabled',
|
|
FlashFileSystem: 'LittleFs',
|
|
HostPath: '/',
|
|
Time: 'none',
|
|
Cam_ID: '4',
|
|
Cam_name: 'ESP32 Cam',
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
if (url.indexOf('ESP111') != -1) {
|
|
res.send('192.168.1.111');
|
|
return;
|
|
}
|
|
if (url.indexOf('ESP420') != -1) {
|
|
res.json({
|
|
Status: [
|
|
{ id: 'chip id', value: '38078' },
|
|
{ id: 'CPU Freq', value: '240 Mhz' },
|
|
{ id: 'CPU Temp', value: '50.6 C' },
|
|
{ id: 'free mem', value: '217.50 KB' },
|
|
{ id: 'SDK', value: 'v3.3.1-61-g367c3c09c' },
|
|
{ id: 'flash size', value: '4.00 MB' },
|
|
{ id: 'size for update', value: '1.87 MB' },
|
|
{ id: 'FS type', value: 'SPIFFS' },
|
|
{ id: 'FS usage', value: '39.95 KB/169.38 KB' },
|
|
{ id: 'baud', value: '115200' },
|
|
{ id: 'sleep mode', value: 'none' },
|
|
{ id: 'wifi', value: 'ON' },
|
|
{ id: 'hostname', value: 'esp3d' },
|
|
{ id: 'HTTP port', value: '80' },
|
|
{ id: 'Telnet port', value: '23' },
|
|
{ id: 'Ftp ports', value: '21, 20, 55600' },
|
|
{ id: 'sta', value: 'ON' },
|
|
{ id: 'mac', value: '30:AE:A4:21:BE:94' },
|
|
{ id: 'SSID', value: 'WIFI_OFFICE_B2G' },
|
|
{ id: 'signal', value: '100 %' },
|
|
{ id: 'phy mode', value: '11n' },
|
|
{ id: 'channel', value: '2' },
|
|
{ id: 'ip mode', value: 'dhcp' },
|
|
{ id: 'ip', value: '192.168.1.43' },
|
|
{ id: 'gw', value: '192.168.1.1' },
|
|
{ id: 'msk', value: '255.255.255.0' },
|
|
{ id: 'DNS', value: '192.168.1.1' },
|
|
{ id: 'ap', value: 'OFF' },
|
|
{ id: 'mac', value: '30:AE:A4:21:BE:95' },
|
|
{ id: 'serial', value: 'ON' },
|
|
{ id: 'notification', value: 'OFF' },
|
|
{ id: 'FW ver', value: '3.0.0.a28' },
|
|
{ id: 'FW arch', value: 'ESP32' },
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (url.indexOf('ESP410') != -1) {
|
|
res.json({
|
|
AP_LIST: [
|
|
{
|
|
SSID: 'HP-Setup>71-M277 LaserJet',
|
|
SIGNAL: '92',
|
|
IS_PROTECTED: '0',
|
|
},
|
|
{ SSID: 'WIFI_OFFICE_B2G', SIGNAL: '88', IS_PROTECTED: '1' },
|
|
{ SSID: 'NETGEAR70', SIGNAL: '66', IS_PROTECTED: '1' },
|
|
{ SSID: 'ZenFone6'luc', SIGNAL: '48', IS_PROTECTED: '1' },
|
|
{ SSID: 'Livebox-EF01', SIGNAL: '20', IS_PROTECTED: '1' },
|
|
{ SSID: 'orange', SIGNAL: '20', IS_PROTECTED: '0' },
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (url.indexOf('ESP400') != -1) {
|
|
res.json({
|
|
Settings: [
|
|
{
|
|
F: 'network/network',
|
|
P: '130',
|
|
T: 'S',
|
|
V: 'esp3d',
|
|
H: 'hostname',
|
|
S: '32',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'network/network',
|
|
P: '0',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'radio mode',
|
|
O: [{ none: '0' }, { sta: '1' }, { ap: '2' }],
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '1',
|
|
T: 'S',
|
|
V: 'WIFI_OFFICE_B2G',
|
|
S: '32',
|
|
H: 'SSID',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '34',
|
|
T: 'S',
|
|
N: '1',
|
|
V: '********',
|
|
S: '64',
|
|
H: 'pwd',
|
|
M: '8',
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '99',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'ip mode',
|
|
O: [{ dhcp: '1' }, { static: '0' }],
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '100',
|
|
T: 'A',
|
|
V: '192.168.0.1',
|
|
H: 'ip',
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '108',
|
|
T: 'A',
|
|
V: '192.168.0.1',
|
|
H: 'gw',
|
|
},
|
|
{
|
|
F: 'network/sta',
|
|
P: '104',
|
|
T: 'A',
|
|
V: '255.255.255.0',
|
|
H: 'msk',
|
|
},
|
|
{
|
|
F: 'network/ap',
|
|
P: '218',
|
|
T: 'S',
|
|
V: 'ESP3D',
|
|
S: '32',
|
|
H: 'SSID',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'network/ap',
|
|
P: '251',
|
|
T: 'S',
|
|
N: '1',
|
|
V: '********',
|
|
S: '64',
|
|
H: 'pwd',
|
|
M: '8',
|
|
},
|
|
{
|
|
F: 'network/ap',
|
|
P: '316',
|
|
T: 'A',
|
|
V: '192.168.0.1',
|
|
H: 'ip',
|
|
},
|
|
{
|
|
F: 'network/ap',
|
|
P: '118',
|
|
T: 'B',
|
|
V: '11',
|
|
H: 'channel',
|
|
O: [
|
|
{ 1: '1' },
|
|
{ 2: '2' },
|
|
{ 3: '3' },
|
|
{ 4: '4' },
|
|
{ 5: '5' },
|
|
{ 6: '6' },
|
|
{ 7: '7' },
|
|
{ 8: '8' },
|
|
{ 9: '9' },
|
|
{ 10: '10' },
|
|
{ 11: '11' },
|
|
{ 12: '12' },
|
|
{ 13: '13' },
|
|
{ 14: '14' },
|
|
],
|
|
},
|
|
{
|
|
F: 'service/http',
|
|
P: '328',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'enable',
|
|
O: [{ no: '0' }, { yes: '1' }],
|
|
},
|
|
{
|
|
F: 'service/http',
|
|
P: '121',
|
|
T: 'I',
|
|
V: '80',
|
|
H: 'port',
|
|
S: '65001',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'service/telnetp',
|
|
P: '329',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'enable',
|
|
O: [{ no: '0' }, { yes: '1' }],
|
|
},
|
|
{
|
|
F: 'service/telnetp',
|
|
P: '125',
|
|
T: 'I',
|
|
V: '23',
|
|
H: 'port',
|
|
S: '65001',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'service/ftp',
|
|
P: '1208',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'enable',
|
|
O: [{ no: '0' }, { yes: '1' }],
|
|
},
|
|
{
|
|
F: 'service/ftp',
|
|
P: '1196',
|
|
T: 'I',
|
|
V: '21',
|
|
H: 'control port',
|
|
S: '65001',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'service/ftp',
|
|
P: '1200',
|
|
T: 'I',
|
|
V: '20',
|
|
H: 'active port',
|
|
S: '65001',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'service/ftp',
|
|
P: '1204',
|
|
T: 'I',
|
|
V: '55600',
|
|
H: 'passive port',
|
|
S: '65001',
|
|
M: '1',
|
|
},
|
|
{
|
|
F: 'service/notification',
|
|
P: '1191',
|
|
T: 'B',
|
|
V: '1',
|
|
H: 'auto notif',
|
|
O: [{ no: '0' }, { yes: '1' }],
|
|
},
|
|
{
|
|
F: 'service/notification',
|
|
P: '116',
|
|
T: 'B',
|
|
V: '0',
|
|
H: 'notification',
|
|
O: [
|
|
{ none: '0' },
|
|
{ pushover: '1' },
|
|
{ email: '2' },
|
|
{ line: '3' },
|
|
],
|
|
},
|
|
{
|
|
F: 'service/notification',
|
|
P: '332',
|
|
T: 'S',
|
|
V: '********',
|
|
S: '63',
|
|
H: 't1',
|
|
M: '0',
|
|
},
|
|
{
|
|
F: 'service/notification',
|
|
P: '583',
|
|
T: 'S',
|
|
V: '********',
|
|
S: '63',
|
|
H: 't2',
|
|
M: '0',
|
|
},
|
|
{
|
|
F: 'service/notification',
|
|
P: '1042',
|
|
T: 'S',
|
|
V: ' ',
|
|
S: '127',
|
|
H: 'ts',
|
|
M: '0',
|
|
},
|
|
{
|
|
F: 'system/system',
|
|
P: '648',
|
|
T: 'B',
|
|
V: '40',
|
|
H: 'targetfw',
|
|
O: [
|
|
{ repetier: '50' },
|
|
{ marlin: '20' },
|
|
{ marlinkimbra: '35' },
|
|
{ smoothieware: '40' },
|
|
{ grbl: '10' },
|
|
{ unknown: '0' },
|
|
],
|
|
},
|
|
{
|
|
F: 'system/system',
|
|
P: '112',
|
|
T: 'I',
|
|
V: '115200',
|
|
H: 'baud',
|
|
O: [
|
|
{ 9600: '9600' },
|
|
{ 19200: '19200' },
|
|
{ 38400: '38400' },
|
|
{ 57600: '57600' },
|
|
{ 74880: '74880' },
|
|
{ 115200: '115200' },
|
|
{ 230400: '230400' },
|
|
{ 250000: '250000' },
|
|
{ 500000: '500000' },
|
|
{ 921600: '921600' },
|
|
],
|
|
},
|
|
{
|
|
F: 'system/system',
|
|
P: '320',
|
|
T: 'I',
|
|
V: '10000',
|
|
H: 'bootdelay',
|
|
S: '40000',
|
|
M: '0',
|
|
},
|
|
{
|
|
F: 'system/system',
|
|
P: '129',
|
|
T: 'F',
|
|
V: '255',
|
|
H: 'outputmsg',
|
|
O: [{ M117: '16' }, { serial: '1' }, { telnet: '2' }],
|
|
},
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
SendBinary('ok\n');
|
|
res.send('');
|
|
});
|
|
|
|
function fileSizeString(size) {
|
|
let s;
|
|
if (size < 1024) return size + ' B';
|
|
if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB';
|
|
if (size < 1024 * 1024 * 1024)
|
|
return (size / (1024 * 1024)).toFixed(2) + ' MB';
|
|
if (size < 1024 * 1024 * 1024 * 1024)
|
|
return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
|
|
return 'X B';
|
|
}
|
|
|
|
function filesList(mypath, mainpath) {
|
|
let res = '{"files":[';
|
|
let nb = 0;
|
|
let total = sdpath == mainpath ? 4096 * 1024 * 1024 : 1.2 * 1024 * 1024;
|
|
let totalused = getTotalSize(mainpath);
|
|
let currentpath = path.normalize(mainpath + mypath);
|
|
console.log('[path]' + currentpath);
|
|
fs.readdirSync(currentpath).forEach((fileelement) => {
|
|
let fullpath = path.normalize(currentpath + '/' + fileelement);
|
|
let fst = fs.statSync(fullpath);
|
|
let fsize = -1;
|
|
|
|
if (fst.isFile()) {
|
|
fsize = fileSizeString(fst.size);
|
|
}
|
|
if (nb > 0) res += ',';
|
|
res += '{"name":"' + fileelement + '","size":"' + fsize + '"}';
|
|
nb++;
|
|
});
|
|
res +=
|
|
'],"path":"' +
|
|
mypath +
|
|
'","occupation":"' +
|
|
((100 * totalused) / total).toFixed(0) +
|
|
'","status":"ok","total":"' +
|
|
fileSizeString(total) +
|
|
'","used":"' +
|
|
fileSizeString(totalused) +
|
|
'"}';
|
|
return res;
|
|
}
|
|
|
|
const getAllFiles = function (dirPath, arrayOfFiles) {
|
|
let files = fs.readdirSync(dirPath);
|
|
|
|
arrayOfFiles = arrayOfFiles || [];
|
|
|
|
files.forEach(function (file) {
|
|
if (fs.statSync(dirPath + '/' + file).isDirectory()) {
|
|
arrayOfFiles = getAllFiles(dirPath + '/' + file, arrayOfFiles);
|
|
} else {
|
|
arrayOfFiles.push(dirPath + '/' + file);
|
|
}
|
|
});
|
|
|
|
return arrayOfFiles;
|
|
};
|
|
|
|
const getTotalSize = function (directoryPath) {
|
|
const arrayOfFiles = getAllFiles(directoryPath);
|
|
|
|
let totalSize = 0;
|
|
|
|
arrayOfFiles.forEach(function (filePath) {
|
|
totalSize += fs.statSync(filePath).size;
|
|
});
|
|
|
|
return totalSize;
|
|
};
|
|
|
|
function deleteFolderRecursive(path) {
|
|
if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
|
|
fs.readdirSync(path).forEach(function (file, index) {
|
|
let curPath = path + '/' + file;
|
|
|
|
if (fs.lstatSync(curPath).isDirectory()) {
|
|
// recurse
|
|
deleteFolderRecursive(curPath);
|
|
} else {
|
|
// delete file
|
|
fs.unlinkSync(curPath);
|
|
}
|
|
});
|
|
|
|
console.log(`[server]Deleting directory "${path}"...`);
|
|
if (fs.existsSync(path)) fs.rmdirSync(path);
|
|
} else console.log(`[server]No directory "${path}"...`);
|
|
}
|
|
|
|
app.all('/updatefw', function (req, res) {
|
|
res.send('ok');
|
|
});
|
|
|
|
app.all('/sdfiles', function (req, res) {
|
|
let mypath = req.query.path;
|
|
let url = req.originalUrl;
|
|
let filepath = path.normalize(sdpath + mypath + '/' + req.query.filename);
|
|
if (url.indexOf('action=deletedir') != -1) {
|
|
console.log('[server]delete directory ' + filepath);
|
|
deleteFolderRecursive(filepath);
|
|
fs.readdirSync(mypath);
|
|
} else if (url.indexOf('action=delete') != -1) {
|
|
fs.unlinkSync(filepath);
|
|
console.log('[server]delete file ' + filepath);
|
|
}
|
|
if (url.indexOf('action=createdir') != -1) {
|
|
fs.mkdirSync(filepath);
|
|
console.log('[server]new directory ' + filepath);
|
|
}
|
|
if (typeof mypath == 'undefined') {
|
|
if (typeof req.body.path == 'undefined') {
|
|
console.log('[server]path is not defined');
|
|
mypath = '/';
|
|
} else {
|
|
mypath = (req.body.path == '/' ? '' : req.body.path) + '/';
|
|
}
|
|
}
|
|
console.log('[server]path is ' + mypath);
|
|
if (!req.files || Object.keys(req.files).length === 0) {
|
|
return res.send(filesList(mypath, sdpath));
|
|
}
|
|
let myFile = req.files.myfiles;
|
|
if (typeof myFile.length == 'undefined') {
|
|
let fullpath = path.normalize(sdpath + mypath + myFile.name);
|
|
console.log('[server]one file:' + fullpath);
|
|
myFile.mv(fullpath, function (err) {
|
|
if (err) return res.status(500).send(err);
|
|
res.send(filesList(mypath, sdpath));
|
|
});
|
|
return;
|
|
} else {
|
|
console.log(myFile.length + ' files');
|
|
for (let i = 0; i < myFile.length; i++) {
|
|
let fullpath = path.normalize(sdpath + mypath + myFile[i].name);
|
|
console.log(fullpath);
|
|
myFile[i].mv(fullpath).then(() => {
|
|
if (i == myFile.length - 1) res.send(filesList(mypath, sdpath));
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
app.all('/files', function (req, res) {
|
|
let mypath = req.query.path;
|
|
let url = req.originalUrl;
|
|
let filepath = path.normalize(
|
|
serverpath + mypath + '/' + req.query.filename
|
|
);
|
|
if (url.indexOf('action=deletedir') != -1) {
|
|
console.log('[server]delete directory ' + filepath);
|
|
deleteFolderRecursive(filepath);
|
|
fs.readdirSync(mypath);
|
|
} else if (url.indexOf('action=delete') != -1) {
|
|
fs.unlinkSync(filepath);
|
|
console.log('[server]delete file ' + filepath);
|
|
}
|
|
if (url.indexOf('action=createdir') != -1) {
|
|
fs.mkdirSync(filepath);
|
|
console.log('[server]new directory ' + filepath);
|
|
}
|
|
if (typeof mypath == 'undefined') {
|
|
if (typeof req.body.path == 'undefined') {
|
|
console.log('[server]path is not defined');
|
|
mypath = '/';
|
|
} else {
|
|
mypath = (req.body.path == '/' ? '' : req.body.path) + '/';
|
|
}
|
|
}
|
|
console.log('[server]path is ' + mypath);
|
|
if (!req.files || Object.keys(req.files).length === 0) {
|
|
return res.send(filesList(mypath, serverpath));
|
|
}
|
|
let myFile = req.files.myfiles;
|
|
if (typeof myFile.length == 'undefined') {
|
|
let fullpath = path.normalize(serverpath + mypath + myFile.name);
|
|
console.log('[server]one file:' + fullpath);
|
|
myFile.mv(fullpath, function (err) {
|
|
if (err) return res.status(500).send(err);
|
|
res.send(filesList(mypath, serverpath));
|
|
});
|
|
return;
|
|
} else {
|
|
console.log(myFile.length + ' files');
|
|
for (let i = 0; i < myFile.length; i++) {
|
|
let fullpath = path.normalize(serverpath + mypath + myFile[i].name);
|
|
console.log(fullpath);
|
|
myFile[i].mv(fullpath).then(() => {
|
|
if (i == myFile.length - 1)
|
|
res.send(filesList(mypath, serverpath));
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
wss.on('connection', (socket, request) => {
|
|
console.log(wscolor('[ws] New connection'));
|
|
console.log(wscolor(`[ws] currentID:${currentID}`));
|
|
socket.send(`currentID:${currentID}`);
|
|
wss.clients.forEach(function each(client) {
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
client.send(`activeID:${currentID}`);
|
|
}
|
|
});
|
|
currentID++;
|
|
socket.on('message', (message) => {
|
|
console.log(wscolor('[ws] received: %s', message));
|
|
});
|
|
});
|
|
wss.on('error', (error) => {
|
|
console.log(wscolor('[ws] Error: %s', error));
|
|
});
|