Skip to content

Commit

Permalink
[FE] socket 이벤트 핸들러 함수 등록에 관한 리팩토링 진행 (#190)
Browse files Browse the repository at this point in the history
* fix: 초기 vote에 관한 정보 불러오기

* refactor: socket에서 사용되는 store 분리 및 핸들러 등록 리팩토링 진행

* feat: store reset에 관한 처리 로직 추가

* fix: 스케쥴러 원복
  • Loading branch information
yoonseo-han authored Dec 2, 2024
1 parent f9e901c commit 03f128b
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 141 deletions.
2 changes: 2 additions & 0 deletions client/src/shared/hook/useStreamingRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export function useStreamingRoom() {
setSocket(newSocket);

return () => {
console.log('DISCONNECTED');
newSocket.removeAllListeners();
newSocket.disconnect();
};
}, []);
Expand Down
4 changes: 2 additions & 2 deletions client/src/shared/icon/VolumeMuted.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export function VolumeMuted() {
<path
d="M20.0713 19.5713L7.00024 5.00024"
stroke="#F3F3F3"
stroke-width="2"
stroke-linecap="round"
strokeWidth="2"
strokeLinecap="round"
/>
</svg>
);
Expand Down
14 changes: 14 additions & 0 deletions client/src/shared/store/state/chatState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MessageData } from '@/entities/message/types';

export interface ChatMessageState {
messages: MessageData[];
addMessage: (message: MessageData) => void;
clearMessages: () => void;
reset: () => void;
}

export interface ChatActions {
addMessage: (message: MessageData) => void;
clearMessages: () => void;
reset: () => void;
}
17 changes: 17 additions & 0 deletions client/src/shared/store/state/socketState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Socket } from 'socket.io-client';

export interface SocketState {
socket: Socket | null;
isConnected: boolean;
roomId: string | null;
userCount: number;
}

export interface SocketActions {
connect: (roomId: string) => void;
disconnect: () => void;
reset: () => void;
setUserCount: (count: number) => void;
setConnectionStatus: (status: boolean) => void;
resetAllStores: () => void;
}
11 changes: 11 additions & 0 deletions client/src/shared/store/state/voteState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type VoteType = { votes: Record<string, string>; trackNumber: string };

export interface VoteState {
voteData: VoteType;
}

export interface VoteActions {
showVote: (voteData: VoteType) => void;
updateVote: (voteData: VoteType) => void;
reset: () => void;
}
11 changes: 5 additions & 6 deletions client/src/shared/store/useChatMessageStore.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { create } from 'zustand';
import { MessageData } from '@/entities/message/types';
import { ChatMessageState } from './state/chatState';

interface ChatMessageState {
messages: MessageData[];
addMessage: (message: MessageData) => void;
clearMessages: () => void;
}
const INITIAL_STATE = {
messages: [],
};

export const useChatMessageStore = create<ChatMessageState>((set) => ({
messages: [],
addMessage: (message) =>
set((state) => ({ messages: [...state.messages, message] })),
clearMessages: () => set({ messages: [] }),
reset: () => set(INITIAL_STATE),
}));
136 changes: 60 additions & 76 deletions client/src/shared/store/useSocketStore.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,62 @@
import { create } from 'zustand';
import { Socket } from 'socket.io-client';
import { createSocket } from '../api/socket';

interface SocketState {
socket: Socket | null;
isConnected: boolean;
roomId: string | null;
userCount: number;
connect: (roomId: string) => void;
disconnect: () => void;
reset: () => void;
setUserCount: (count: number) => void;
}

export const useSocketStore = create<SocketState>((set, get) => ({
socket: null,
isConnected: false,
roomId: null,
userCount: 0,

connect: (newRoomId: string) => {
const { socket, roomId } = get();

// 이미 같은 방에 연결되어 있다면 무시
if (roomId === newRoomId && socket?.connected) return;

// 기존 소켓 연결 해제
if (socket) {
socket.disconnect();
}

const newSocket = createSocket(newRoomId);

newSocket.on('connect', () =>
set({
isConnected: true,
socket: newSocket,
roomId: newRoomId,
}),
);

newSocket.on('disconnect', () =>
set({
isConnected: false,
socket: null,
roomId: null,
}),
);

newSocket.on(
'roomUsersUpdated',
(data: { roomId: string; userCount: number }) => {
set({ userCount: data.userCount });
},
);

newSocket.connect();
},

setUserCount: (count: number) => set({ userCount: count }),

disconnect: () => {
const { socket } = get();
if (socket) {
socket.disconnect();
set({ isConnected: false, socket: null, roomId: null });
}
},

reset: () => {
const { socket } = get();
if (socket) {
socket.disconnect();
}
set({ socket: null, isConnected: false, roomId: null });
},
}));
import { useVoteStore } from './useVoteStore';
import { SocketActions, SocketState } from './state/socketState';
import { useChatMessageStore } from './useChatMessageStore';
import { setupSocketListeners } from './utils/socketEvents';

export const useSocketStore = create<SocketState & SocketActions>(
(set, get) => ({
socket: null,
isConnected: false,
roomId: null,
userCount: 0,

setConnectionStatus: (status: boolean) => set({ isConnected: status }),

setUserCount: (count: number) => set({ userCount: count }),

resetAllStores: () => {
useVoteStore.getState().reset();
useChatMessageStore.getState().reset();
},

connect: (newRoomId: string) => {
const { socket, roomId } = get();
if (roomId === newRoomId && socket?.connected) return;
console.log('NEW ROOM CONNECTED');

const newSocket = createSocket(newRoomId);
setupSocketListeners(newSocket, {
socketStore: get(),
voteStore: useVoteStore.getState(),
chatStore: useChatMessageStore.getState(),
});

newSocket.connect();
set({ socket: newSocket, roomId: newRoomId });
},

disconnect: () => {
console.log('DISCONNECTED');
const { socket } = get();
if (socket) {
socket.removeAllListeners();
socket.disconnect();
get().resetAllStores();
set({ isConnected: false, socket: null, roomId: null });
}
},

reset: () => {
console.log('RECONNECTED');
const { socket } = get();
if (socket) {
socket.removeAllListeners();
socket.disconnect();
get().resetAllStores();
}
set({ socket: null, isConnected: false, roomId: null });
},
}),
);
25 changes: 15 additions & 10 deletions client/src/shared/store/useVoteStore.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { create } from 'zustand';
import { VoteActions, VoteState, VoteType } from './state/voteState';

export type VoteType = { votes: Record<string, string>; trackNumber: string };
const INITIAL_STATE: VoteType = {
votes: {},
trackNumber: '',
};

interface VoteState {
voteData: VoteType;
showVote: (voteData: VoteType) => void;
updateVote: (voteData: VoteType) => void;
}
export const useVoteStore = create<VoteState & VoteActions>((set) => ({
voteData: {
votes: {},
trackNumber: '',
},

export const useVoteStore = create<VoteState>((set) => ({
voteData: { votes: {}, trackNumber: '' },
showVote: (voteData) =>
showVote: (voteData: VoteType) =>
set((state) => ({
voteData: {
...state.voteData,
...voteData,
},
})),
updateVote: (voteData) =>

updateVote: (voteData: VoteType) =>
set((state) => ({
voteData: {
...state.voteData,
votes: voteData.votes,
},
})),

reset: () => set({ voteData: INITIAL_STATE }),
}));
40 changes: 40 additions & 0 deletions client/src/shared/store/utils/socketEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Socket } from 'socket.io-client';
import { ChatActions } from '../state/chatState';
import { SocketActions } from '../state/socketState';
import { VoteActions, VoteType } from '../state/voteState';
import { MessageData } from '@/entities/message/types';

interface Stores {
socketStore: SocketActions;
voteStore: VoteActions;
chatStore: ChatActions;
}

export const setupSocketListeners = (socket: Socket, stores: Stores) => {
socket.on('connect', () => {
stores.socketStore.setConnectionStatus(true);
});

socket.on('disconnect', () => {
stores.socketStore.setConnectionStatus(false);
});

socket.on('voteShow', (data: VoteType) => {
stores.voteStore.showVote(data);
});

socket.on('voteUpdated', (data: VoteType) => {
stores.voteStore.updateVote(data);
});

socket.on(
'roomUsersUpdated',
(data: { roomId: string; userCount: number }) => {
stores.socketStore.setUserCount(data.userCount);
},
);

socket.on('broadcast', (data: MessageData) => {
stores.chatStore.addMessage(data);
});
};
21 changes: 1 addition & 20 deletions client/src/widgets/chatting/useChatMessage.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
import { MessageData } from '@/entities/message/types';
import { useSocketStore } from '@/shared/store/useSocketStore';
import { useEffect } from 'react';
import { useChatMessageStore } from '@/shared/store/useChatMessageStore';

export function useChatMessage() {
const { messages, addMessage } = useChatMessageStore();
const { socket } = useSocketStore();

useEffect(() => {
if (!socket) return;

const handleBroadcast = (data: MessageData) => {
addMessage(data);
};

socket.on('broadcast', handleBroadcast);

return () => {
socket.off('broadcast', handleBroadcast);
};
}, [socket, addMessage]);

const messages = useChatMessageStore((state) => state.messages);
return { messages };
}
2 changes: 1 addition & 1 deletion client/src/widgets/vote/ui/Vote.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChevronDown } from '@/shared/icon/ChevronDown';
import { useState } from 'react';
import { useSocketStore } from '@/shared/store/useSocketStore.ts';
import { useSocketStore } from '@/shared/store/useSocketStore';
import { SongData } from '@/entities/album/types.ts';
import { useVote } from '@/widgets/vote/useVote.ts';
import './ScrollBar.css';
Expand Down
28 changes: 2 additions & 26 deletions client/src/widgets/vote/useVote.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,6 @@
import { useSocketStore } from '@/shared/store/useSocketStore';
import { useEffect } from 'react';
import { useVoteStore, VoteType } from '@/shared/store/useVoteStore.ts';
import { useVoteStore } from '@/shared/store/useVoteStore';

export function useVote() {
const { voteData, showVote, updateVote } = useVoteStore();
const { socket } = useSocketStore();

useEffect(() => {
if (!socket) return;

const handleVoteUpdate = (data: VoteType) => {
updateVote(data);
};

const handleVoteShow = (data: VoteType) => {
showVote(data);
};

socket.on('voteUpdated', handleVoteUpdate);
socket.on('voteShow', handleVoteShow);

return () => {
socket.off('voteUpdated', handleVoteUpdate);
socket.off('voteShow', handleVoteShow);
};
}, [socket, updateVote]);

const voteData = useVoteStore((state) => state.voteData);
return { voteData };
}

0 comments on commit 03f128b

Please sign in to comment.