From 44c9351ced980e671fcd34c13a6d5ace8f818075 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期三, 09 十月 2024 10:35:27 +0800
Subject: [PATCH] #
---
zy-acs-flow/src/map/websocket.js | 83 ++++++++++++++++++++
zy-acs-flow/src/map/tool.js | 20 +++++
zy-acs-flow/src/map/Notification.jsx | 51 ++++++++++++
zy-acs-flow/src/map/MapPage.jsx | 32 ++++++-
4 files changed, 181 insertions(+), 5 deletions(-)
diff --git a/zy-acs-flow/src/map/MapPage.jsx b/zy-acs-flow/src/map/MapPage.jsx
index 031d5b1..668d32c 100644
--- a/zy-acs-flow/src/map/MapPage.jsx
+++ b/zy-acs-flow/src/map/MapPage.jsx
@@ -8,6 +8,7 @@
SpeedDial,
SpeedDialAction,
useTheme,
+ Snackbar,
} from '@mui/material';
import {
MoreVert as MoreVertIcon,
@@ -18,16 +19,19 @@
Share as ShareIcon,
} from '@mui/icons-material';
import Player from './player';
+import * as Tool from './tool';
+import { NotificationProvider, useNotification } from './Notification';
let player;
-const MapPage = () => {
+const Map = () => {
const mapRef = useRef();
const contentRef = React.useRef();
const [app, setApp] = useState(null);
const [mapContainer, setMapContainer] = React.useState(null);
+ const notify = useNotification();
- const [mode, setMode] = useState('monitoring');
+ const [mode, setMode] = useState(MapModel.OBSERVER_MODEL);
const theme = useTheme();
const themeMode = theme.palette.mode;
@@ -43,6 +47,8 @@
player = new Player(mapRef.current, themeMode);
setApp(player.app);
setMapContainer(player.mapContainer);
+ Tool.setApp(player.app);
+ Tool.setMapContainer(player.mapContainer);
}
initialize();
@@ -56,6 +62,8 @@
};
handleResize();
window.addEventListener('resize', handleResize);
+
+ notify('Welcome to Rcs', 'info');
return () => {
player.destroy();
@@ -122,9 +130,9 @@
borderRadius: 1,
}}
>
- <MenuItem value="monitoring">鐩戞帶妯″紡</MenuItem>
- <MenuItem value="edit">缂栬緫妯″紡</MenuItem>
- <MenuItem value="configuration">閰嶇疆妯″紡</MenuItem>
+ <MenuItem value={MapModel.OBSERVER_MODEL}>鐩戞帶妯″紡</MenuItem>
+ <MenuItem value={MapModel.MOVABLE_MODEL}>缂栬緫妯″紡</MenuItem>
+ <MenuItem value={MapModel.SETTINGS_MODEL}>閰嶇疆妯″紡</MenuItem>
</Select>
<Button
variant="contained"
@@ -181,4 +189,18 @@
);
}
+const MapPage = () => {
+ return (
+ <NotificationProvider>
+ <Map />
+ </NotificationProvider>
+ )
+}
+
+export const MapModel = Object.freeze({
+ OBSERVER_MODEL: "1",
+ MOVABLE_MODEL: "2",
+ SETTINGS_MODEL: "3",
+})
+
export default MapPage;
diff --git a/zy-acs-flow/src/map/Notification.jsx b/zy-acs-flow/src/map/Notification.jsx
new file mode 100644
index 0000000..ecfb3e7
--- /dev/null
+++ b/zy-acs-flow/src/map/Notification.jsx
@@ -0,0 +1,51 @@
+import React, { createContext, useContext, useState, useCallback } from 'react';
+import { Snackbar, Alert, Portal, Slide } from '@mui/material';
+
+const NotificationContext = createContext();
+
+const SlideTransition = (props) => {
+ return <Slide {...props} direction="up" />;
+}
+
+export const NotificationProvider = ({ children }) => {
+ const [notification, setNotification] = useState({
+ open: false,
+ message: '',
+ severity: 'info',
+ });
+
+ const showNotification = useCallback((message, severity = 'info') => {
+ setNotification({ open: true, message, severity });
+ }, []);
+
+ const handleClose = () => {
+ setNotification({ ...notification, open: false });
+ };
+
+ return (
+ <NotificationContext.Provider value={showNotification}>
+ {children}
+ <Portal>
+ <Snackbar
+ open={notification.open}
+ autoHideDuration={4000}
+ onClose={handleClose}
+ TransitionComponent={SlideTransition}
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
+ sx={{
+ // mt: 12,
+ zIndex: 2000,
+ }}
+ >
+ <Alert onClose={handleClose} severity={notification.severity} sx={{ width: '300px', zIndex: 2000 }}>
+ {notification.message}
+ </Alert>
+ </Snackbar>
+ </Portal>
+ </NotificationContext.Provider>
+ );
+};
+
+export const useNotification = () => {
+ return useContext(NotificationContext);
+};
diff --git a/zy-acs-flow/src/map/tool.js b/zy-acs-flow/src/map/tool.js
new file mode 100644
index 0000000..a445b38
--- /dev/null
+++ b/zy-acs-flow/src/map/tool.js
@@ -0,0 +1,20 @@
+import * as PIXI from 'pixi.js';
+import * as TWEEDLE from 'tweedle.js';
+
+let app, mapContainer;
+
+export function setApp(param) {
+ app = param;
+}
+
+export function setMapContainer(param) {
+ mapContainer = param;
+}
+
+export function getApp() {
+ return app;
+}
+
+export function getMapContainer() {
+ return mapContainer;
+}
diff --git a/zy-acs-flow/src/map/websocket.js b/zy-acs-flow/src/map/websocket.js
new file mode 100644
index 0000000..3c9ec74
--- /dev/null
+++ b/zy-acs-flow/src/map/websocket.js
@@ -0,0 +1,83 @@
+import { WEBSOCKET_BASE_URL } from '@/config/setting';
+
+export default class WebSocketClient {
+
+ constructor(path) {
+ this.url = WEBSOCKET_BASE_URL + path;
+ this.webSocket = null;
+ this.heartbeatInterval = null; // Store the interval ID
+ this.heartbeatFrequency = 30000; // Heartbeat every 30 seconds
+ }
+
+ connect() {
+ if (!this.url) {
+ console.error('WebSocketClient: Cannot connect without url.');
+ return;
+ }
+
+ this.webSocket = new WebSocket(this.url);
+
+ this.webSocket.onopen = (event) => {
+ console.log('websocket connection opened.');
+ // Start the heartbeat
+ this.startHeartbeat();
+ };
+
+ this.webSocket.onmessage = (event) => {
+ // console.log('websocket message received:', event.data);
+ this.onMessage(event.data);
+ };
+
+ this.webSocket.onerror = (event) => {
+ console.error('websocket error observed:', event);
+ };
+
+ this.webSocket.onclose = (event) => {
+ console.log('websocket connection closed!');
+ // Clear the heartbeat
+ this.stopHeartbeat();
+ this.reconnect();
+ };
+ }
+
+ sendMessage(message) {
+ if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
+ this.webSocket.send(message);
+ } else {
+ console.error('WebSocketClient: Cannot send message, WebSocket connection is not open.');
+ }
+ }
+
+ // Override
+ onMessage(data) {
+ }
+
+ close() {
+ if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
+ this.webSocket.close();
+ }
+ }
+
+ reconnect() {
+ setTimeout(() => {
+ console.log('WebSocketClient: Attempting to reconnect...');
+ this.connect();
+ }, 3000);
+ }
+
+ startHeartbeat() {
+ if (this.heartbeatInterval) {
+ clearInterval(this.heartbeatInterval);
+ }
+ this.heartbeatInterval = setInterval(() => {
+ this.sendMessage('1');
+ }, this.heartbeatFrequency);
+ }
+
+ stopHeartbeat() {
+ if (this.heartbeatInterval) {
+ clearInterval(this.heartbeatInterval);
+ this.heartbeatInterval = null;
+ }
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.1