Functioning websocket connections
This commit is contained in:
parent
a227da52bc
commit
30db96a3f7
9 changed files with 104 additions and 182 deletions
|
@ -1,10 +1,12 @@
|
|||
import Icon from "./Icon"
|
||||
import Player from "./Player"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import useSocket from "@lib/hooks/useSocket"
|
||||
import { Fragment, useEffect, useState } from "react"
|
||||
|
||||
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||
const { payload } = useGameState().gameProps
|
||||
useSocket()
|
||||
const [dots, setDots] = useState(1)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -18,7 +20,8 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
|||
<div className="flex items-center justify-between border-b-2 border-slate-900">
|
||||
<Icon src="speech_bubble.png">Chat</Icon>
|
||||
<h1 className="font-farro text-5xl font-medium">
|
||||
Game-PIN: <span className="underline">{payload?.gamePin?.pin}</span>
|
||||
Game-PIN:{" "}
|
||||
<span className="underline">{payload?.gamePin?.pin ?? "---"}</span>
|
||||
</h1>
|
||||
<Icon src="gear.png" onClick={openSettings}>
|
||||
Settings
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
import { cSocket } from "../interfaces/NextApiSocket"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { useEffect } from "react"
|
||||
import { io } from "socket.io-client"
|
||||
|
||||
let socket: cSocket
|
||||
|
||||
function SocketIO() {
|
||||
const { session, status } = useGameState()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading" || socket) return
|
||||
socket = io({
|
||||
path: "/api/ws2",
|
||||
})
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected")
|
||||
})
|
||||
|
||||
socket.on("authenticated", () => {
|
||||
console.log("Yay!")
|
||||
})
|
||||
|
||||
socket.on("unauthenticated", () => {
|
||||
console.log("No... pls work")
|
||||
})
|
||||
|
||||
return () => {
|
||||
socket.off("connect")
|
||||
socket.off("authenticated")
|
||||
socket.off("unauthenticated")
|
||||
}
|
||||
}, [status])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(4, socket)
|
||||
socket?.emit("authenticate", { token: `hello from ${session?.user.email}` })
|
||||
}, [session?.user.email, status])
|
||||
|
||||
return <div>SocketIO</div>
|
||||
}
|
||||
|
||||
export default SocketIO
|
|
@ -1,3 +1,4 @@
|
|||
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||
import { User } from "@prisma/client"
|
||||
import type { Server as HTTPServer } from "http"
|
||||
import type { Socket as NetSocket } from "net"
|
||||
|
@ -20,19 +21,14 @@ export interface NextApiResponseWithSocket extends NextApiResponse {
|
|||
export interface ServerToClientEvents {
|
||||
// noArg: () => void
|
||||
// basicEmit: (a: number, b: string, c: Buffer) => void
|
||||
// withAck: (d: string, callback: (e: number) => void) => void
|
||||
"update-input": (msg: string) => void
|
||||
unauthenticated: () => void
|
||||
authenticated: () => void
|
||||
test2: (test: string) => void
|
||||
test: () => void
|
||||
// withAck: (d: string, ) => void
|
||||
forbidden: () => void
|
||||
update: (game: GamePropsSchema) => void
|
||||
}
|
||||
|
||||
export interface ClientToServerEvents {
|
||||
// hello: () => void
|
||||
"input-change": (msg: string) => void
|
||||
join: (userId: string, callback: () => void) => void
|
||||
authenticate: (payload: { token: string }) => void
|
||||
test: (payload: any) => void
|
||||
}
|
||||
|
||||
interface InterServerEvents {
|
||||
|
@ -41,6 +37,7 @@ interface InterServerEvents {
|
|||
|
||||
interface SocketData {
|
||||
user: User | null
|
||||
gameProps: GamePropsSchema
|
||||
}
|
||||
|
||||
export type cServer = Server<
|
||||
|
|
58
leaky-ships/lib/hooks/useSocket.ts
Normal file
58
leaky-ships/lib/hooks/useSocket.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { socket } from "@lib/socket"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
function useSocket() {
|
||||
const [isConnected, setIsConnected] = useState(socket.connected)
|
||||
const [hasJoined, setHasJoined] = useState(false)
|
||||
// const [fooEvents, setFooEvents] = useState([])
|
||||
const { session, status, setGameProps } = useGameState()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading") return
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected")
|
||||
setIsConnected(true)
|
||||
})
|
||||
socket.on("connect_error", () => {
|
||||
console.log("connect_error")
|
||||
})
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("disconnect")
|
||||
setIsConnected(false)
|
||||
})
|
||||
|
||||
socket.on("forbidden", () => {
|
||||
console.log("forbidden")
|
||||
})
|
||||
|
||||
socket.on("update", (body) => {
|
||||
console.log("update")
|
||||
setGameProps(body)
|
||||
})
|
||||
|
||||
return () => {
|
||||
// for all events
|
||||
socket.removeAllListeners()
|
||||
}
|
||||
}, [status, setGameProps])
|
||||
|
||||
useEffect(() => {
|
||||
if (session?.user.id && !hasJoined) {
|
||||
socket?.emit("join", session?.user.id, () => {
|
||||
setHasJoined(true)
|
||||
})
|
||||
}
|
||||
}, [session?.user.id, hasJoined])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isConnected) return
|
||||
socket?.emit("authenticate", { token: `hello from ${session?.user.email}` })
|
||||
}, [isConnected, status, session?.user.email])
|
||||
|
||||
return socket
|
||||
}
|
||||
|
||||
export default useSocket
|
6
leaky-ships/lib/socket.ts
Normal file
6
leaky-ships/lib/socket.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { cSocket } from "../interfaces/NextApiSocket"
|
||||
import { io } from "socket.io-client"
|
||||
|
||||
export const socket: cSocket = io({
|
||||
path: "/api/ws2",
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
import type {
|
||||
NextApiResponseWithSocket,
|
||||
cServer,
|
||||
} from "../../interfaces/NextApiSocket"
|
||||
import type { NextApiRequest } from "next"
|
||||
import { Server } from "socket.io"
|
||||
|
||||
const SocketHandler = (req: NextApiRequest, res: NextApiResponseWithSocket) => {
|
||||
if (res.socket.server.io) {
|
||||
console.log("Socket is already running " + req.url)
|
||||
} else {
|
||||
console.log("Socket is initializing " + req.url)
|
||||
const io: cServer = new Server(res.socket.server, {
|
||||
path: "/api/ws",
|
||||
})
|
||||
res.socket.server.io = io
|
||||
|
||||
// io.use(authenticate)
|
||||
io.on("connection", (socket) => {
|
||||
socket.on("input-change", (msg) => {
|
||||
if (!socket.data.user) socket.emit("unauthenticated")
|
||||
// socket.broadcast.emit("update-input", msg)
|
||||
io.emit("update-input", msg)
|
||||
})
|
||||
|
||||
socket.on("test", (payload) => {
|
||||
console.log("Got test:", payload)
|
||||
// ...
|
||||
})
|
||||
|
||||
socket.emit("test2", "lol")
|
||||
})
|
||||
}
|
||||
res.end()
|
||||
}
|
||||
|
||||
export default SocketHandler
|
|
@ -2,6 +2,7 @@ import {
|
|||
NextApiResponseWithSocket,
|
||||
cServer,
|
||||
} from "../../interfaces/NextApiSocket"
|
||||
import { composeBody, getAnyRunningGame } from "./game/running"
|
||||
import prisma from "@lib/prisma"
|
||||
import colors from "colors"
|
||||
import { NextApiRequest } from "next"
|
||||
|
@ -18,7 +19,12 @@ const SocketHandler = async (
|
|||
console.log("Socket is already running " + req.url)
|
||||
} else {
|
||||
console.log("Socket is initializing " + req.url)
|
||||
const io: cServer = new Server(res.socket.server, { path: "/api/ws2" })
|
||||
const io: cServer = new Server(res.socket.server, {
|
||||
path: "/api/ws2",
|
||||
cors: {
|
||||
origin: "https://leaky-ships.mal-noh.de",
|
||||
},
|
||||
})
|
||||
|
||||
res.socket.server.io = io
|
||||
|
||||
|
@ -41,21 +47,34 @@ const SocketHandler = async (
|
|||
})
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log(`User connected <${socket.data.user?.email}>`.green)
|
||||
console.log(
|
||||
`User connected <${socket.data.user?.email}>`.green,
|
||||
socket.id
|
||||
)
|
||||
|
||||
socket.on("authenticate", (msg) => {
|
||||
// if (!socket.data.isAuthenticated) socket.emit("unauthenticated")
|
||||
// socket.broadcast.emit("update-input", msg)
|
||||
// io.emit("update-input", msg)
|
||||
console.log(msg)
|
||||
socket.on("join", async (userId, cb) => {
|
||||
console.log(socket.rooms, "join")
|
||||
const game = await getAnyRunningGame(userId ?? "")
|
||||
if (!game) {
|
||||
const warst = socket.emit("forbidden")
|
||||
console.log("forbidden", warst)
|
||||
return
|
||||
}
|
||||
cb()
|
||||
socket.join(userId)
|
||||
const body = composeBody(game)
|
||||
socket.data.gameProps = body
|
||||
io.to(userId).emit("update", body)
|
||||
})
|
||||
|
||||
socket.on("test", (payload) => {
|
||||
console.log("Got test:", payload)
|
||||
// ...
|
||||
socket.on("disconnecting", () => {
|
||||
console.log("disconnecting", socket.rooms) // the Set contains at least the socket ID
|
||||
})
|
||||
|
||||
socket.emit("test2", "lol")
|
||||
socket.on("disconnect", () => {
|
||||
// socket.rooms.size === 0
|
||||
console.log("disconnect", socket.id)
|
||||
})
|
||||
})
|
||||
}
|
||||
res.end()
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
import { cSocket } from "../interfaces/NextApiSocket"
|
||||
import useGameState from "@lib/hooks/useGameState"
|
||||
import { ChangeEventHandler, useEffect, useState } from "react"
|
||||
import { io } from "socket.io-client"
|
||||
|
||||
let socket: cSocket
|
||||
|
||||
const Home = () => {
|
||||
const [input, setInput] = useState("")
|
||||
const [data, setData] = useState("")
|
||||
|
||||
const { status } = useGameState()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading") return
|
||||
if (!socket) {
|
||||
console.log("Socket init.")
|
||||
socket = io({
|
||||
path: "/api/ws",
|
||||
})
|
||||
} else console.log("Socket present.")
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected")
|
||||
})
|
||||
|
||||
socket.on("authenticated", () => {
|
||||
console.log("Yay!")
|
||||
})
|
||||
|
||||
socket.on("unauthenticated", () => {
|
||||
console.log("No... pls work")
|
||||
})
|
||||
|
||||
socket.on("update-input", (msg) => {
|
||||
setData(msg)
|
||||
})
|
||||
|
||||
return () => {
|
||||
socket.off("connect")
|
||||
socket.off("authenticated")
|
||||
socket.off("unauthenticated")
|
||||
socket.off("update-input")
|
||||
}
|
||||
}, [status, setData])
|
||||
|
||||
const onChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
setInput(e.target.value)
|
||||
socket?.emit("input-change", e.target.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
placeholder="Type something"
|
||||
value={input}
|
||||
onChange={onChangeHandler}
|
||||
onDoubleClick={() => setInput(data)}
|
||||
/>
|
||||
<h1>{data}</h1>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
|
@ -1,15 +0,0 @@
|
|||
import SocketIO from "../components/SocketIO"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<SocketIO />
|
||||
</header>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue