Browse Source

websocket

pull/3/head
yuan_yi 3 years ago
parent
commit
0c1b8f8d99
  1. 10
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  2. 3
      code/VideoAccess-VCMP/api/app/lib/index.js
  3. 26
      code/VideoAccess-VCMP/api/app/lib/service/socket.js
  4. 2
      code/VideoAccess-VCMP/web/client/src/app.jsx
  5. 5
      code/VideoAccess-VCMP/web/client/src/layout/actions/global.js
  6. 9
      code/VideoAccess-VCMP/web/client/src/layout/actions/index.js
  7. 31
      code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js
  8. 10
      code/VideoAccess-VCMP/web/client/src/layout/components/header/index.jsx
  9. 5
      code/VideoAccess-VCMP/web/client/src/layout/index.jsx
  10. 15
      code/VideoAccess-VCMP/web/client/src/layout/reducers/global.js
  11. 4
      code/VideoAccess-VCMP/web/client/src/layout/reducers/index.js
  12. 21
      code/VideoAccess-VCMP/web/client/src/layout/reducers/webSocket.js
  13. 4
      code/VideoAccess-VCMP/web/client/src/sections/auth/actions/auth.js
  14. 5
      code/VideoAccess-VCMP/web/client/src/sections/auth/actions/index.js
  15. 13
      code/VideoAccess-VCMP/web/client/src/sections/auth/containers/login.jsx
  16. 19
      code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx

10
code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js

