Skip to content

Commit

Permalink
Merge pull request #102 from softeerbootcamp4th/socket-chat-list
Browse files Browse the repository at this point in the history
[Feature] 기대평 채팅 과거 내역 불러오기 & 소켓 관련 에러 탐지용 구독 경로 추가
  • Loading branch information
nim-od authored Aug 21, 2024
2 parents 1ca5bc1 + f0bb1d6 commit bdbe5d2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 54 deletions.
2 changes: 2 additions & 0 deletions packages/common/src/constants/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const CHAT_SOCKET_ENDPOINTS = {
PUBLISH_NOTICE: '/app/chat.sendNotice',
SUBSCRIBE_CHAT_LIST: '/user/queue/chatHistory',
PUBLISH_CHAT_LIST: '/app/chat.getHistory',
SUBSCRIBE_ERROR: '/user/queue/errors',

} as const;

export const RACING_SOCKET_ENDPOINTS = {
Expand Down
9 changes: 4 additions & 5 deletions packages/common/src/utils/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface SendMessageProps {
destination: string;
body: unknown;
headers?: Record<string, string>;
requiresAuth?: boolean;
}

export default class Socket {
Expand Down Expand Up @@ -68,19 +69,17 @@ export default class Socket {
}
}

async sendMessages({ destination, body }: SendMessageProps) {
if (!this.token) {
async sendMessages({ destination, body, headers, requiresAuth = true}: SendMessageProps) {
if (requiresAuth && !this.token) {
throw new Error('로그인 후 참여할 수 있어요!');
}

const messageProps = {
destination,
headers,
body: JSON.stringify(body),
};

if (!this.client.connected) {
await this.connect();
}
this.client.publish(messageProps);
}

Expand Down
39 changes: 6 additions & 33 deletions packages/user/src/hooks/socket/useChatSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ export default function useChatSocket() {
const [storedChatList, storeChatList] = useChatListStorage();
const [chatList, setChatList] = useState<ChatProps[]>(storedChatList);

const [isChatListSubscribed, setIsChatListSubscribed] = useState(false);

useEffect(() => storeChatList(chatList), [chatList]);

const handleIncomingMessage: SocketSubscribeCallbackType = useCallback(
Expand All @@ -35,11 +33,12 @@ export default function useChatSocket() {
[setChatList],
);

const socketClient = socketManager.getSocketClient();


const handleSendMessage = useCallback(
(content: string) => {
try {
const socketClient = socketManager.getSocketClient();

const chatMessage = { content };

socketClient.sendMessages({
Expand All @@ -54,7 +53,7 @@ export default function useChatSocket() {
});
}
},
[socketClient],
[],
);

const handleIncomingChatHistory: SocketSubscribeCallbackType = useCallback(
Expand All @@ -63,37 +62,11 @@ export default function useChatSocket() {
},
[setChatList],
);

const handleRequestForSendingChatHistory = useCallback(async () => {
try {
await socketClient.sendMessages({
destination: CHAT_SOCKET_ENDPOINTS.PUBLISH_CHAT_LIST,
body: {},
});
setIsChatListSubscribed(true);
} catch (error) {
const errorMessage = (error as Error).message;
toast({
description:
errorMessage.length > 0 ? errorMessage : '기대평 내역을 불러오는 중 문제가 발생했습니다.',
});
}
}, [setIsChatListSubscribed, socketClient]);

const handleReceiveChatList: SocketSubscribeCallbackType = useCallback(
(data: unknown) => {
if (!isChatListSubscribed) {
handleRequestForSendingChatHistory();
}
handleIncomingChatHistory(data);
},
[isChatListSubscribed],
);


return {
onReceiveMessage: handleIncomingMessage,
onReceiveBlock: handleIncomingBlock,
onReceiveChatList: handleReceiveChatList,
onReceiveChatList: handleIncomingChatHistory,
onSendMessage: handleSendMessage,
messages: chatList,
};
Expand Down
40 changes: 24 additions & 16 deletions packages/user/src/services/socket.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {
ACCESS_TOKEN_KEY,
CHAT_SOCKET_ENDPOINTS,
RACING_SOCKET_ENDPOINTS,
} from '@softeer/common/constants';
import { Cookie, Socket, SocketSubscribeCallbackType } from '@softeer/common/utils';
import { Socket, SocketSubscribeCallbackType } from '@softeer/common/utils';
import { SOCKET_BASE_URL } from 'src/constants/environments.ts';
import CustomError from 'src/utils/error.ts';
import { toast } from 'src/hooks/useToast.ts';

class SocketManager {
private socketClient: Socket | null = null;
Expand All @@ -18,10 +17,6 @@ class SocketManager {

private onReceiveStatus: SocketSubscribeCallbackType | null = null;

constructor(token: string | null) {
this.initializeSocketClient(token);
}

private initializeSocketClient(token?: string | null) {
this.socketClient = new Socket(SOCKET_BASE_URL, token);
}
Expand All @@ -43,10 +38,6 @@ class SocketManager {
onReceiveStatus: SocketSubscribeCallbackType;
onReceiveChatList: SocketSubscribeCallbackType;
}) {
if (this.socketClient) {
await this.socketClient.disconnect();
}

this.initializeSocketClient(token);

this.onReceiveChatList = onReceiveChatList;
Expand All @@ -56,9 +47,16 @@ class SocketManager {

try {
await this.socketClient!.connect();
this.subscribeToTopics();
} catch (error) {
throw new CustomError('서버에서 데이터를 불러오는 데 실패했습니다.', 500);
toast({ description: '새로고침 후 다시 시도해주세요.' });
console.error('[Socket Connection Error]', error);
}

try {
await this.subscribeToTopics();
} catch (error) {
toast({ description: '새로고침 후 다시 시도해주세요.' });
console.error('[Socket Subscribe Error]', error);
}
}

Expand All @@ -72,13 +70,23 @@ class SocketManager {
});
}

subscribeToTopics() {
async subscribeToTopics() {
if (this.socketClient && this.socketClient.client.connected) {
this.socketClient.subscribe({
destination: CHAT_SOCKET_ENDPOINTS.SUBSCRIBE_ERROR,
callback: (errorMessage) => console.error(errorMessage),
});

if (this.onReceiveChatList) {
this.socketClient.subscribe({
await this.socketClient.subscribe({
destination: CHAT_SOCKET_ENDPOINTS.SUBSCRIBE_CHAT_LIST,
callback: this.onReceiveChatList,
});
this.socketClient.sendMessages({
destination: CHAT_SOCKET_ENDPOINTS.PUBLISH_CHAT_LIST,
body: {},
requiresAuth: false,
});
}

if (this.onReceiveMessage) {
Expand All @@ -105,5 +113,5 @@ class SocketManager {
}
}

const socketManager = new SocketManager(Cookie.getCookie(ACCESS_TOKEN_KEY));
const socketManager = new SocketManager();
export default socketManager;

0 comments on commit bdbe5d2

Please sign in to comment.