Skip to content

Commit

Permalink
Merge pull request #172 from sharemindteam/fix/171-chat-broadcast-issue
Browse files Browse the repository at this point in the history
fix: 채팅 send할 때 전체에게 전달되는 문제 해결
  • Loading branch information
aeyongdodam authored Apr 6, 2024
2 parents a3797ac + 6539d90 commit 7d4cafc
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public void validateChatWithWebSocket(Long chatId, Map<String, Object> sessionAt
@Override
public void getAndSendChatIdsByWebSocket(Map<String, Object> sessionAttributes, Boolean isCustomer) {
ChatGetConnectResponse chatGetConnectResponse = getChatIds(sessionAttributes, isCustomer);
sendChatIds(chatGetConnectResponse);
Long userId = (Long) sessionAttributes.get("userId");
sendChatIds(chatGetConnectResponse, userId);
}

private ChatGetConnectResponse getChatIds(Map<String, Object> sessionAttributes, Boolean isCustomer) {
Expand All @@ -119,9 +120,9 @@ private ChatGetConnectResponse getChatIds(Map<String, Object> sessionAttributes,
return ChatGetConnectResponse.of(userId, chatRoomIds);
}

private void sendChatIds(ChatGetConnectResponse chatGetConnectResponse) {
simpMessagingTemplate.convertAndSend("/queue/chattings/connect/counselors/", chatGetConnectResponse);
simpMessagingTemplate.convertAndSend("/queue/chattings/connect/customers/", chatGetConnectResponse);
private void sendChatIds(ChatGetConnectResponse chatGetConnectResponse, Long userId) {
simpMessagingTemplate.convertAndSend("/queue/chattings/connect/counselors/" + userId, chatGetConnectResponse);
simpMessagingTemplate.convertAndSend("/queue/chattings/connect/customers/" + userId, chatGetConnectResponse);
}

private Long getLatestMessageIdForChat(Chat chat) { //todo: ChatMessageService로 빼고싶었는데 순환참조 문제때문에 못뺌.. 구조 고민해보기
Expand Down Expand Up @@ -243,7 +244,8 @@ private List<Chat> getFilterChats(List<Consult> consults, Boolean filter) {
}

@Override
public void getAndSendChatStatus(Long chatId, Map<String, Object> sessionAttributes, ChatStatusUpdateRequest chatStatusUpdateRequest,
public void getAndSendChatStatus(Long chatId, Map<String, Object> sessionAttributes,
ChatStatusUpdateRequest chatStatusUpdateRequest,
Boolean isCustomer) {
ChatGetStatusResponse chatGetStatusResponse = getChatStatus(chatId, chatStatusUpdateRequest, isCustomer);

Expand Down Expand Up @@ -284,7 +286,9 @@ private void handleStatusRequest(Chat chat, ChatStatusUpdateRequest chatStatusUp
chatTaskScheduler.checkSendRequest(chat); //10분을 세는 상황

if (!chat.getAutoRefund()) // 처음 요청을 보낸거 기준으로 자동환불 처리 해주기 때문에
{
chat.updateAutoRefundTrue();
}

break;
}
Expand Down Expand Up @@ -395,7 +399,8 @@ private void notifyFinishChat(Chat chat, Consult consult) {
public void setChatInSessionRedis(Long chatId, Long customerId, Boolean isCustomer) {
String redisKey = isCustomer
? CUSTOMER_CHATTING_PREFIX + customerId.toString()
: COUNSELOR_CHATTING_PREFIX + counselorService.getCounselorByCustomerId(customerId).getCounselorId().toString();
: COUNSELOR_CHATTING_PREFIX + counselorService.getCounselorByCustomerId(customerId).getCounselorId()
.toString();
Map<Long, Integer> chatIdCounts = sessionRedisTemplate.opsForValue().get(redisKey);

if (chatIdCounts == null) {
Expand All @@ -413,14 +418,16 @@ public void setChatInSessionRedis(Long chatId, Long customerId, Boolean isCustom

private void sendReadAllEvent(Long chatId, Long customerId, Boolean isCustomer) {

if (isCustomer)
if (isCustomer) {
simpMessagingTemplate.convertAndSend(
"/queue/chattings/notifications/customers/" + customerId,
ChatNotifyEventResponse.of(chatId, ChatRoomWebsocketStatus.CHAT_READ_ALL));
else
} else {
simpMessagingTemplate.convertAndSend(
"/queue/chattings/notifications/counselors/" + counselorService.getCounselorByCustomerId(customerId).getCounselorId(),
"/queue/chattings/notifications/counselors/" + counselorService.getCounselorByCustomerId(customerId)
.getCounselorId(),
ChatNotifyEventResponse.of(chatId, ChatRoomWebsocketStatus.CHAT_READ_ALL));
}
}

@Override
Expand All @@ -431,7 +438,8 @@ public void leaveChatSession(Map<String, Object> sessionAttributes, Long chatId,
Counselor counselor = counselorService.getCounselorByCounselorId(userId);
customerId = customerService.getCustomerByCounselor(counselor).getCustomerId();
}
String redisKey = isCustomer ? CUSTOMER_CHATTING_PREFIX + userId.toString() : COUNSELOR_CHATTING_PREFIX + userId.toString();
String redisKey = isCustomer ? CUSTOMER_CHATTING_PREFIX + userId.toString()
: COUNSELOR_CHATTING_PREFIX + userId.toString();
Map<Long, Integer> chatIdCounts = sessionRedisTemplate.opsForValue().get(redisKey);
if (chatIdCounts != null && chatIdCounts.containsKey(chatId)) {
int count = chatIdCounts.get(chatId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ public ResponseEntity<List<ChatLetterGetResponse>> getCustomerChatList(
public ResponseEntity<ChatGetRoomInfoResponse> getCounselorChatInfo(
@PathVariable Long chatId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return ResponseEntity.ok(chatService.getChatInfoByCounselor(chatId, customUserDetails.getCustomer().getCustomerId()));
return ResponseEntity.ok(
chatService.getChatInfoByCounselor(chatId, customUserDetails.getCustomer().getCustomerId()));
}

@MessageMapping("/api/v1/chat/customers/{chatId}")
Expand Down Expand Up @@ -146,14 +147,16 @@ public ResponseEntity<Void> getAndSendCounselorChatIds(SimpMessageHeaderAccessor
}

@MessageMapping("/api/v1/chat/customers/exit/{chatId}")
public ResponseEntity<Void> leaveCustomerSession(@DestinationVariable Long chatId, SimpMessageHeaderAccessor headerAccessor) {
public ResponseEntity<Void> leaveCustomerSession(@DestinationVariable Long chatId,
SimpMessageHeaderAccessor headerAccessor) {
Map<String, Object> sessionAttributes = Objects.requireNonNull(headerAccessor.getSessionAttributes());
chatService.leaveChatSession(sessionAttributes, chatId, true);
return ResponseEntity.ok().build();
}

@MessageMapping("/api/v1/chat/counselors/exit/{chatId}")
public ResponseEntity<Void> leaveCounselorSession(@DestinationVariable Long chatId, SimpMessageHeaderAccessor headerAccessor) {
public ResponseEntity<Void> leaveCounselorSession(@DestinationVariable Long chatId,
SimpMessageHeaderAccessor headerAccessor) {
Map<String, Object> sessionAttributes = Objects.requireNonNull(headerAccessor.getSessionAttributes());
chatService.leaveChatSession(sessionAttributes, chatId, false);
return ResponseEntity.ok().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,15 @@ public ResponseEntity<CounselorGetAccountResponse> getAccount(
return ResponseEntity.ok(
counselorService.getAccount(customUserDetails.getCustomer().getCustomerId()));
}

@Operation(summary = "counselor id 조회",
description = "채팅 연결을 위한 상담사 id 조회")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공")
})
@GetMapping()
public ResponseEntity<Long> getCounselorId(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return ResponseEntity.ok(counselorService.getCounselorByCustomerId(customUserDetails.getCustomer()
.getCustomerId()).getCounselorId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ public class CustomerController {
public ResponseEntity<String> getCustomerNickname(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return ResponseEntity.ok(customerService.getCustomerNickname(customUserDetails.getCustomer().getCustomerId()));
}

@Operation(summary = "customerId 조회", description = "채팅 연결에 필요한 customerId 조회")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공"),
})
@GetMapping()
public ResponseEntity<Long> getCustomerId(@AuthenticationPrincipal CustomUserDetails customUserDetails) {
return ResponseEntity.ok(customUserDetails.getCustomer().getCustomerId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/api/v1/auth/signUp", "/api/v1/auth/signIn", "/api/v1/auth/reissue",
"/api/v1/auth/find-id", "/api/v1/auth/find-password", "/api/v1/auth/recovery-email/**", "/api/v1/emails/**").permitAll()
.requestMatchers("/api/v1/counselors/all/**", "/api/v1/searchWords/results/**", "/api/v1/reviews/all/**").permitAll()
.requestMatchers("/index.html", "/favicon.ico", "/chat/**", "/customer.html",
.requestMatchers("/index.html", "/favicon.ico", "/chat/**", "/customer.html", "/customer2.html",
"/counselor.html").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/posts/{postId}").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/posts/customers/public/**").permitAll()
Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/static/customer.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h2>Customer Chat</h2>

<script type="text/javascript">
var stompClient = null;
var chatId = 20; // 채팅방 ID로 업데이트
var chatId = 183; // 채팅방 ID로 업데이트 ceos1
var isCustomer = true; // 고객 여부

function connect() {
Expand All @@ -37,11 +37,11 @@ <h2>Customer Chat</h2>
}, function (frame) {
console.log('Connected: ' + frame);

stompClient.subscribe('/queue/chattings/connect/customers/', function (response) {
stompClient.subscribe('/queue/chattings/connect/customers/20', function (response) {
console.log('Received response for customers: ', response.body);
});
// 구독
stompClient.subscribe('/queue/chattings/notifications/customers/19', function (notification) {
stompClient.subscribe('/queue/chattings/notifications/customers/20', function (notification) {
console.log('Notification: ', notification.body);
});
stompClient.subscribe('/queue/chattings/customers/' + chatId, function (statusUpdate) {
Expand Down
92 changes: 92 additions & 0 deletions src/main/resources/static/customer2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<title>Customer Chat</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
<h2>Customer Chat</h2>
<div id="chat">
<div>
<label for="tokenInput">Token:</label>
<input type="text" id="tokenInput">
<button onclick="connect()">Connect</button>
</div>
<div id="messages"></div>
<input type="text" id="messageInput">
<button onclick="sendMessage()">Send Message</button>
<button onclick="sendChatStartRequest()">Start Chat Request</button>
<button onclick="sendChatStartResponse()">Start Chat Response</button>
<button onclick="sendChatFinishRequest()">End Chat</button>
<button onclick="sendConnectRequest()">Send Connect Request</button>
</div>

<script type="text/javascript">
var stompClient = null;
var chatId = 182; // 채팅방 ID로 업데이트 ceos2
var isCustomer = true; // 고객 여부

function connect() {
var token = document.getElementById('tokenInput').value; // 사용자가 입력한 토큰
var socket = new SockJS('/chat'); // 서버의 웹소켓 연결 주소
stompClient = Stomp.over(socket);
stompClient.connect({
'Authorization': 'Bearer ' + token,
'isCustomer': isCustomer
}, function (frame) {
console.log('Connected: ' + frame);

stompClient.subscribe('/queue/chattings/connect/customers/21', function (response) {
console.log('Received response for customers: ', response.body);
});
// 구독
stompClient.subscribe('/queue/chattings/notifications/customers/21', function (notification) {
console.log('Notification: ', notification.body);
});
stompClient.subscribe('/queue/chattings/customers/' + chatId, function (statusUpdate) {
console.log('Status Update: ', statusUpdate.body);
});
stompClient.subscribe('/queue/chattings/status/customers/' + chatId, function (statusAutoUpdate) {
console.log('Status Auto Update: ', statusAutoUpdate.body);
});
stompClient.subscribe('/queue/chattings/exception/customers/' + chatId, function (error) {
console.log('Error: ', error.body);
});
stompClient.subscribe('/queue/chatMessages/customers/' + chatId, function (message) {
console.log('Message: ', message.body);
displayMessage(message.body);
});
});
}

function sendMessage() {
var message = document.getElementById('messageInput').value;
stompClient.send("/app/api/v1/chatMessages/customers/" + chatId, {}, JSON.stringify({content: message}));
}

function sendChatStartRequest() {
stompClient.send("/app/api/v1/chat/customers/" + chatId, {}, JSON.stringify({chatWebsocketStatus: "COUNSELOR_CHAT_START_REQUEST"}));
}

function sendChatStartResponse() {
stompClient.send("/app/api/v1/chat/customers/" + chatId, {}, JSON.stringify({chatWebsocketStatus: "CUSTOMER_CHAT_START_RESPONSE"}));
}

function sendChatFinishRequest() {
stompClient.send("/app/api/v1/chat/customers/" + chatId, {}, JSON.stringify({chatWebsocketStatus: "CUSTOMER_CHAT_FINISH_REQUEST"}));
}

function displayMessage(message) {
var messagesDiv = document.getElementById('messages');
messagesDiv.innerHTML += '<div>' + message + '</div>';
}

function sendConnectRequest() {
if (stompClient !== null) {
stompClient.send("/app/api/v1/chat/customers/connect", {}, JSON.stringify({}));
}
}
</script>
</body>
</html>

0 comments on commit 7d4cafc

Please sign in to comment.