From a95c0b1f7fe255144d300f07b05de44bfeca2663 Mon Sep 17 00:00:00 2001 From: aronmal Date: Sat, 5 Aug 2023 23:22:09 +0200 Subject: [PATCH] Fixed socket event listeners removal --- leaky-ships/components/Gamefield/EventBar.tsx | 3 +- .../Lobby/SettingsFrame/Setting.tsx | 9 +-- .../Lobby/SettingsFrame/Settings.tsx | 3 +- leaky-ships/hooks/useDraw.ts | 23 ++++--- leaky-ships/hooks/useGameProps.ts | 2 +- leaky-ships/hooks/useSocket.ts | 67 +++++++++++-------- leaky-ships/interfaces/NextApiSocket.ts | 25 +++---- leaky-ships/interfaces/frontend.ts | 19 ++++++ 8 files changed, 88 insertions(+), 63 deletions(-) diff --git a/leaky-ships/components/Gamefield/EventBar.tsx b/leaky-ships/components/Gamefield/EventBar.tsx index dab4faf..8cd2ddd 100644 --- a/leaky-ships/components/Gamefield/EventBar.tsx +++ b/leaky-ships/components/Gamefield/EventBar.tsx @@ -1,4 +1,3 @@ -import { GameSettings } from "@components/Lobby/SettingsFrame/Setting" import { faSquare2, faSquare3, @@ -32,7 +31,7 @@ import { GamePropsSchema } from "@lib/zodSchemas" import { useRouter } from "next/router" import { useCallback, useEffect, useMemo } from "react" import { Icons, toast } from "react-toastify" -import { EventBarModes } from "../../interfaces/frontend" +import { EventBarModes, GameSettings } from "../../interfaces/frontend" import Item from "./Item" export function setGameSetting( diff --git a/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx b/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx index a58f3b8..9734523 100644 --- a/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx +++ b/leaky-ships/components/Lobby/SettingsFrame/Setting.tsx @@ -7,14 +7,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { useGameProps } from "@hooks/useGameProps" import classNames from "classnames" import { ReactNode, useMemo } from "react" - -type GameSettingKeys = - | "allowSpectators" - | "allowSpecials" - | "allowChat" - | "allowMarkDraw" - -export type GameSettings = { [key in GameSettingKeys]?: boolean } +import { GameSettingKeys } from "../../../interfaces/frontend" function Setting({ children, diff --git a/leaky-ships/components/Lobby/SettingsFrame/Settings.tsx b/leaky-ships/components/Lobby/SettingsFrame/Settings.tsx index 78ff8ee..6c3c05b 100644 --- a/leaky-ships/components/Lobby/SettingsFrame/Settings.tsx +++ b/leaky-ships/components/Lobby/SettingsFrame/Settings.tsx @@ -4,7 +4,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { useGameProps } from "@hooks/useGameProps" import { socket } from "@lib/socket" import { useCallback } from "react" -import Setting, { GameSettings } from "./Setting" +import { GameSettings } from "../../../interfaces/frontend" +import Setting from "./Setting" function Settings({ closeSettings }: { closeSettings: () => void }) { const { setSetting, full } = useGameProps() diff --git a/leaky-ships/hooks/useDraw.ts b/leaky-ships/hooks/useDraw.ts index 981a491..fe360b1 100644 --- a/leaky-ships/hooks/useDraw.ts +++ b/leaky-ships/hooks/useDraw.ts @@ -1,6 +1,6 @@ import { socket } from "@lib/socket" import { useEffect, useRef, useState } from "react" -import { Draw, Point } from "../interfaces/frontend" +import { Draw, DrawLineProps, PlayerEvent, Point } from "../interfaces/frontend" import { useDrawProps } from "./useDrawProps" function drawLine({ prevPoint, currentPoint, ctx, color }: Draw) { @@ -88,30 +88,37 @@ export const useDraw = () => { const ctx = canvas.getContext("2d") if (!ctx) return - socket.on("playerEvent", (event) => { + const playerEvent = (event: PlayerEvent) => { if (!canvasRef.current?.toDataURL() || event.type !== "connect") return console.log("sending canvas state") socket.emit("canvas-state", canvasRef.current.toDataURL()) - }) + } - socket.on("canvas-state-from-server", (state: string, index) => { + const canvasStateFromServer = (state: string, index: number) => { console.log("I received the state") const img = new Image() img.src = state img.onload = () => { ctx?.drawImage(img, 0, 0) } - }) + } - socket.on("draw-line", ({ prevPoint, currentPoint, color }, index) => { + const socketDrawLine = (props: DrawLineProps, index: number) => { + const { prevPoint, currentPoint, color } = props if (!ctx) return console.log("no ctx here") drawLine({ prevPoint, currentPoint, ctx, color }) - }) + } + socket.on("playerEvent", playerEvent) + socket.on("canvas-state-from-server", canvasStateFromServer) + socket.on("draw-line", socketDrawLine) socket.on("canvas-clear", clear) return () => { - socket.removeAllListeners() + socket.off("playerEvent", playerEvent) + socket.off("canvas-state-from-server", canvasStateFromServer) + socket.off("draw-line", socketDrawLine) + socket.off("canvas-clear", clear) } }) diff --git a/leaky-ships/hooks/useGameProps.ts b/leaky-ships/hooks/useGameProps.ts index b7536a1..0d532d5 100644 --- a/leaky-ships/hooks/useGameProps.ts +++ b/leaky-ships/hooks/useGameProps.ts @@ -1,4 +1,3 @@ -import { GameSettings } from "@components/Lobby/SettingsFrame/Setting" import { getPayloadwithChecksum } from "@lib/getPayloadwithChecksum" import { socket } from "@lib/socket" import { @@ -21,6 +20,7 @@ import { create } from "zustand" import { devtools } from "zustand/middleware" import { EventBarModes, + GameSettings, MouseCursor, MoveDispatchProps, ShipProps, diff --git a/leaky-ships/hooks/useSocket.ts b/leaky-ships/hooks/useSocket.ts index a64f181..72d08b3 100644 --- a/leaky-ships/hooks/useSocket.ts +++ b/leaky-ships/hooks/useSocket.ts @@ -4,6 +4,7 @@ import status from "http-status" import { useRouter } from "next/router" import { useEffect, useMemo, useState } from "react" import { toast } from "react-toastify" +import { GameSettings, PlayerEvent } from "../interfaces/frontend" import { isAuthenticated } from "../pages/start" import { useGameProps } from "./useGameProps" import useIndex from "./useIndex" @@ -42,13 +43,13 @@ function useSocket() { }, [selfIndex, isConnectedState, setIsConnected]) useEffect(() => { - socket.on("connect", () => { + const connect = () => { console.log("connected") toast.dismiss("connect_error") setIsConnectedState(true) - }) + } - socket.on("connect_error", (error) => { + const connectError = (error: Error) => { console.log("Connection error:", error.message) if (error.message === status["403"]) router.push("/") if (error.message !== "xhr poll error") return @@ -61,19 +62,9 @@ function useSocket() { }) else toast.warn("Es gibt Probleme mit der Echtzeitverbindung.", { toastId }) - }) + } - socket.on("gameSetting", (payload, hash) => { - const newHash = setSetting(payload) - if (!newHash || newHash === hash) return - console.log("hash", hash, newHash) - socket.emit("update", (body) => { - console.log("update") - full(body) - }) - }) - - socket.on("playerEvent", (event) => { + const playerEvent = (event: PlayerEvent) => { const { type, i } = event let message: string console.log("playerEvent", type) @@ -114,25 +105,47 @@ function useSocket() { console.log("update") full(body) }) - }) + } - socket.on("isReady", setIsReady) + const gameSetting = (payload: GameSettings, hash: string) => { + const newHash = setSetting(payload) + if (!newHash || newHash === hash) return + console.log("hash", hash, newHash) + socket.emit("update", (body) => { + console.log("update") + full(body) + }) + } - socket.on("gameState", gameState) + const activeIndex = (i: number) => setActiveIndex(i, selfIndex) - socket.on("dispatchMove", DispatchMove) - - socket.on("activeIndex", (i) => setActiveIndex(i, selfIndex)) - - socket.on("ships", setShips) - - socket.on("disconnect", () => { + const disconnect = () => { console.log("disconnect") setIsConnectedState(false) - }) + } + + socket.on("connect", connect) + socket.on("connect_error", connectError) + socket.on("gameSetting", gameSetting) + socket.on("playerEvent", playerEvent) + socket.on("isReady", setIsReady) + socket.on("gameState", gameState) + socket.on("dispatchMove", DispatchMove) + socket.on("activeIndex", activeIndex) + socket.on("ships", setShips) + socket.on("disconnect", disconnect) return () => { - socket.removeAllListeners() + socket.off("connect", connect) + socket.off("connect_error", connectError) + socket.off("gameSetting", gameSetting) + socket.off("playerEvent", playerEvent) + socket.off("isReady", setIsReady) + socket.off("gameState", gameState) + socket.off("dispatchMove", DispatchMove) + socket.off("activeIndex", activeIndex) + socket.off("ships", setShips) + socket.off("disconnect", disconnect) } }, [ DispatchMove, diff --git a/leaky-ships/interfaces/NextApiSocket.ts b/leaky-ships/interfaces/NextApiSocket.ts index 835ecbe..0565e7d 100644 --- a/leaky-ships/interfaces/NextApiSocket.ts +++ b/leaky-ships/interfaces/NextApiSocket.ts @@ -1,5 +1,4 @@ -import { GameSettings } from "@components/Lobby/SettingsFrame/Setting" -import { GamePropsSchema, PlayerSchema } from "@lib/zodSchemas" +import { GamePropsSchema } from "@lib/zodSchemas" import { GameState } from "@prisma/client" import type { Server as HTTPServer } from "http" import type { Socket as NetSocket } from "net" @@ -11,7 +10,13 @@ import type { Socket as SocketforServer, } from "socket.io" import type { Socket as SocketforClient } from "socket.io-client" -import { DrawLineProps, MoveDispatchProps, ShipProps } from "./frontend" +import { + DrawLineProps, + GameSettings, + MoveDispatchProps, + PlayerEvent, + ShipProps, +} from "./frontend" interface SocketServer extends HTTPServer { io?: IOServer @@ -30,19 +35,7 @@ export interface ServerToClientEvents { // basicEmit: (a: number, b: string, c: Buffer) => void // withAck: (d: string, ) => void gameSetting: (payload: GameSettings, hash: string) => void - playerEvent: ( - event: - | { - type: "connect" | "leave" - i: number - payload: { users: PlayerSchema[] } - hash: string - } - | { - type: "disconnect" - i: number - }, - ) => void + playerEvent: (event: PlayerEvent) => void isReady: (payload: { i: number; isReady: boolean }) => void isConnected: (payload: { i: number; isConnected: boolean }) => void "get-canvas-state": () => void diff --git a/leaky-ships/interfaces/frontend.ts b/leaky-ships/interfaces/frontend.ts index 6a07bd8..b8ed0c9 100644 --- a/leaky-ships/interfaces/frontend.ts +++ b/leaky-ships/interfaces/frontend.ts @@ -1,4 +1,5 @@ import { IconDefinition } from "@fortawesome/pro-solid-svg-icons" +import { PlayerSchema } from "@lib/zodSchemas" import { MoveType, Orientation } from "@prisma/client" export interface Position { @@ -70,3 +71,21 @@ export interface MoveDispatchProps extends Position { type: MoveType orientation: Orientation } +export type GameSettingKeys = + | "allowSpectators" + | "allowSpecials" + | "allowChat" + | "allowMarkDraw" + +export type GameSettings = { [key in GameSettingKeys]?: boolean } +export type PlayerEvent = + | { + type: "connect" | "leave" + i: number + payload: { users: PlayerSchema[] } + hash: string + } + | { + type: "disconnect" + i: number + }