1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-28 14:50:08 +03:00

F : Add socket hook in client ()

This commit is contained in:
Sergio Betanzos 2020-11-19 18:40:52 +01:00 committed by GitHub
parent 6fe6728da9
commit 9f77261af5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 169 additions and 41 deletions
src/fireedge/src/client
app.js
components/Header
constants
containers/Webconsole
hooks
providers
services

@ -20,6 +20,7 @@ import { StaticRouter, BrowserRouter } from 'react-router-dom'
import { Provider as ReduxProvider } from 'react-redux'
import root from 'window-or-global'
import SocketProvider from 'client/providers/socketProvider'
import MuiProvider from 'client/providers/muiProvider'
import NotistackProvider from 'client/providers/notistackProvider'
import { TranslateProvider } from 'client/components/HOC'
@ -48,19 +49,21 @@ const App = ({ location, context, store, app }) => {
<MuiProvider app={appName} location={location}>
<ReduxProvider store={store}>
<NotistackProvider>
<TranslateProvider>
{location && context ? (
// server build
<StaticRouter location={location} context={context}>
<Router app={appName} />
</StaticRouter>
) : (
// browser build
<BrowserRouter basename={`/${appName}`}>
<Router app={appName} />
</BrowserRouter>
)}
</TranslateProvider>
<SocketProvider>
<TranslateProvider>
{location && context ? (
// server build
<StaticRouter location={location} context={context}>
<Router app={appName} />
</StaticRouter>
) : (
// browser build
<BrowserRouter basename={`/${appName}`}>
<Router app={appName} />
</BrowserRouter>
)}
</TranslateProvider>
</SocketProvider>
</NotistackProvider>
</ReduxProvider>
</MuiProvider>

@ -1,12 +1,13 @@
import React from 'react'
import React, { memo } from 'react'
import { MenuItem, MenuList } from '@material-ui/core'
import LanguageIcon from '@material-ui/icons/Language'
import { Tr } from 'client/components/HOC'
import HeaderPopover from 'client/components/Header/Popover'
import { Tr } from 'client/components/HOC'
import { ZoneLabel } from 'client/constants/translates'
const Zone = React.memo(() => (
const Zone = memo(() => (
<HeaderPopover
id="zone-menu"
icon={<LanguageIcon />}
@ -15,7 +16,9 @@ const Zone = React.memo(() => (
>
{({ handleClose }) => (
<MenuList>
<MenuItem onClick={handleClose}>{Tr('Zone')}</MenuItem>
<MenuItem onClick={handleClose}>
{Tr(ZoneLabel)}
</MenuItem>
</MenuList>
)}
</HeaderPopover>

@ -33,6 +33,7 @@ module.exports = {
/* sections */
Dashboard: 'Dashboard',
Settings: 'Settings',
ZoneLabel: 'Zone',
ApplicationsTemplates: 'Applications templates',
ApplicationsInstances: 'Applications instances',
ProviderLabel: 'Provider',

@ -1,4 +1,4 @@
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
@ -13,31 +13,67 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import React, { useState, useEffect } from 'react'
import io from 'socket.io-client'
import { findStorageData } from 'client/utils'
import { JWT_NAME } from 'client/constants'
import { defaultPort } from 'server/utils/constants/defaults'
import React, { useState, useEffect, memo } from 'react'
const ENDPOINT = `http://127.0.0.1:${defaultPort}`
import { Button, makeStyles } from '@material-ui/core'
import useSocket from 'client/hooks/useSocket'
const Webconsole = ({ zone }) => {
const [response, setResponse] = useState({})
const useStyles = makeStyles(() => ({
sticky: { position: 'sticky', top: 0, backgroundColor: '#fafafa' },
loading: {
'&::after': {
overflow: 'hidden',
display: 'inline-block',
verticalAlign: 'bottom',
animation: '$ellipsis steps(4,end) 1000ms infinite',
content: '"\\2026"', /* ascii code for the ellipsis character */
width: 0
}
},
'@keyframes ellipsis': {
to: { width: 20 }
}
}))
const ResponseComponent = memo(response => (
<p style={{ wordBreak: 'break-all' }}>{JSON.stringify(response)}</p>
))
ResponseComponent.displayName = 'ResponseComponent'
const Webconsole = () => {
const classes = useStyles()
const [listening, setListening] = useState(false)
const [response, setResponse] = useState([])
const { getHooks } = useSocket()
const toggleListening = () => setListening(list => !list)
useEffect(() => {
const socket = io(ENDPOINT, {
path: '/websocket',
query: {
token: findStorageData(JWT_NAME),
zone
}
})
socket.on('hooks', data => {
setResponse(data)
})
return () => { socket.disconnect() }
}, [zone])
console.log('-->', response)
return <p />
listening
? getHooks.on(data => setResponse(prev => [...prev, data]))
: getHooks.off()
return getHooks.off
}, [listening])
return (
<>
<div className={classes.sticky}>
<p className={listening ? classes.loading : ''}>
{`socket is ${listening ? '' : 'not'} listening`}
</p>
<Button
variant="contained"
color="primary"
onClick={toggleListening}>
{listening ? 'Disconnect' : 'Connect'}
</Button>
</div>
{response?.map((res, index) =>
<ResponseComponent key={index} {...res} />
)}
</>
)
}
export default Webconsole

@ -4,7 +4,7 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux'
import * as actions from 'client/actions/general'
export default function useGeneral () {
const { isLoading, isOpenMenu, isFixMenu } = useSelector(
const { zone, isLoading, isOpenMenu, isFixMenu } = useSelector(
state => state?.General,
shallowEqual
)
@ -38,6 +38,7 @@ export default function useGeneral () {
)
return {
zone,
isLoading,
isOpenMenu,
isFixMenu,

@ -0,0 +1,24 @@
import { useContext, useMemo } from 'react'
import { SocketContext } from 'client/providers/socketProvider'
const SOCKETS = {
hooks: 'hooks',
provision: 'provision'
}
export default function useSocket () {
const { socket, isConnected } = useContext(SocketContext)
const getHooks = useMemo(() => ({
on: (func) => isConnected && socket.on(SOCKETS.hooks, func),
off: () => isConnected && socket.off()
}), [socket, isConnected])
const getProvision = useMemo(() => ({
on: (func) => isConnected && socket.on(SOCKETS.provision, func),
off: () => isConnected && socket.off()
}), [socket, isConnected])
return { isConnected, getHooks, getProvision }
}

@ -0,0 +1,52 @@
import React, { createContext, useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import * as serviceSocket from 'client/services/socket'
const CONNECT = 'connect'
const DISCONNECT = 'disconnect'
export const SocketContext = createContext(null)
const SocketProvider = ({ children }) => {
const [socket, setSocket] = useState({})
const [isConnected, setConnected] = useState(false)
const { jwt, zone } = useSelector(state => ({
zone: state?.General?.zone,
jwt: state?.Authenticated?.jwt
}))
useEffect(() => {
if (!jwt) return
const client = serviceSocket.websocket({ token: jwt, zone })
client.on(CONNECT, () => setConnected(true))
client.on(DISCONNECT, () => setConnected(false))
setSocket(client)
return () => {
setSocket(null)
return client.disconnect()
}
}, [jwt, zone])
return (
<SocketContext.Provider value={{ socket, isConnected }}>
{children}
</SocketContext.Provider>
)
}
SocketProvider.propTypes = {
children: PropTypes.oneOfType([
PropTypes.node,
PropTypes.arrayOf(PropTypes.node)
])
}
SocketProvider.defaultProps = {
children: undefined
}
export default SocketProvider

@ -0,0 +1,8 @@
import io from 'socket.io-client'
export const websocket = query => io({
path: '/websocket',
query
})
export default { websocket }