Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.development

This file was deleted.

26 changes: 15 additions & 11 deletions src/context/socketManager.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { createContext, FC, ReactNode } from 'react'
import { io, Manager, Socket } from 'socket.io-client'
import { Manager } from 'libs/Manager'
import { createContext, FC, ReactNode, useRef } from 'react'
import { Socket } from 'socket.io-client'

// export const manager = new Manager(import.meta.env.VITE_SOCKET_SERVER_URL, {
// path: '/',
// transports: ['websocket'],
// })

const socket = io(import.meta.env.VITE_SOCKET_SERVER_URL, {
path: '/',
export const manager = new Manager(import.meta.env.VITE_SOCKET_SERVER_URL, {
transports: ['websocket'],
path: '',
})

export const SocketContext = createContext<{ socket: Socket | null }>({ socket: null })
export const SocketContext = createContext<{
socket: Socket | null
manager: Manager
}>({
socket: null,
manager,
})
const SocketProvider: FC<{ children: ReactNode }> = ({ children }) => {
return <SocketContext.Provider value={{ socket }}>{children}</SocketContext.Provider>
return (
<SocketContext.Provider value={{ socket: null, manager }}>{children}</SocketContext.Provider>
)
}
export default SocketProvider

Expand Down
20 changes: 19 additions & 1 deletion src/hooks/useSocket.ts
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
export {}
import { useEffect, useRef, useState } from 'react'
import { useContext } from 'react'
import { SocketContext } from 'context/socketManager'
import { Socket } from 'socket.io-client'
interface useSocketProps {
nsp: string
}

const useSocket = ({ nsp }: useSocketProps) => {
const { manager } = useContext(SocketContext)

const socket = useRef(manager.create_socket(nsp))
return {
manager,
socket: socket.current,
}
}

export default useSocket
5 changes: 3 additions & 2 deletions src/layout/SocketLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { SocketContext } from 'context/socketManager'
import useSocket from 'hooks/useSocket'
import { useContext, useLayoutEffect, useState } from 'react'
import { Outlet } from 'react-router-dom'
const SocketLayout = () => {
const { socket } = useContext(SocketContext)
const { socket } = useSocket({ nsp: '/' })
const [loading, setLoading] = useState(true)
useLayoutEffect(() => {
const nickname = localStorage.getItem('plug_nickname')
if (socket && nickname) {
socket?.emit('set_nickname', nickname, (nickname: string) => {
socket.emit('set_nickname', nickname, (nickname: string) => {
if (nickname) {
localStorage.setItem('plug_nickname', nickname)
} else {
Expand Down
34 changes: 34 additions & 0 deletions src/libs/Manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Manager as M, Socket } from 'socket.io-client'
import { SocketOptions } from 'socket.io-client/build/esm/socket'

export class Manager extends M {
private readonly sockets: { [key: string]: Socket } = {}
private readonly latestSocketNsp = null
create_socket(nsp: string, opts?: Partial<SocketOptions> | undefined): Socket {
//TODO: ์ตœ๊ทผ์‚ฌ์šฉํ•œ ์†Œ์ผ“ ์ปค๋„ฅ์…˜ ์ข…๋ฃŒ

if (this.sockets.hasOwnProperty(nsp)) {
return this.sockets[nsp]
}

// if (this.latestSocketNsp) {

// }
const socket = this.socket(nsp, opts)

socket.publicId = nsp
socket.listen = function bindEventListnerOnSocket(ev, lisnter) {
if (this.hasListeners(ev)) {
socket.off(ev)
}
socket.on(ev, lisnter)
return socket
}
this.sockets[nsp] = socket
return socket
}

isExistNsp(url: string) {
return !!this.sockets[url]
}
}
23 changes: 10 additions & 13 deletions src/screen/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SocketContext } from 'context/socketManager'
import { useCallback, useContext, useEffect, useState } from 'react'
import useSocket from 'hooks/useSocket'
import { useCallback, useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'

Expand All @@ -11,17 +11,16 @@ interface NicknameInput {
}

const Home = () => {
const { socket } = useContext(SocketContext)

useEffect(() => {}, [])
const { socket } = useSocket({ nsp: '/' })
const navigate = useNavigate()
const [rooms, setRooms] = useState<string[] | []>([])
const { register: roomRegister, handleSubmit: roomSubmit } = useForm<JoinRoomInput>()
const { register: nicknameRegister, handleSubmit: nicknameSubmit } = useForm<NicknameInput>({
defaultValues: {
nickname: localStorage.getItem('plug_nickname') || '',
},
})
const navigate = useNavigate()

const onJoinRoom = useCallback(
({ roomName }: JoinRoomInput) => {
navigate(roomName)
Expand All @@ -35,21 +34,19 @@ const Home = () => {
if (nickname) {
localStorage.setItem('plug_nickname', nickname)
} else {
// todo
// TODO
}
})
},
[socket?.on],
)
useEffect(() => {
if (socket) {
socket.on('room_change', (data) => setRooms(data))
if (!socket.connected) {
socket.connect()
}
socket.listen('room_change', (data: any) => {
setRooms(data)
})
}
}, [socket?.connected])

}, [rooms, setRooms])
return (
<>
<form onSubmit={nicknameSubmit(onSetNickname)}>
Expand Down
26 changes: 15 additions & 11 deletions src/screen/Room.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import { useNavigate, useParams } from 'react-router-dom'
import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { SocketContext } from 'context/socketManager'
import { Welcome } from 'types/dtos/socketResponse.dto'
import useSocket from 'hooks/useSocket'

const Room = () => {
const { roomName } = useParams()
const navigate = useNavigate()
const { socket } = useContext(SocketContext)
const { socket } = useSocket({
nsp: '/workspace',
})
const [userList, setUserList] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const myVideo = useRef<HTMLVideoElement>(null)
Expand Down Expand Up @@ -89,24 +92,24 @@ const Room = () => {

useEffect(() => {
if (socket && myPeer && !socket.hasListeners('ice')) {
socket.on('ice', (ice) => {
socket.listen('ice', (ice: RTCIceCandidate) => {
console.log('received candidate')
addIceCandidate(ice)
})
}
}, [socket, myPeer])
useLayoutEffect(() => {
if (socket && roomName) {
!socket.hasListeners('leave') &&
socket.on('leave', ({ userList: users }: Pick<Welcome, 'userList'>) => {
setUserList(users)
})
socket.listen('leave', ({ userList: users }: Pick<Welcome, 'userList'>) => {
console.log('leave user')
setUserList(users)
})
socket.emit('join_room', roomName, ({ nickname, userList: users, ok }: Welcome) => {
if (!ok) {
navigate('/')
return
}
loading && setUserList(users)
!loading && setUserList(users)
})

getMedia()
Expand All @@ -128,16 +131,17 @@ const Room = () => {
}, [])

useEffect(() => {
if (socket && !socket.hasListeners('welcome') && myPeer) {
socket.on('welcome', ({ nickname, userList: users }: Welcome) => {
if (socket && myPeer) {
socket.listen('welcome', ({ nickname, userList: users }: Welcome) => {
console.log(nickname, 'welcome')
setUserList(users)
sendOffer()
// sendOffer()
})
}
}, [myPeer, socket])
return (
<div>
<video autoPlay ref={myVideo}></video>
<video ref={myVideo}></video>
<video autoPlay ref={peerVideo}></video>
{userList.map((user, index) => (
<div key={user + '' + index}>
Expand Down
17 changes: 17 additions & 0 deletions src/socket.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Socket as S } from 'socket.io-client'
declare module 'socket.io-client' {
interface Socket extends S {
listen<Ev extends string>(
ev: Ev,
listener: FallbackToUntypedListener<
Ev extends 'connect' | 'connect_error' | 'disconnect'
? SocketReservedEvents[Ev]
: Ev extends string
? (...args: any[]) => void
: never
>,
): this

publicId: string
}
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"context/*" : ["./context/*"],
"hooks/*" : ["./hooks/*"],
"layout/*" : ["./layout/*"],
"libs/*" : ["./libs/*"],
},
"target": "ESNext",
"useDefineForClassFields": true,
Expand Down
4 changes: 4 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export default ({ mode }) => {
find: 'layout',
replacement: path.resolve(__dirname, 'src/layout'),
},
{
find: 'libs',
replacement: path.resolve(__dirname, 'src/libs'),
},
],
},
})
Expand Down