websocket
parent
9df013f603
commit
6f411232bd
47
src/App.js
47
src/App.js
|
@ -5,37 +5,21 @@ import PageContent from "./Components/PageContent";
|
||||||
import SideMenu from "./Components/SideMenu";
|
import SideMenu from "./Components/SideMenu";
|
||||||
import Login from "./Pages/Login";
|
import Login from "./Pages/Login";
|
||||||
import { Layout } from "antd";
|
import { Layout } from "antd";
|
||||||
import { Constants, ClientUserDataPreview, ClientUserData } from "./constants";
|
import {
|
||||||
|
Constants,
|
||||||
function useUserSession() {
|
ClientUserDataContextPreview,
|
||||||
const getUserSession = () => {
|
ClientUserDataContext,
|
||||||
return JSON.parse(localStorage.getItem("session"));
|
UseUserSession,
|
||||||
};
|
WebSocketProvider,
|
||||||
|
} from "./utils";
|
||||||
const [userSession, setUserSession] = useState(getUserSession());
|
|
||||||
|
|
||||||
const saveUserSession = (session) => {
|
|
||||||
setUserSession(session);
|
|
||||||
|
|
||||||
if (session === undefined) {
|
|
||||||
localStorage.removeItem("session");
|
|
||||||
} else {
|
|
||||||
localStorage.setItem("session", JSON.stringify(session));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
setUserSession: saveUserSession,
|
|
||||||
userSession,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const { userSession, setUserSession } = useUserSession();
|
const { userSession, setUserSession } = UseUserSession();
|
||||||
const [userData, setUserData] = useState(ClientUserDataPreview);
|
const [userData, setUserData] = useState(ClientUserDataContextPreview);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userSession) return;
|
if (!userSession) return;
|
||||||
|
|
||||||
fetch(Constants.API_ADDRESS + "/user", {
|
fetch(Constants.API_ADDRESS + "/user", {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
|
||||||
|
@ -49,6 +33,7 @@ export default function App() {
|
||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setUserSession();
|
||||||
return Promise.reject(res.status);
|
return Promise.reject(res.status);
|
||||||
})
|
})
|
||||||
.then((data) => setUserData(data))
|
.then((data) => setUserData(data))
|
||||||
|
@ -61,10 +46,12 @@ export default function App() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout style={{ minHeight: "100vh" }}>
|
<Layout style={{ minHeight: "100vh" }}>
|
||||||
<ClientUserData.Provider value={userData}>
|
<ClientUserDataContext.Provider value={userData}>
|
||||||
<SideMenu setUserSession={setUserSession}></SideMenu>
|
<WebSocketProvider userSession={userSession}>
|
||||||
<PageContent></PageContent>
|
<SideMenu setUserSession={setUserSession}></SideMenu>
|
||||||
</ClientUserData.Provider>
|
<PageContent></PageContent>
|
||||||
|
</WebSocketProvider>
|
||||||
|
</ClientUserDataContext.Provider>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,19 @@ import Sider from "antd/es/layout/Sider";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { ClientUserData, Constants, UseUserSession } from "../../constants";
|
import {
|
||||||
|
ClientUserDataContext,
|
||||||
|
Constants,
|
||||||
|
UseUserSession,
|
||||||
|
WebSocketTestContext,
|
||||||
|
} from "../../utils";
|
||||||
|
|
||||||
export default function SideMenu({ setUserSession }) {
|
export default function SideMenu({ setUserSession }) {
|
||||||
const { userSession } = UseUserSession();
|
const { userSession } = UseUserSession();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [selectedKeys, setSelectedKeys] = useState("/");
|
const [selectedKeys, setSelectedKeys] = useState("/");
|
||||||
const clientUserData = useContext(ClientUserData);
|
const clientUserDataContext = useContext(ClientUserDataContext);
|
||||||
|
const webSocketTestContext = useContext(WebSocketTestContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const pathName = location.pathname;
|
const pathName = location.pathname;
|
||||||
|
@ -67,10 +73,21 @@ export default function SideMenu({ setUserSession }) {
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
icon: <Badge status="success" text="Connected" />,
|
icon: (
|
||||||
|
<Badge
|
||||||
|
status={webSocketTestContext.connectionBadgeStatus}
|
||||||
|
text={`${
|
||||||
|
webSocketTestContext.connectedWebSocketUsersCount
|
||||||
|
} ${
|
||||||
|
webSocketTestContext.connectedWebSocketUsersCount == 1
|
||||||
|
? "user"
|
||||||
|
: "users"
|
||||||
|
} connected`}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: clientUserData.Username,
|
label: clientUserDataContext.Username,
|
||||||
icon: <UserOutlined />,
|
icon: <UserOutlined />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { LockOutlined, LoginOutlined, UserOutlined } from "@ant-design/icons";
|
import { LockOutlined, LoginOutlined, UserOutlined } from "@ant-design/icons";
|
||||||
import { Button, Form, Input, Modal, notification } from "antd";
|
import { Button, Form, Input, Modal, notification } from "antd";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { Constants } from "../../constants";
|
import { Constants } from "../../utils";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Buffer } from "buffer";
|
import { Buffer } from "buffer";
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { createContext, useState } from "react";
|
|
||||||
|
|
||||||
export const Constants = {
|
|
||||||
API_ADDRESS: "http://localhost:8080/v1",
|
|
||||||
};
|
|
||||||
|
|
||||||
let l = "loading...";
|
|
||||||
|
|
||||||
// for the data preview when the request is not finished
|
|
||||||
export const ClientUserDataPreview = {
|
|
||||||
Username: l,
|
|
||||||
Email: l,
|
|
||||||
};
|
|
||||||
|
|
||||||
export let ClientUserData = createContext(null);
|
|
||||||
|
|
||||||
export function UseUserSession() {
|
|
||||||
const getUserSession = () => {
|
|
||||||
return JSON.parse(localStorage.getItem("session"));
|
|
||||||
};
|
|
||||||
|
|
||||||
const [userSession, setUserSession] = useState(getUserSession());
|
|
||||||
|
|
||||||
const saveUserSession = (session) => {
|
|
||||||
setUserSession(session);
|
|
||||||
|
|
||||||
if (session === undefined) {
|
|
||||||
localStorage.removeItem("session");
|
|
||||||
} else {
|
|
||||||
localStorage.setItem("session", JSON.stringify(session));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
setUserSession: saveUserSession,
|
|
||||||
userSession,
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
import { createContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constants
|
||||||
|
*/
|
||||||
|
export const Constants = {
|
||||||
|
API_ADDRESS: "http://localhost:8080/v1",
|
||||||
|
WS_ADDRESS: "ws://localhost:8080/ws",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* client user data
|
||||||
|
*/
|
||||||
|
|
||||||
|
let l = "loading...";
|
||||||
|
|
||||||
|
// for the data preview when the request is not finished
|
||||||
|
export const ClientUserDataContextPreview = {
|
||||||
|
Username: l,
|
||||||
|
Email: l,
|
||||||
|
};
|
||||||
|
|
||||||
|
export let ClientUserDataContext = createContext(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* user session
|
||||||
|
*/
|
||||||
|
export function UseUserSession() {
|
||||||
|
const getUserSession = () => {
|
||||||
|
return JSON.parse(localStorage.getItem("session"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const [userSession, setUserSession] = useState(getUserSession());
|
||||||
|
|
||||||
|
const saveUserSession = (session) => {
|
||||||
|
setUserSession(session);
|
||||||
|
|
||||||
|
if (session === undefined) {
|
||||||
|
localStorage.removeItem("session");
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("session", JSON.stringify(session));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUserSession: saveUserSession,
|
||||||
|
userSession,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* websocket
|
||||||
|
*/
|
||||||
|
let webSocketContextPreview = {
|
||||||
|
connectionBadgeStatus: "error",
|
||||||
|
connectedWebSocketUsersCount: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WebSocketTestContext = createContext(webSocketContextPreview);
|
||||||
|
|
||||||
|
export function WebSocketProvider({ children, userSession }) {
|
||||||
|
const [isReady, setIsReady] = useState(false);
|
||||||
|
const [connectionBadgeStatus, setConnectionBadgeStatus] = useState("error");
|
||||||
|
const [connectedWebSocketUsersCount, setConnectedWebSocketUsersCount] =
|
||||||
|
useState(0);
|
||||||
|
|
||||||
|
let socket = null;
|
||||||
|
|
||||||
|
const connect = () => {
|
||||||
|
socket = new WebSocket(Constants.WS_ADDRESS + "?auth=" + userSession);
|
||||||
|
|
||||||
|
socket.onopen = () => {
|
||||||
|
console.log("connected");
|
||||||
|
setConnectionBadgeStatus("success");
|
||||||
|
setIsReady(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
console.log("received message", data);
|
||||||
|
|
||||||
|
const cmd = data.Cmd;
|
||||||
|
const Body = data.Body;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case 1:
|
||||||
|
setConnectedWebSocketUsersCount(Body);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onclose = (event) => {
|
||||||
|
setIsReady(false);
|
||||||
|
setConnectionBadgeStatus("error");
|
||||||
|
console.log("closed", event.reason.code);
|
||||||
|
|
||||||
|
if (event.reason.code === 1005) return;
|
||||||
|
|
||||||
|
console.log("reconnecting...");
|
||||||
|
|
||||||
|
setTimeout(() => connect(), 1000);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
connect();
|
||||||
|
|
||||||
|
return () => socket.close();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WebSocketTestContext.Provider
|
||||||
|
value={{
|
||||||
|
connectionBadgeStatus: connectionBadgeStatus,
|
||||||
|
connectedWebSocketUsersCount: connectedWebSocketUsersCount,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</WebSocketTestContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue