From f434e396457b10e3245a97ccf37beadf95789151 Mon Sep 17 00:00:00 2001
From: Kamynale <47644905+Kamynale@users.noreply.github.com>
Date: Sun, 29 Nov 2020 21:50:29 +0300
Subject: [PATCH 1/3] socket
---
server/app.js | 249 +++++++++++++++++++++++++++-----
src/views/app/gogo/start.jsx | 269 +++++++----------------------------
2 files changed, 270 insertions(+), 248 deletions(-)
diff --git a/server/app.js b/server/app.js
index c7a2cef..683dd22 100644
--- a/server/app.js
+++ b/server/app.js
@@ -7,12 +7,20 @@ const bodyParser = require('body-parser');
const mysql = require('mysql');
const fs = require('fs');
const path = require('path');
-const params = require('express-route-params');
const config = require('./config');
+const params = require('express-route-params');
+const createStore = require('redux')
+const Provider = require('react-redux')
+const compression = require('compression');
+const morgan = require('morgan')
+const io = require('socket.io')();
+
+
const app = express();
params(express);
+
// Define MySQL parameter in Config.js file.
const pool = mysql.createPool({
host: config.host,
@@ -38,28 +46,46 @@ config.facebook_api_key = '2640133479605924';
// let HOSTNAME = 'https://opexflow.com';
passport.use(new FacebookStrategy({
- clientID: config.facebook_api_key,
- clientSecret: config.facebook_api_secret,
- callbackURL: config.callback_url,
- profileFields: ['id', 'displayName', 'name', 'gender', 'profileUrl', 'emails', 'photos'],
-},
-((accessToken, refreshToken, profile, done) => {
- process.nextTick(() => {
- console.log(profile);
- if (profile && profile.id) {
- const photo = profile.photos && profile.photos[0] && profile.photos[0].value || '';
- const email = profile.emails && profile.emails[0] && profile.emails[0].value || '';
-
- pool.query(`INSERT INTO Users SET
- id = '${profile.id}', login = '${profile.displayName}', email = '${email}', photo='${photo}', createdAt = NOW(), balance = 10000
- ON DUPLICATE KEY UPDATE login = '${profile.displayName}', email = '${email}', photo='${photo}'
- `);
-
- profile.accessToken = accessToken;
- }
- return done(null, profile);
- });
-})));
+ clientID: config.facebook_api_key,
+ clientSecret: config.facebook_api_secret,
+ callbackURL: config.callback_url,
+ profileFields: ['id', 'displayName', 'name', 'gender', 'profileUrl', 'emails', 'photos']
+ },
+ ((accessToken, refreshToken, profile, done) => {
+ process.nextTick(() => {
+ console.log(profile);
+ if (profile && profile.id) {
+ const photo = profile.photos && profile.photos[0] && profile.photos[0].value || '';
+ const email = profile.emails && profile.emails[0] && profile.emails[0].value || '';
+
+ pool.query(`SELECT * from Users where id=${profile.id}`, (err, rows) => {
+ if (err) throw err;
+ if (rows && rows.length === 0) {
+ console.log('There is no such user, adding now');
+ pool.query(`INSERT INTO Users SET id = '${profile.id}', login = '${profile.displayName}', email = '${email}', photo='${photo}'`);
+ } else {
+ console.log('User already exists in database');
+ }
+ });
+
+ pool.query(`SELECT * from Transactions where id='${profile.id}'`, (err, rows) => {
+ if (err) throw err;
+ if (rows && rows.length === 0) {
+ console.log('There is no balance User in Transaction, adding now');
+ pool.query(`INSERT INTO Transactions SET id = '${profile.id}'`);
+ } else {
+ console.log('Balance for User already exists in database');
+ }
+ });
+
+ profile.accessToken = accessToken;
+ }
+ return done(null, profile);
+ });
+ }))
+);
+
+
// app.set('views', __dirname + '/views');
// app.set('view engine', 'ejs');
@@ -69,7 +95,7 @@ function replaceHost(host) {
}
app.use(bodyParser.urlencoded({ extended: false }));
-app.use(session({ secret: 'secret123', key: 'sid' })); //, resave: false, saveUninitialized: false }));
+app.use(session({ secret: 'secret123', key: 'sid' }));
app.use(passport.initialize());
app.use(passport.session());
@@ -94,6 +120,7 @@ app.get('/', (req, res) => {
}
});
+
app.get('/api/account', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', replaceHost(HOSTNAME));
@@ -106,9 +133,12 @@ app.get('/api/account', (req, res) => {
return res.end('{}');
}
- pool.query(`SELECT * from Users where id=${req.user.id}`, (err, rows) => {
- res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance } }));
- });
+/* pool.query(`SELECT user from Users where id=${req.user.id}` , (err, rows) => {
+ res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance }}));
+ })*/
+ pool.query(`SELECT * from Users,Transactions WHERE Users.id=Transactions.id`, (err, rows) => {
+ res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance }}));
+ })
});
app.get('/api/account/:id', (req, res) => {
@@ -134,7 +164,8 @@ app.get('/api/logout', (req, res) => {
return res.end('{}');
});
-app.param('tick', /^\d+(min|h|d|m)$/i);
+
+app.param('tick', /^\d+(min|h|d|m)$/i)
// ========= Работа с тиками ==========
app.get('/api/stocks/ticks/:tick', ensureAuthenticated, (req, res) => {
@@ -167,7 +198,8 @@ app.get('/api/stocks/ticks/:tick', ensureAuthenticated, (req, res) => {
return res.end(JSON.stringify(ticks));
});
-app.param('price', /^\d+\.?\d*$/i);
+app.param('price', /^\d+\.?\d*$/i)
+
// ========= Работа с тиками ==========
app.get('/api/stocks/trades/buy/:price', ensureAuthenticated, (req, res) => {
@@ -182,10 +214,59 @@ app.get('/api/stocks/trades/buy/:price', ensureAuthenticated, (req, res) => {
return res.end('{}');
}
- pool.query(`UPDATE Users SET balance = balance - '${req.params.price}' WHERE id = '${req.user.id}'`);
- return res.end(JSON.stringify({}));
+ const sql = `SELECT balance FROM Transactions WHERE id='${req.user.id}' AND balance>=${req.params.price}`;
+ const transaction = `UPDATE Transactions SET stock='SBER', commission=0, price=${req.params.price}+commission, balance = balance - price WHERE id='${req.user.id}'`
+ const logs = `INSERT INTO Transactions_logs(id,balance,price,commission,stock) SELECT id,balance,price,commission,stock FROM Transactions WHERE id='${req.user.id}')`
+ let a = pool.getConnection(function (err, connection) {
+
+ connection.query(sql, (err, results) => {
+ if (err) throw err;
+ if (results && results.length === 0) {
+ connection.release();
+ console.log('Not enough money');
+ } else {
+ connection.beginTransaction(function (err) {
+ if (err) { //Transaction Error (Rollback and release connection)
+ connection.rollback(function () {
+ connection.release();
+ console.log('connection is lost')
+ //Failure
+ });
+ } else {
+ connection.query(transaction, function (err, results) {
+ if (err) { //Query Error (Rollback and release connection)
+ connection.rollback(function () {
+ connection.release();
+ console.log('no money');
+ });
+ } else {
+ connection.commit(function (err) {
+ if (err) {
+ connection.rollback(function () {
+ connection.release();
+ console.log('lost!');
+ });
+ } else {
+ connection.release();
+ console.log(`'balance update - '${req.params.price}`);
+ console.log('success!');
+ connection.query(logs, (err, results) => {
+ console.log('Transactions logs added');
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ });
+ console.log(a)
});
+
+
app.get('/api/stocks/trades/sell/:price', ensureAuthenticated, (req, res) => {
// TODO: сделать общее решение для локальной разработки.
res.setHeader('Content-Type', 'application/json');
@@ -198,8 +279,55 @@ app.get('/api/stocks/trades/sell/:price', ensureAuthenticated, (req, res) => {
return res.end('{}');
}
- pool.query(`UPDATE Users SET balance = balance + '${req.params.price}' WHERE id = '${req.user.id}'`);
- return res.end(JSON.stringify({}));
+ const sql = `SELECT balance FROM Transactions WHERE id='${req.user.id}' AND balance>=${req.params.price}`;
+ const transaction = `UPDATE Transactions SET stock='SBER', commission=0, price=${req.params.price}+commission, balance = balance + price WHERE id='${req.user.id}'`
+ const logs = `INSERT INTO Transactions_logs(id,balance,price,commission,stock) SELECT id,balance,price,commission,stock FROM Transactions WHERE id='${req.user.id}')`
+
+ pool.getConnection(function (err, connection) {
+
+ connection.query(sql, (err, results) => {
+ if (err) throw err;
+ if (results && results.length === 0) {
+ connection.release();
+ console.log('Not enough money');
+ } else {
+ connection.beginTransaction(function (err) {
+ if (err) { //Transaction Error (Rollback and release connection)
+ connection.rollback(function () {
+ connection.release();
+ console.log('connection is lost')
+ //Failure
+ });
+ } else {
+ connection.query(transaction, function (err, results) {
+ if (err) { //Query Error (Rollback and release connection)
+ connection.rollback(function () {
+ connection.release();
+ console.log('no money');
+ });
+ } else {
+ connection.commit(function (err) {
+ if (err) {
+ connection.rollback(function () {
+ connection.release();
+ console.log('lost!');
+ });
+ } else {
+ connection.release();
+ console.log(`'balance update + '${req.params.price}`);
+ console.log('success!');
+ connection.query(logs, (err, results) => {
+ console.log('Transactions logs added');
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ });
});
function ensureAuthenticated(req, res, next) {
@@ -208,4 +336,59 @@ function ensureAuthenticated(req, res, next) {
return next();
}
+/*
+// SSR
+
+app.use(compression());
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(morgan('dev'));
+app.use(cookieParser());
+
+// Set up homepage, static assets, and capture everything else
+app.use(express.Router().get('/exchangerate'));
+app.use(express.static(path.resolve(__dirname, '../build')));
+
+
+// We tell React Loadable to load all required assets and start listening - ROCK AND ROLL!
+Loadable.preloadAll().then(() => {
+ app.listen(PORT, console.log(`App listening on port ${PORT}!`));
+});
+
+// Handle the bugs somehow
+app.on('error', error => {
+ if (error.syscall !== 'listen') {
+ throw error;
+ }
+
+ const bind = typeof PORT === 'string' ? 'Pipe ' + PORT : 'Port ' + PORT;
+
+ switch (error.code) {
+ case 'EACCES':
+ console.error(bind + ' requires elevated privileges');
+ process.exit(1);
+ break;
+ case 'EADDRINUSE':
+ console.error(bind + ' is already in use');
+ process.exit(1);
+ break;
+ default:
+ throw error;
+ }
+});
+*/
+
+//socket.io
+io.sockets.on('connection', function (socket) {
+ io.sockets.emit('getting_data', 'Loading Data for chart');
+ setInterval(5000,function(data){
+ let q = "SELECT * FROM stock";
+ connection.query(q, function(err, rows) {
+ if (err) throw err;
+ res.end(JSON.stringify(rows))
+ });
+ });
+});
+
+
app.listen(3001);
diff --git a/src/views/app/gogo/start.jsx b/src/views/app/gogo/start.jsx
index 248eeb9..6763b05 100644
--- a/src/views/app/gogo/start.jsx
+++ b/src/views/app/gogo/start.jsx
@@ -1,237 +1,74 @@
import React, { PureComponent } from 'react';
import { Row, Button } from 'reactstrap';
-import Chart from 'react-apexcharts';
-import ApexCharts from 'apexcharts';
-import IntlMessages from '../../../helpers/IntlMessages';
import { Colxx, Separator } from '../../../components/common/CustomBootstrap';
-import Breadcrumb from '../../../containers/navs/Breadcrumb';
+import Chart from 'kaktana-react-lightweight-charts'
+import io from "socket.io-client"
-export default class Start extends PureComponent {
+
+
+export default class Start extends PureComponent {
constructor(props) {
super(props);
this.state = {
- series: [{
- data: [],
- }],
options: {
- chart: {
- id: 'ticks_chart',
- type: 'candlestick',
- height: 350,
- },
- title: {
- text: 'CandleStick Chart',
- align: 'left',
- },
- xaxis: {
- // type: 'datetime',
- type: 'numeric'
- },
- yaxis: {
- tooltip: {
- enabled: true,
- },
- },
+ alignLabels: true,
+ timeScale: {
+ rightOffset: 12,
+ barSpacing: 3,
+ fixLeftEdge: true,
+ lockVisibleTimeRangeOnResize: true,
+ rightBarStaysOnScroll: true,
+ borderVisible: true,
+ borderColor: "#fff000",
+ visible: true,
+ timeVisible: true,
+ secondsVisible: false
+ }
},
- // Берём данные из LS, чтобы при возврате рисовался интересующий график.
- currentTicks: window.localStorage.getItem('ticks') || '5min',
- };
- }
-
- // lastDate = 1538884800000
- // [Timestamp, O, H, L, C]
- // lastTick = [6604.98, 6606, 6604.07, 6606]
-
- componentDidMount() {
- this.getChartData();
- }
-
- componentDidUpdate() {
- if(!this.state.interactive) {
- this.getChartData();
- this.interval && window.clearInterval(this.interval);
- } else {
- if (!this.interval) {
- this.interval = window.setInterval(() => {
- const dataBuff = this.state.dataBuff.slice(0);
- const data = this.state.series[0].data.slice(0);
- let nextData;
-
- if (this.state.dataBuff.length) {
- nextData = dataBuff.shift();
- data.push(nextData);
-
- this.setState({
- dataBuff,
- series: [{
- data
- }]
- });
- } else {
- window.clearInterval(this.interval);
- }
- }, 250);
- }
- }
-
- if (this.state.series[0].data && this.state.series[0].data.length) {
- ApexCharts.exec('ticks_chart', 'render', [{
- data: this.state.series[0].data
- }])
+ candlestickSeries: [{
+ data: [
+ { time: '2018-10-19', open: 180.34, high: 180.99, low: 178.57, close: 179.85 },
+ { time: '2018-10-22', open: 180.82, high: 181.40, low: 177.56, close: 178.75 },
+ { time: '2018-10-23', open: 175.77, high: 179.49, low: 175.44, close: 178.53 },
+ { time: '2018-10-24', open: 178.58, high: 182.37, low: 176.31, close: 176.97 },
+ { time: '2018-10-25', open: 177.52, high: 180.50, low: 176.83, close: 179.07 },
+ { time: '2018-10-26', open: 176.88, high: 177.34, low: 170.91, close: 172.23 },
+ { time: '2018-10-29', open: 173.74, high: 175.99, low: 170.95, close: 173.20 },
+ { time: '2018-10-30', open: 173.16, high: 176.43, low: 172.64, close: 176.24 },
+ { time: '2018-10-31', open: 177.98, high: 178.85, low: 175.59, close: 175.88 },
+ { time: '2020-11-01', open: 176.84, high: 180.86, low: 175.90, close: 180.46 },
+ { time: '2020-11-02', open: 182.47, high: 183.01, low: 177.39, close: 179.93 },
+ { time: '2018-10-19', open: 180.34, high: 180.99, low: 178.57, close: 179.85 },
+ { time: '2018-10-22', open: 180.82, high: 181.40, low: 177.56, close: 178.75 },
+ { time: '2018-10-23', open: 175.77, high: 179.49, low: 175.44, close: 178.53 },
+ { time: '2018-10-24', open: 178.58, high: 182.37, low: 176.31, close: 176.97 },
+ { time: '2018-10-25', open: 177.52, high: 180.50, low: 176.83, close: 179.07 },
+ { time: '2018-10-26', open: 176.88, high: 177.34, low: 170.91, close: 172.23 },
+ { time: '2018-10-29', open: 173.74, high: 175.99, low: 170.95, close: 173.20 },
+ { time: '2018-10-30', open: 173.16, high: 176.43, low: 172.64, close: 176.24 },
+ { time: '2018-10-31', open: 177.98, high: 178.85, low: 175.59, close: 175.88 },
+ { time: '2020-11-01', open: 176.84, high: 180.86, low: 175.90, close: 180.46 },
+ { time: '2020-11-02', open: 182.47, high: 183.01, low: 177.39, close: 179.93 },
+ { time: '2020-11-05', open: 181.02, high: 182.41, low: 179.30, close: 182.19 }
+ ]
+ }]
}
}
-
- getHost(postfix) {
- // Костыль для локальной разработки, чтобы порты сервера и клиента разнести.
- // TODO: сделать в едином месте
- let host = `https://${window.location.host}/api/stocks/${postfix}`;
- if (host.indexOf('3000') !== -1) {
- // TODO: сделать в едином месте
- host = host.replace('3000', '3001').replace('https', 'http');
- }
-
- return host;
- }
-
- getChartData() {
- this.loadedData || (this.loadedData = {});
- const current = this.loadedData[this.state.currentTicks];
- if (this.loadedData[this.state.currentTicks] === true) {
- return;
- } else if (current) {
- ApexCharts.exec('ticks_chart', 'updateSeries', [{
- data: this.loadedData[this.state.currentTicks].series[0].data,
- }]);
- this.setState(this.loadedData[this.state.currentTicks]);
- return;
- } else {
- this.loadedData[this.state.currentTicks] = true;
- }
-
- /*
- {
- x: new Date(1538874000000),
- y: [6600.55, 6605, 6589.14, 6593.01],
- },
- */
- const x = new XMLHttpRequest();
- x.open('GET', this.getHost(`ticks/${this.state.currentTicks}`), true);
- x.onload = () => {
- const res = x.responseText && JSON.parse(x.responseText);
-
- const series = this.state.series.slice(0);
- let name;
-
- series[0].data = !res || !Object.keys(res).length ? [] : res.map((t, i) => {
- // ticker, per, date, time, open, hight, low, close, vol (объём торгов)
- // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370
- const tick = t.split(',');
-
- if (!name) {
- name = tick[0];
- }
-
- if (!tick[2] || !tick[3]) {
- return;
- }
-
- // console.log(`${tick[2]} ${tick[3]}`, [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])]);
- // [Timestamp, O, H, L, C]
- return {
- x: `${tick[2]} ${tick[3]}`,
- y: [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])],
-
- };
- })
- .filter(Boolean);
-
- this.loadedData[this.state.currentTicks] = {
- series,
- options: {
- ...this.state.options,
- title: {
- ...this.state.options.title,
- text: name,
- },
- },
- };
-
- this.setState(this.loadedData[this.state.currentTicks]);
-
- ApexCharts.exec('ticks_chart', 'updateSeries', [{
- data: series[0].data,
- }]);
- };
- x.withCredentials = true;
- x.send();
+ componentDidMount(){
+ let socket = io.connect("https://localhost:3000");
+ console.log(socket)
+ socket.on("getting_data", function(data) {
+ console.log(data);
+ })
}
render() {
return (
<>
-
-
- {this.props.match && }
-
-
-
-
-
-
- {[
- // '1min',
- '5min',
- '10min',
- ].map((t, i) =>
-
- )}
-
-
-
- {Boolean(this.state.series[0].data.length) && (
-
- )}
+
@@ -261,6 +98,8 @@ export default class Start extends PureComponent {
x.open('GET', this.getHost(`trades/sell/${price}`), true);
x.withCredentials = true;
x.send();
+
+ console.log('sell', price);
}}
size="lg"
>
From fb37190c811b523ff8ad07c9258ddbbb364c8bfa Mon Sep 17 00:00:00 2001
From: Kamynale <47644905+Kamynale@users.noreply.github.com>
Date: Tue, 1 Dec 2020 11:33:12 +0300
Subject: [PATCH 2/3] socket with comments
---
.gitignore | 3 +
package-lock.json | 311 ++++++++++++++++++++++++++++++++++++
package.json | 6 +-
server/app.js | 29 ++--
src/views/app/bots/sber.jsx | 12 ++
5 files changed, 348 insertions(+), 13 deletions(-)
diff --git a/.gitignore b/.gitignore
index 3e7fc92..3ebc440 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,4 +105,7 @@ dist
.DS_Store
+.idea/
+.idea
+
build
diff --git a/package-lock.json b/package-lock.json
index 5a7cf22..00c6fb5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2376,6 +2376,15 @@
"@babel/types": "^7.3.0"
}
},
+ "@types/body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
"@types/classnames": {
"version": "2.2.10",
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz",
@@ -2386,11 +2395,58 @@
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
+ "@types/component-emitter": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
+ "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
+ },
+ "@types/connect": {
+ "version": "3.4.33",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
+ "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
+ },
+ "@types/cors": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz",
+ "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==",
+ "requires": {
+ "@types/express": "*"
+ }
+ },
"@types/eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag=="
},
+ "@types/express": {
+ "version": "4.17.9",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.9.tgz",
+ "integrity": "sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw==",
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "*",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.17.14",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.14.tgz",
+ "integrity": "sha512-uFTLwu94TfUFMToXNgRZikwPuZdOtDgs3syBtAIr/OXorL1kJqUJT9qCLnRZ5KBOWfZQikQ2xKgR2tnDj1OgDA==",
+ "requires": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
"@types/glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz",
@@ -2442,6 +2498,11 @@
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
},
+ "@types/mime": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
+ "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
+ },
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -2493,6 +2554,11 @@
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
},
+ "@types/qs": {
+ "version": "6.9.5",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
+ "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ=="
+ },
"@types/quill": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz",
@@ -2501,6 +2567,11 @@
"parchment": "^1.1.2"
}
},
+ "@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
+ },
"@types/react": {
"version": "16.9.38",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.38.tgz",
@@ -2523,6 +2594,15 @@
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz",
"integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE="
},
+ "@types/serve-static": {
+ "version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz",
+ "integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==",
+ "requires": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
"@types/sortablejs": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.10.4.tgz",
@@ -5130,6 +5210,11 @@
"lodash.clone": "^4.5.0"
}
},
+ "backo2": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -5190,11 +5275,21 @@
}
}
},
+ "base64-arraybuffer": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+ "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
+ },
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
+ "base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
+ },
"base64url": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
@@ -6283,6 +6378,11 @@
"integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
"dev": true
},
+ "component-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+ "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
+ },
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
@@ -6607,6 +6707,15 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
+ "cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
"cosmiconfig": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
@@ -7884,6 +7993,87 @@
"once": "^1.4.0"
}
},
+ "engine.io": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.4.tgz",
+ "integrity": "sha512-4ggUX5pICZU17OTZNFv5+uFE/ZyoK+TIXv2SvxWWX8lwStllQ6Lvvs4lDBqvKpV9EYXNcvlNOcjKChd/mo+8Tw==",
+ "requires": {
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.4.1",
+ "cors": "~2.8.5",
+ "debug": "~4.1.0",
+ "engine.io-parser": "~4.0.0",
+ "ws": "^7.1.2"
+ },
+ "dependencies": {
+ "cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "ws": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
+ "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ=="
+ }
+ }
+ },
+ "engine.io-client": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.0.4.tgz",
+ "integrity": "sha512-and4JRvjv+BQ4WBLopYUFePxju3ms3aBRk0XjaLdh/t9TKv2LCKtKKWFRoRzIfUZsu3U38FcYqNLuXhfS16vqw==",
+ "requires": {
+ "base64-arraybuffer": "0.1.4",
+ "component-emitter": "~1.3.0",
+ "debug": "~4.1.0",
+ "engine.io-parser": "~4.0.1",
+ "has-cors": "1.1.0",
+ "parseqs": "0.0.6",
+ "parseuri": "0.0.6",
+ "ws": "~7.2.1",
+ "xmlhttprequest-ssl": "~1.5.4",
+ "yeast": "0.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "ws": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz",
+ "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA=="
+ }
+ }
+ },
+ "engine.io-parser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.1.tgz",
+ "integrity": "sha512-v5aZK1hlckcJDGmHz3W8xvI3NUHYc9t8QtTbqdR5OaH3S9iJZilPubauOm+vLWOMMWzpE3hiq92l9lTAHamRCg=="
+ },
"enhanced-resolve": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
@@ -9940,6 +10130,11 @@
"ansi-regex": "^2.0.0"
}
},
+ "has-cors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
+ },
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -14833,6 +15028,16 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
},
+ "parseqs": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+ "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
+ },
+ "parseuri": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+ "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
+ },
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -19108,6 +19313,102 @@
"kind-of": "^3.2.0"
}
},
+ "socket.io": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.3.tgz",
+ "integrity": "sha512-TC1GnSXhDVmd3bHji5aG7AgWB8UL7E6quACbKra8uFXBqlMwEDbrJFK+tjuIY5Pe9N0L+MAPPDv3pycnn0000A==",
+ "requires": {
+ "@types/cookie": "^0.4.0",
+ "@types/cors": "^2.8.8",
+ "@types/node": "^14.14.7",
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "debug": "~4.1.0",
+ "engine.io": "~4.0.0",
+ "socket.io-adapter": "~2.0.3",
+ "socket.io-parser": "~4.0.1"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "14.14.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
+ "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "socket.io-adapter": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz",
+ "integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ=="
+ },
+ "socket.io-client": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.0.3.tgz",
+ "integrity": "sha512-kwCJAKb6JMqE9ZYXg78Dgt8rYLSwtJ/g/LJqpb/pOTFRZMSr1cKAsCaisHZ+IBwKHBY7DYOOkjtkHqseY3ZLpw==",
+ "requires": {
+ "@types/component-emitter": "^1.2.10",
+ "backo2": "1.0.2",
+ "component-bind": "1.0.0",
+ "component-emitter": "~1.3.0",
+ "debug": "~4.1.0",
+ "engine.io-client": "~4.0.0",
+ "parseuri": "0.0.6",
+ "socket.io-parser": "~4.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "socket.io-parser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz",
+ "integrity": "sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==",
+ "requires": {
+ "@types/component-emitter": "^1.2.10",
+ "component-emitter": "~1.3.0",
+ "debug": "~4.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"sockjs": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
@@ -22198,6 +22499,11 @@
"resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
"integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
},
+ "xmlhttprequest-ssl": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
+ },
"xregexp": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz",
@@ -22544,6 +22850,11 @@
}
}
},
+ "yeast": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
+ },
"yup": {
"version": "0.29.1",
"resolved": "https://registry.npmjs.org/yup/-/yup-0.29.1.tgz",
diff --git a/package.json b/package.json
index 90e092d..6f4e501 100644
--- a/package.json
+++ b/package.json
@@ -80,6 +80,8 @@
"sequelize": "^6.2.4",
"sequelize-cli": "^6.1.0",
"shelljs": "^0.8.4",
+ "socket.io": "^3.0.3",
+ "socket.io-client": "^3.0.3",
"sortablejs": "^1.10.2",
"tmp": "^0.2.1",
"video.js": "^7.8.4",
@@ -87,12 +89,12 @@
"yup": "^0.29.1"
},
"scripts": {
- "start": "react-scripts start",
+ "start": "set HTTPS=true&&react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"server": "nodemon server/app",
- "dev": "HTTPS=true concurrently \"npm run server\" \"npm run start\"",
+ "dev": "concurrently \"npm run server\" \"npm run start\"",
"lint": "eslint --debug src/",
"lint:write": "eslint --debug src/ --fix",
"precommit": "lint-staged"
diff --git a/server/app.js b/server/app.js
index 683dd22..bc5c45a 100644
--- a/server/app.js
+++ b/server/app.js
@@ -12,8 +12,7 @@ const params = require('express-route-params');
const createStore = require('redux')
const Provider = require('react-redux')
const compression = require('compression');
-const morgan = require('morgan')
-const io = require('socket.io')();
+
@@ -379,16 +378,24 @@ app.on('error', error => {
*/
//socket.io
-io.sockets.on('connection', function (socket) {
- io.sockets.emit('getting_data', 'Loading Data for chart');
- setInterval(5000,function(data){
- let q = "SELECT * FROM stock";
- connection.query(q, function(err, rows) {
- if (err) throw err;
- res.end(JSON.stringify(rows))
+let server = app.listen(3001);
+const io = require('socket.io')(server);
+
+// Подключение клиента
+io.on('connection', function (socket) {
+ const { id } = socket.client;
+ console.log(`User connected: ${id}`);
+ setInterval(5000, function (data) {
+ // Подключение к Mysql, с выбором всех данных из таблицы stock
+ let q ="SELECT * FROM stock";
+ connection.query(q, function (err, rows) {
+ if (err) throw err;
+ console.log(rows)
+ // отправление данных на клиент
+ io.emit('showrows', rows);
+ });
});
});
-});
-app.listen(3001);
+
diff --git a/src/views/app/bots/sber.jsx b/src/views/app/bots/sber.jsx
index c9e7791..fb15c02 100644
--- a/src/views/app/bots/sber.jsx
+++ b/src/views/app/bots/sber.jsx
@@ -11,6 +11,7 @@ import * as tf from '@tensorflow/tfjs';
import { TradeGameAgent } from './sber/trade_agent';
import { TradeGame, NUM_ACTIONS, ALL_ACTIONS, getStateTensor } from './sber/trade_game';
+import io from "socket.io-client";
let game;
let qNet;
@@ -151,6 +152,17 @@ export default class Sber extends Component {
// lastTick = [6604.98, 6606, 6604.07, 6606]
componentDidMount() {
+ // Переменные для подключение к серверу
+ let socket = io.connect("http://localhost:3002");
+ console.log(socket)
+ // Подключение к серверу socket
+ socket.on('connection', function(data){
+ console.log('connected', data)
+ })
+ // Вывод массива даты
+ socket.on('showrows', function(rows) {
+ console.log(rows);
+ })
this.getChartData();
this.resetState();
}
From 6d56fa55cd67f35b217c4e2dc0e08be33aafb01a Mon Sep 17 00:00:00 2001
From: Kamynale <47644905+Kamynale@users.noreply.github.com>
Date: Thu, 3 Dec 2020 15:13:59 +0300
Subject: [PATCH 3/3] chart
---
server/app.js | 13 +-
src/views/app/bots/sber.jsx | 271 +++++++++++++-----------------------
2 files changed, 106 insertions(+), 178 deletions(-)
diff --git a/server/app.js b/server/app.js
index bc5c45a..0c1bfe9 100644
--- a/server/app.js
+++ b/server/app.js
@@ -379,22 +379,27 @@ app.on('error', error => {
//socket.io
let server = app.listen(3001);
-const io = require('socket.io')(server);
+const io = require('socket.io')(server, {
+ path: '/test',
+ cors: {
+ origin: '*',
+ }
+});
// Подключение клиента
io.on('connection', function (socket) {
const { id } = socket.client;
console.log(`User connected: ${id}`);
- setInterval(5000, function (data) {
+/* setInterval( function (data) {*/
// Подключение к Mysql, с выбором всех данных из таблицы stock
let q ="SELECT * FROM stock";
- connection.query(q, function (err, rows) {
+ pool.query(q, function (err, rows) {
if (err) throw err;
console.log(rows)
// отправление данных на клиент
io.emit('showrows', rows);
});
- });
+/* },5000);*/
});
diff --git a/src/views/app/bots/sber.jsx b/src/views/app/bots/sber.jsx
index fb15c02..c51a0d8 100644
--- a/src/views/app/bots/sber.jsx
+++ b/src/views/app/bots/sber.jsx
@@ -1,7 +1,5 @@
import React, { Component } from 'react';
import { Row, Button } from 'reactstrap';
-import Chart from 'react-apexcharts';
-import ApexCharts from 'apexcharts';
import { Colxx, Separator } from '../../../components/common/CustomBootstrap';
import Breadcrumb from '../../../containers/navs/Breadcrumb';
import IconCard from '../../../components/cards/IconCard';
@@ -11,7 +9,9 @@ import * as tf from '@tensorflow/tfjs';
import { TradeGameAgent } from './sber/trade_agent';
import { TradeGame, NUM_ACTIONS, ALL_ACTIONS, getStateTensor } from './sber/trade_game';
+import Chart from 'kaktana-react-lightweight-charts'
import io from "socket.io-client";
+import {replace} from "formik";
let game;
let qNet;
@@ -101,171 +101,99 @@ export default class Sber extends Component {
super(props);
this.state = {
- balance: 10000,
- stocks: 0,
- maxBuyStocks: 40,
- lastStockPrice: 0,
- commission: 0.05,
- logs: [],
-
- series: [{
- data: [],
- }],
- options: {
- chart: {
- id: 'ticks_chart',
- type: 'candlestick',
- height: 350,
- },
- title: {
- text: 'CandleStick Chart',
- align: 'left',
- },
- xaxis: {
- // type: 'datetime',
- type: 'numeric'
- },
- yaxis: {
- tooltip: {
- enabled: true,
+ balance: 10000,
+ stocks: 0,
+ maxBuyStocks: 40,
+ lastStockPrice: 0,
+ commission: 0.05,
+ logs: [],
+
+ series: [{
+ data: [],
+ }],
+/* options: {
+ chart: {
+ id: 'ticks_chart',
+ type: 'candlestick',
+ height: 350,
+ },
+ title: {
+ text: 'CandleStick Chart',
+ align: 'left',
},
- },
+ xaxis: {
+ // type: 'datetime',
+ type: 'numeric'
+ },
+ yaxis: {
+ tooltip: {
+ enabled: true,
+ },
+ },
+ },*/
+ // Берём данные из LS, чтобы при возврате рисовался интересующий график.
+ currentTicks: window.localStorage.getItem('ticks') || '5min',
+ //Начало настроек для нового графика
+ options: {
+ alignLabels: true,
+ timeScale: {
+ rightOffset: 12,
+ barSpacing: 3,
+ fixLeftEdge: true,
+ lockVisibleTimeRangeOnResize: true,
+ rightBarStaysOnScroll: true,
+ borderVisible: true,
+ borderColor: "#fff000",
+ visible: true,
+ timeVisible: true,
+ secondsVisible: false
+ }
},
- // Берём данные из LS, чтобы при возврате рисовался интересующий график.
- currentTicks: window.localStorage.getItem('ticks') || '5min',
- };
- }
-
- resetState() {
- this.setState({
- balance: 10000,
- stocks: 0,
- maxBuyStocks: 40,
- lastStockPrice: 0,
- commission: 0.05,
- logs: [],
- });
- }
-
- // lastDate = 1538884800000
- // [Timestamp, O, H, L, C]
- // lastTick = [6604.98, 6606, 6604.07, 6606]
-
- componentDidMount() {
- // Переменные для подключение к серверу
- let socket = io.connect("http://localhost:3002");
- console.log(socket)
- // Подключение к серверу socket
- socket.on('connection', function(data){
- console.log('connected', data)
- })
- // Вывод массива даты
- socket.on('showrows', function(rows) {
- console.log(rows);
- })
- this.getChartData();
- this.resetState();
- }
-
- componentDidUpdate() {
- if(!this.state.interactive) {
- // this.getChartData();
+ // Дата для нового графика из mysql
+ candlestickSeries: [{
+ data: [
+/* { time: '', open: '', high: '', low: '', close: '' }*/
+ ]
+ }]
}
}
- getHost(postfix) {
- // Костыль для локальной разработки, чтобы порты сервера и клиента разнести.
- // TODO: сделать в едином месте
- let host = `https://${window.location.host}/api/stocks/${postfix}`;
- if (host.indexOf('3000') !== -1) {
- // TODO: сделать в едином месте
- host = host.replace('3000', '3001').replace('https', 'http');
- }
-
- return host;
- }
-
- getChartData() {
- this.loadedData || (this.loadedData = {});
- const current = this.loadedData[this.state.currentTicks];
- if (this.loadedData[this.state.currentTicks] === true) {
- return;
- } else if (current) {
- ApexCharts.exec('ticks_chart', 'updateSeries', [{
- data: this.loadedData[this.state.currentTicks].series[0].data,
- }]);
- this.setState(this.loadedData[this.state.currentTicks]);
- return;
- } else {
- this.loadedData[this.state.currentTicks] = true;
- }
-
- /*
- {
- x: new Date(1538874000000),
- y: [6600.55, 6605, 6589.14, 6593.01],
- },
- */
- const x = new XMLHttpRequest();
- x.open('GET', this.getHost(`ticks/${this.state.currentTicks}`), true);
- x.onload = () => {
- const res = x.responseText && JSON.parse(x.responseText);
-
- const series = this.state.series.slice(0);
- let name;
-
- series[0].data = !res || !Object.keys(res).length ? [] : res.map((t, i) => {
- // ticker, per, date, time, open, hight, low, close, vol (объём торгов)
- // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370
- const tick = t.split(',');
-
- if (!name) {
- name = tick[0];
- }
-
- if (!tick[2] || !tick[3]) {
- return false;
- }
-
- // console.log(`${tick[2]} ${tick[3]}`, [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])]);
- // [Timestamp, O, H, L, C]
- return {
- x: `${tick[2]} ${tick[3]}`,
- y: [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])],
-
- };
+ componentDidMount() {
+ // Переменные для подключение к серверу
+ let socket = io.connect("http://localhost:3001", {
+ path: '/test'
+ });
+ console.log(socket)
+ // Подключение к серверу socket
+ socket.on('connection', function(data){
+ console.log('connected', data)
})
- .filter(Boolean);
-
- this.loadedData[this.state.currentTicks] = {
- series,
- options: {
- ...this.state.options,
- title: {
- ...this.state.options.title,
- text: name,
- },
- },
- stocksData: res.map(r => {
- const tick = r.split(',');
- if (!tick[2] || !tick[3]) {
- return false;
- }
-
- // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370
- // Для упрощения наблюдений увеличиваем стоимость акций, чтобы следить за целыми числами
- return [tick[2] + ' ' + tick[3], parseInt(tick[5] * 10, 10), tick[8]];
- }).filter(Boolean)
- };
-
- this.setState(this.loadedData[this.state.currentTicks]);
-
- // ApexCharts.exec('ticks_chart', 'updateSeries', [{
- // data: series[0].data,
- // }]);
- };
- x.withCredentials = true;
- x.send();
+ // Вывод массива даты и перебор из mysql
+ socket.on('showrows', function(rows) {
+ let arrRows = JSON.stringify(rows)
+ console.log(arrRows)
+ arrRows.split("},").forEach(function (line) {
+ const arr = line.toString().split(',')
+ console.log(arr)
+ const vol = arr.map(elem => elem.trim());
+/* console.log(vol[3], vol[5], vol[6], vol[7], vol[8]);*/
+ let dataChart = vol[3]+' '+vol[5]+' '+vol[6]+' '+vol[7]+' '+vol[8]
+ //чистил и преобразовал массив
+ let arrTick = dataChart.replace('"date":"', '').replace('Z"', 'Z').replace('"open":', '').replace('"high":', '').replace('"low":', '').replace('"close":', '').split(' ');
+ console.log(arrTick)
+ let d = {time:arrTick[0],open:arrTick[1],high:arrTick[2],low:arrTick[3],close:arrTick[4]}
+ console.log(d)
+ this.setState.candlestickSeries({data:d})
+ /*this.setState.candlestickSeries.data({time:arrTick[0],open:arrTick[1],high:arrTick[2],low:arrTick[3],close:arrTick[4]})*/
+ })
+
+/* rows.forEach(function (line) {
+ const arr = line.toString().split(',')
+ console.log(arr)
+ const vol = arr.map(elem => elem.trim());
+ console.log(vol[8])
+ })*/
+ })
}
render() {
@@ -278,8 +206,8 @@ export default class Sber extends Component {
{this.props.match && }
-
-
+
+
{/*
@@ -304,19 +232,12 @@ export default class Sber extends Component {
)}
*/}
+{/* Рендер чарта*/}
- {Boolean(this.state.series[0].data.length) && (
-
- )}
-
-
-
+
+
+