-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #172 from ijun17/feature-fe#16#20
[FE] feat#16#20
- Loading branch information
Showing
14 changed files
with
393 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,66 @@ | ||
import { io, Socket } from 'socket.io-client'; | ||
import SocketEvents from '../constants/socketEvents'; | ||
import { SocketDataMap } from './socketEventTypes'; | ||
|
||
// type SocketEvent = (typeof SocketEvents)[keyof typeof SocketEvents]; | ||
|
||
type ChatMessage = { | ||
userId: string; | ||
message: string; | ||
}; | ||
|
||
type CreateRoomPayload = { | ||
title: string; | ||
maxPlayerCount: number; | ||
gameMode: string; | ||
isPublic: boolean; | ||
}; | ||
|
||
// μ΄λ²€νΈμ λ°μ΄ν° νμ μ μ μ | ||
// type SocketDataMap = { | ||
// [SocketEvents.CHAT_MESSAGE]: ChatMessage; | ||
// [SocketEvents.CREATE_ROOM]: CreateRoomPayload; | ||
// // λ€λ₯Έ μ΄λ²€νΈμ λ°μ΄ν° νμ μ μΆκ° | ||
// }; | ||
type SocketEvent = keyof SocketDataMap; | ||
|
||
class SocketService { | ||
private socket: Socket; | ||
private url: string; | ||
private handlers: (() => void)[]; | ||
|
||
constructor(url: string) { | ||
this.socket = io(); | ||
this.url = url; | ||
this.handlers = []; | ||
} | ||
|
||
connect() { | ||
async connect() { | ||
if (this.isActive()) return; | ||
this.socket = io(this.url); | ||
return new Promise((resolve, reject) => { | ||
this.socket.on('connect', () => resolve(null)); | ||
await new Promise<void>((resolve, reject) => { | ||
this.socket.on('connect', () => resolve()); | ||
this.socket.on('error', () => reject()); | ||
}); | ||
this.handlers.forEach((h) => h()); | ||
return; | ||
} | ||
|
||
disconnect() { | ||
this.socket.disconnect(); | ||
} | ||
|
||
isActive() { | ||
return this.socket && this.socket.active; | ||
return this.socket && this.socket.connected; | ||
} | ||
|
||
// μ΄λ²€νΈ μμ λ©μλ | ||
// on<T extends SocketEvent>(event: T, callback: (data: SocketDataMap[T]) => void) { | ||
// this.socket.on(event, (data: SocketDataMap[T]) => { | ||
// callback(data); | ||
// }); | ||
// } | ||
on<T extends SocketEvent>(event: T, callback: (data: SocketDataMap[T]['response']) => void) { | ||
const handler = () => this.socket.on(event as string, callback); | ||
this.handlers.push(handler); | ||
if (this.isActive()) handler(); | ||
} | ||
|
||
// λ©μμ§ μ μ‘ λ©μλ | ||
sendChatMessage(message: ChatMessage) { | ||
this.socket.emit(SocketEvents.CHAT_MESSAGE, message); | ||
emit<T extends SocketEvent>(event: T, data: SocketDataMap[T]['request']) { | ||
this.socket.emit(event, data); | ||
} | ||
|
||
// λ°© μμ± λ©μλ | ||
async createRoom(payload: CreateRoomPayload) { | ||
await this.connect(); | ||
this.socket.emit(SocketEvents.CREATE_ROOM, payload); | ||
sendChatMessage(message: SocketDataMap[typeof SocketEvents.CHAT_MESSAGE]['request']) { | ||
this.emit(SocketEvents.CHAT_MESSAGE, message); | ||
} | ||
|
||
// μ°κ²° μ’ λ£ λ©μλ | ||
disconnect() { | ||
this.socket.disconnect(); | ||
async createRoom(payload: SocketDataMap['createRoom']['request']) { | ||
await this.connect(); | ||
this.socket.emit(SocketEvents.CREATE_ROOM, payload); | ||
} | ||
|
||
joinRoom(gameId: string, playerName: string) { | ||
this.socket.send(SocketEvents.JOIN_ROOM, { gameId, playerName }); | ||
async joinRoom(gameId: string, playerName: string) { | ||
if (!this.isActive()) await this.connect(); | ||
this.socket.emit(SocketEvents.JOIN_ROOM, { gameId, playerName }); | ||
} | ||
|
||
chatMessage(gameId: string, message: string) { | ||
this.socket.send(SocketEvents.CHAT_MESSAGE, { gameId, message }); | ||
this.socket.emit(SocketEvents.CHAT_MESSAGE, { gameId, message }); | ||
} | ||
} | ||
|
||
export const socketService = new SocketService('http://quizground.duckdns.org:3000/game'); | ||
export const socketService = new SocketService('http://' + window.location.hostname + ':3000/game'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
// μ±ν λ©μμ§ μ λ¬ νμ | ||
type ChatMessageRequest = { | ||
gameId: string; // PIN | ||
message: string; | ||
}; | ||
|
||
type ChatMessageResponse = { | ||
playerId: string; // socketId | ||
playerName: string; | ||
message: string; | ||
timestamp: Date; | ||
}; | ||
|
||
// νλ μ΄μ΄ μμΉ μ λ°μ΄νΈ νμ | ||
type UpdatePositionRequest = { | ||
newPosition: [number, number]; | ||
}; | ||
|
||
type UpdatePositionResponse = { | ||
playerId: string; // socketId | ||
playerPosition: [number, number]; | ||
}; | ||
|
||
// κ²μλ°© μμ± νμ | ||
type CreateRoomRequest = { | ||
title: string; | ||
gameMode: 'RANKING' | 'SURVIVAL'; | ||
maxPlayerCount: number; | ||
isPublic: boolean; | ||
}; | ||
|
||
type CreateRoomResponse = { | ||
gameId: string; // PIN | ||
}; | ||
|
||
// κ²μλ°© μ΅μ μμ νμ | ||
type UpdateRoomOptionRequest = { | ||
gameId: string; | ||
title: string; | ||
gameMode: 'RANKING' | 'SURVIVAL'; | ||
maxPlayerCount: number; | ||
isPublic: boolean; | ||
}; | ||
|
||
type UpdateRoomOptionResponse = { | ||
title: string; | ||
gameMode: 'RANKING' | 'SURVIVAL'; | ||
maxPlayerCount: number; | ||
isPublic: boolean; | ||
}; | ||
|
||
// κ²μλ°© ν΄μ¦μ μμ νμ | ||
type UpdateRoomQuizsetRequest = { | ||
quizsetId: number; | ||
quizCount: number; | ||
}; | ||
|
||
type UpdateRoomQuizsetResponse = { | ||
quizsetId: number; | ||
quizCount: number; | ||
}; | ||
|
||
// κ²μλ°© μ μ₯ νμ | ||
type JoinRoomRequest = { | ||
gameId: string; | ||
playerName: string; | ||
}; | ||
|
||
type JoinRoomResponse = { | ||
players: Array<{ | ||
playerId: string; // socketId | ||
playerName: string; | ||
playerPosition: [number, number]; | ||
}>; | ||
}; | ||
|
||
// κ²μ μμ νμ | ||
type StartGameRequest = { | ||
gameId: string; | ||
}; | ||
|
||
type StartGameResponse = Record<string, never>; // λΉ κ°μ²΄ | ||
|
||
// κ²μ μ μ§ νμ | ||
type StopGameRequest = { | ||
gameId: string; | ||
}; | ||
|
||
type StopGameResponse = { | ||
status: string; | ||
}; | ||
|
||
// ν΄μ¦ μκ° μ’ λ£ νμ | ||
type EndQuizTimeEvent = { | ||
gameId: string; | ||
}; | ||
|
||
// ν΄μ¦ μμ νμ | ||
type StartQuizTimeEvent = { | ||
quiz: string; | ||
options: string[]; | ||
quizEndTime: Date; | ||
}; | ||
|
||
// κ²μ μ μ μ λ°μ΄νΈ νμ | ||
type UpdateScoreEvent = { | ||
scores: Map<string, number>; // Map<playerId, score> | ||
}; | ||
|
||
// κ²μλ°© ν΄μ₯ νμ | ||
type ExitRoomEvent = { | ||
playerId: string; | ||
}; | ||
|
||
// μ 체 μμΌ μ΄λ²€νΈ νμ 맡 | ||
export type SocketDataMap = { | ||
chatMessage: { | ||
request: ChatMessageRequest; | ||
response: ChatMessageResponse; | ||
}; | ||
updatePosition: { | ||
request: UpdatePositionRequest; | ||
response: UpdatePositionResponse; | ||
}; | ||
createRoom: { | ||
request: CreateRoomRequest; | ||
response: CreateRoomResponse; | ||
}; | ||
updateRoomOption: { | ||
request: UpdateRoomOptionRequest; | ||
response: UpdateRoomOptionResponse; | ||
}; | ||
updateRoomQuizset: { | ||
request: UpdateRoomQuizsetRequest; | ||
response: UpdateRoomQuizsetResponse; | ||
}; | ||
joinRoom: { | ||
request: JoinRoomRequest; | ||
response: JoinRoomResponse; | ||
}; | ||
startGame: { | ||
request: StartGameRequest; | ||
response: StartGameResponse; | ||
}; | ||
stopGame: { | ||
request: StopGameRequest; | ||
response: StopGameResponse; | ||
}; | ||
endQuizTime: { | ||
request: null; | ||
response: EndQuizTimeEvent; | ||
}; | ||
startQuizTime: { | ||
request: null; | ||
response: StartQuizTimeEvent; | ||
}; | ||
updateScore: { | ||
request: null; | ||
response: UpdateScoreEvent; | ||
}; | ||
exitRoom: { | ||
request: null; | ||
response: ExitRoomEvent; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.