@ -46,8 +46,12 @@ async function edit (ctx, next) {
async function get (ctx) {
const models = ctx.fs.dc.models;
try {
const { limit, offset, orderBy, orderDirection } = ctx.query
const { limit, page, orderBy, orderDirection } = ctx.query
let findOption = {
attributes: { exclude: ['delete'] },
where: {
delete: false,
},
order: [
[orderBy || 'id', orderDirection || 'DESC']
]
@ -55,8 +59,8 @@ async function get (ctx) {
if (limit) {
findOption.limit = limit
}
if (offset) {
findOption.offset = offset
if (page && limit) {
findOption.offset = page * limit
}
const res = await models.Nvr.findAll(findOption)

3
code/VideoAccess-VCMP/api/app/lib/index.js

@ -2,6 +2,7 @@
const routes = require('./routes');
const redisConnect = require('./service/redis')
const socketConect = require('./service/socket')
const authenticator = require('./middlewares/authenticator');
// const apiLog = require('./middlewares/api-log');
const businessRest = require('./middlewares/business-rest');
@ -13,7 +14,9 @@ module.exports.entry = function (app, router, opts) {
app.fs.api.authAttr = app.fs.api.authAttr || {};
app.fs.api.logAttr = app.fs.api.logAttr || {};
// 顺序固定 ↓
redisConnect(app, opts)
socketConect(app, opts)
router.use(authenticator(app, opts));
// router.use(businessRest(app, router, opts));

26
code/VideoAccess-VCMP/api/app/lib/service/socket.js

@ -0,0 +1,26 @@
'use strict';
module.exports = async function factory (app, opts) {
app.socket.on('connection', async (socket) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已连接');
socket.on('disconnecting', async (reason) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已断开连接:' + reason);
})
})
// 使用测试
// setInterval(async () => {
// const { connected } = app.socket.sockets
// const roomId = 'ROOM_' + Math.random()
// if (connected) {
// for (let c in connected) {
// connected[c].join(roomId)
// }
// app.socket.to(roomId).emit('TEST', { someProperty: `【星域 ROOM:${roomId}】呼叫自然选择号!!!`, })
// }
// app.socket.emit('TEST', { someProperty: '【广播】呼叫青铜时代号!!!', })
// }, 1000)
}

2
code/VideoAccess-VCMP/web/client/src/app.jsx

@ -3,7 +3,7 @@
import React, { useEffect } from 'react';
import Layout from './layout';
import Auth from './sections/auth';
// import Example from './sections/example';
import Example from './sections/example';
import EquipmentWarehouse from './sections/equipmentWarehouse';
const App = props => {

5
code/VideoAccess-VCMP/web/client/src/layout/actions/global.js

@ -2,8 +2,6 @@
import { RouteRequest } from '@peace/utils';
import { RouteTable } from '$utils'
// import io from 'socket.io-client';
export const INIT_LAYOUT = 'INIT_LAYOUT';
export function initLayout (title, copyright, sections, actions) {
return {
@ -35,9 +33,6 @@ export function initApiRoot () {
return dispatch => {
RouteRequest.get(RouteTable.apiRoot).then(res => {
localStorage.setItem('apiRoot', res.root);
// const socket = io('ws://127.0.0.1:4000', () => { });
dispatch({
type: INIT_API_ROOT,
payload: {

9
code/VideoAccess-VCMP/web/client/src/layout/actions/index.js

@ -0,0 +1,9 @@
'use strict';
import * as global from './global'
import * as socket from './webSocket';
export default {
...global,
...socket,
};

31
code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js

@ -0,0 +1,31 @@
'use strict';
import io from 'socket.io-client';
export const INIT_WEB_SOCKET = 'INIT_WEB_SOCKET'
export function initWebSocket ({ ioUrl, token }) {
if (!ioUrl) {
ioUrl = localStorage.getItem('apiRoot')
}
if (!token) {
const user = sessionStorage.getItem('user')
token = JSON.parse(user).token
}
if (!ioUrl || !token) {
return {
type: '',
}
}
return dispatch => {
const socket = io(ioUrl, {
query: {
token: token
}
});
dispatch({
type: INIT_WEB_SOCKET,
payload: {
socket: socket
}
})
}
}

10
code/VideoAccess-VCMP/web/client/src/layout/components/header/index.jsx

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { Nav } from '@douyinfe/semi-ui';
const Header = props => {
const { dispatch, history, user, actions } = props
const { dispatch, history, user, actions, socket } = props
return (
<div style={{ position: 'relative', height: 60, minWidth: 520 }}>
@ -20,6 +20,9 @@ const Header = props => {
<Nav mode={'horizontal'} onClick={({ itemKey }) => {
if (itemKey == 'logout') {
dispatch(actions.auth.logout(user));
if (socket) {
socket.disconnect()
}
history.push(`/signin`);
}
}}>
@ -33,10 +36,11 @@ const Header = props => {
};
function mapStateToProps (state) {
const { global, auth } = state;
const { global, auth, webSocket } = state;
return {
actions: global.actions,
user: auth.user
user: auth.user,
socket: webSocket.socket
};
}

5
code/VideoAccess-VCMP/web/client/src/layout/index.jsx

@ -8,14 +8,14 @@ import { ConnectedRouter } from 'connected-react-router'
import { Layout, NoMatch } from './containers';
import { Switch, Route } from "react-router-dom";
import { ConfigProvider } from '@douyinfe/semi-ui';
import * as layoutActions from './actions/global';
import layoutActions from './actions';
import zhCN from '@douyinfe/semi-ui/lib/es/locale/source/zh_CN';
import { basicReducer } from '@peace/utils';
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
const { initLayout, initApiRoot, resize } = layoutActions;
const { initLayout, initApiRoot, resize, initWebSocket } = layoutActions;
const Root = props => {
const { sections, title, copyright } = props;
@ -124,6 +124,7 @@ const Root = props => {
store.dispatch(initLayout(title, copyright, sections, actions));
store.dispatch(resize(document.body.clientHeight, document.body.clientWidth));
store.dispatch(actions.auth.initAuth());
store.dispatch(initWebSocket({}))
store.dispatch(initApiRoot())
const combineRoutes = flatRoutes(innerRoutes);

15
code/VideoAccess-VCMP/web/client/src/layout/reducers/global.js

@ -1,6 +1,6 @@
'use strict';
import Immutable from 'immutable';
import { INIT_LAYOUT, RESIZE } from '../actions/global';
import { INIT_LAYOUT, RESIZE, INIT_API_ROOT } from '../actions/global';
function global (state = {
title: '',
@ -9,7 +9,8 @@ function global (state = {
actions: {},
plugins: {},
clientHeight: 768,
clientWidth: 1024
clientWidth: 1024,
apiRoot: '',
}, action) {
const payload = action.payload;
switch (action.type) {
@ -19,15 +20,17 @@ function global (state = {
clientWidth: payload.clientWidth
}).toJS();
case INIT_LAYOUT:
return {
return Immutable.fromJS(state).merge({
title: payload.title,
copyright: payload.copyright,
sections: payload.sections,
actions: payload.actions,
plugins: payload.plugins,
clientHeight: state.clientHeight,
detailsComponent: null
};
}).toJS();
case INIT_API_ROOT:
return Immutable.fromJS(state).merge({
apiRoot: payload.apiRoot,
}).toJS();
default:
return state;
}

4
code/VideoAccess-VCMP/web/client/src/layout/reducers/index.js

@ -7,9 +7,11 @@
'use strict';
import global from './global';
import webSocket from './webSocket'
import ajaxResponse from './ajaxResponse';
export default {
global,
ajaxResponse
webSocket,
ajaxResponse,
};

21
code/VideoAccess-VCMP/web/client/src/layout/reducers/webSocket.js

@ -0,0 +1,21 @@
'use strict';
import * as actionTypes from '../actions/webSocket';
import Immutable from 'immutable';
const initState = {
socket: null,
};
function webSocket (state = initState, action) {
const payload = action.payload;
switch (action.type) {
case actionTypes.INIT_WEB_SOCKET:
return Immutable.fromJS(state).merge({
socket: payload.socket,
}).toJS();
default:
return state;
}
}
export default webSocket;

4
code/VideoAccess-VCMP/web/client/src/sections/auth/actions/auth.js

@ -41,13 +41,13 @@ export function login (username, password) {
return AuthRequest.post(ApiTable.login, { username, password })
.then(user => {
sessionStorage.setItem('user', JSON.stringify(user));
dispatch({
return dispatch({
type: LOGIN_SUCCESS,
payload: { user: user },
});
}, error => {
let { body } = error.response;
dispatch({
return dispatch({
type: LOGIN_ERROR,
payload: {
error: body && body.message ? body.message : '登录失败'

5
code/VideoAccess-VCMP/web/client/src/sections/auth/actions/index.js

@ -1,8 +1,5 @@
/**
* Created by liu.xinyi
* on 2016/4/1.
*/
'use strict';
import auth from './auth';
export default {

13
code/VideoAccess-VCMP/web/client/src/sections/auth/containers/login.jsx

@ -3,10 +3,10 @@ import React, { useEffect, useRef } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { Form, Button, Toast } from '@douyinfe/semi-ui';
import { login } from '../actions/auth';
import { login, LOGIN_SUCCESS } from '../actions/auth';
const Login = props => {
const { dispatch, user, error, isRequesting } = props
const { dispatch, user, error, actions, apiRoot, isRequesting } = props
const form = useRef();
useEffect(() => {
@ -37,7 +37,10 @@ const Login = props => {
<p style={{ fontSize: 21, fontWeight: 'bold', textAlign: 'center' }}>飞尚物联</p>
<Form
onSubmit={values => {
dispatch(login(values.username, values.password))
dispatch(login(values.username, values.password)).then(res => {
const data = res.payload.user
dispatch(actions.layout.initWebSocket({ ioUrl: apiRoot, token: data.token }))
})
}}
getFormApi={formApi => form.current = formApi}
>
@ -51,10 +54,12 @@ const Login = props => {
}
function mapStateToProps (state) {
const { auth } = state;
const { auth, global } = state;
return {
user: auth.user,
error: auth.error,
actions: global.actions,
apiRoot: global.apiRoot,
isRequesting: auth.isRequesting
}
}

19
code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx

@ -5,13 +5,25 @@ import '../style.less'
const { Meta } = Card;
const Example = (props) => {
const { dispatch, actions, user, loading } = props
const { dispatch, actions, user, loading, socket } = props
useEffect(() => {
// ACTION
dispatch(actions.example.getMembers(user.orgId))
}, [])
// websocket 使
useEffect(() => {
if (socket) {
socket.on('TEST', function (msg) {
console.info(msg);
});
return () => {
socket.off("TEST");
}
}
}, [socket])
return (
<Spin tip="biubiubiu~" spinning={loading}>
<div id='example'>
@ -33,12 +45,13 @@ const Example = (props) => {
}
function mapStateToProps (state) {
const { auth, global, members } = state;
const { auth, global, members, webSocket } = state;
return {
loading: members.isRequesting,
user: auth.user,
actions: global.actions,
members: members.data
members: members.data,
socket: webSocket.socket
};
}

Loading…
Cancel
Save