websocket

main
alex 2023-04-20 22:29:51 +02:00
parent 9df013f603
commit 6f411232bd
5 changed files with 160 additions and 73 deletions

View File

@ -5,37 +5,21 @@ import PageContent from "./Components/PageContent";
import SideMenu from "./Components/SideMenu";
import Login from "./Pages/Login";
import { Layout } from "antd";
import { Constants, ClientUserDataPreview, ClientUserData } from "./constants";
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,
};
}
import {
Constants,
ClientUserDataContextPreview,
ClientUserDataContext,
UseUserSession,
WebSocketProvider,
} from "./utils";
export default function App() {
const { userSession, setUserSession } = useUserSession();
const [userData, setUserData] = useState(ClientUserDataPreview);
const { userSession, setUserSession } = UseUserSession();
const [userData, setUserData] = useState(ClientUserDataContextPreview);
useEffect(() => {
if (!userSession) return;
fetch(Constants.API_ADDRESS + "/user", {
method: "GET",
@ -49,6 +33,7 @@ export default function App() {
return res.json();
}
setUserSession();
return Promise.reject(res.status);
})
.then((data) => setUserData(data))
@ -61,10 +46,12 @@ export default function App() {
return (
<Layout style={{ minHeight: "100vh" }}>
<ClientUserData.Provider value={userData}>
<SideMenu setUserSession={setUserSession}></SideMenu>
<PageContent></PageContent>
</ClientUserData.Provider>
<ClientUserDataContext.Provider value={userData}>
<WebSocketProvider userSession={userSession}>
<SideMenu setUserSession={setUserSession}></SideMenu>
<PageContent></PageContent>
</WebSocketProvider>
</ClientUserDataContext.Provider>
</Layout>
);
}

View File

@ -9,13 +9,19 @@ import Sider from "antd/es/layout/Sider";
import { useContext, useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import { ClientUserData, Constants, UseUserSession } from "../../constants";
import {
ClientUserDataContext,
Constants,
UseUserSession,
WebSocketTestContext,
} from "../../utils";
export default function SideMenu({ setUserSession }) {
const { userSession } = UseUserSession();
const location = useLocation();
const [selectedKeys, setSelectedKeys] = useState("/");
const clientUserData = useContext(ClientUserData);
const clientUserDataContext = useContext(ClientUserDataContext);
const webSocketTestContext = useContext(WebSocketTestContext);
useEffect(() => {
const pathName = location.pathname;
@ -67,10 +73,21 @@ export default function SideMenu({ setUserSession }) {
mode="vertical"
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 />,
},
{

View File

@ -1,7 +1,7 @@
import { LockOutlined, LoginOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Form, Input, Modal, notification } from "antd";
import PropTypes from "prop-types";
import { Constants } from "../../constants";
import { Constants } from "../../utils";
import { useState } from "react";
import { Buffer } from "buffer";

View File

@ -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,
};
}

121
src/utils.js Normal file
View File

@ -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>
);
}