매칭때와 다르게 친구와의 대화는 저번에 했던 대화기록을 불러와야 하기때문에
웹소켓을 하나더 추가
package com.example.demo.handler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.example.demo.dto.MessageDTO;
import com.example.demo.dto.TestUser;
import com.example.demo.repository.model.User;
import com.example.demo.service.ChatService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class Chat1vs1Handler extends TextWebSocketHandler{
private final Map<String, WebSocketSession> CLIENTS = new ConcurrentHashMap<>();
private final Map<WebSocketSession, Integer> KEYS = new ConcurrentHashMap<>();
@Autowired
private ChatService chatService;
@Override // 웹 소켓 연결시
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
User user = (User) session.getAttributes().get("principal");
Integer key = (Integer) session.getAttributes().get("key");
ObjectMapper objectMapper = new ObjectMapper();
List<User>userList = chatService.getUserList(key);
// 대화기록 가져오기
List<MessageDTO>history = objectMapper.readValue(readFile(key), new TypeReference<List<MessageDTO>>() {});
// 방에 들어온 사용자 세션 추가
CLIENTS.put(user.getNickname(), session);
KEYS.put(session, key);
for(MessageDTO message : history) {
// 대화기록 나에게 전송
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message)));
}
}
@Override // 웹 소켓 연결 종료시
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
User user = (User) session.getAttributes().get("principal");
Integer key = (Integer) session.getAttributes().get("key");
ObjectMapper objectMapper = new ObjectMapper();
String message = " 님이 나가셧습니다.";
MessageDTO messageDTO = MessageDTO.builder().name(user.getNickname()).uploadFileName(user.getUploadFileName())
.message(message).build();
// 방에서 나간 사용자 세션 제거
CLIENTS.remove(user.getNickname());
for (WebSocketSession users : KEYS.keySet()) {
if (KEYS.get(users) == key && users != session) {
users.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageDTO)));
}
}
KEYS.remove(session);
}
@Override // 데이터 통신시
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
User user = (User) session.getAttributes().get("principal");
Integer key = (Integer) session.getAttributes().get("key");
ObjectMapper objectMapper = new ObjectMapper();
String userMessage = message.getPayload();
MessageDTO messageDTO = MessageDTO.builder().name(user.getNickname()).uploadFileName(user.getUploadFileName())
.message(userMessage).build();
for (WebSocketSession users : KEYS.keySet()) {
if (KEYS.get(users) == key && users != session) {
users.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageDTO)));
saveFile(user, message.getPayload(), key); // 채팅 로그 저장
saveLogByJSON(user, userMessage, key); // 채팅 JSON으로 저장
}
}
}
// 파일를 저장하는 함수
private void saveFile(User user, String message, int roomId) {
// 메시지 내용
String msg = user.getNickname() + ": " + message + "\n";
// 파일을 저장한다.
try (FileOutputStream stream = new FileOutputStream("C:\\chatLog\\roomId_" + roomId, true)) {
stream.write(msg.getBytes("UTF-8"));
} catch (Throwable e) {
e.printStackTrace();
}
}
// 메세지 내용을 JSON형식으로 저장
private void saveLogByJSON(User user, String message, int roomId) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
// 메세지 내용
MessageDTO log = MessageDTO.builder().name(user.getNickname())
.uploadFileName(user.getUploadFileName()).message(message).build();
String msg = objectMapper.writeValueAsString(log);
// 파일 저장
try (FileOutputStream stream = new FileOutputStream("C:\\chatJSON\\roomId_" + roomId, true)) {
stream.write(msg.getBytes("UTF-8"));
} catch (Throwable e) {
e.printStackTrace();
}
}
// 채팅 내용을 파일로 부터 읽어온다.
private String readFile(int roomId) {
// d드라이브의 chat 폴더의 chat 파일
File file = new File("C:\\chatJSON\\roomId_" + roomId);
// 파일 있는지 검사
if (!file.exists()) {
return "";
}
// 파일을 읽어온다.
try (FileInputStream stream = new FileInputStream(file)) {
return new String(stream.readAllBytes());
} catch (Throwable e) {
e.printStackTrace();
return "";
}
}
}
친구와 대화하기를 누르면 컨트롤러에서 방을 가져와줌
@GetMapping("/friendChat")
public String friendChatPage(@RequestParam("id") int id, Model model) {
User principal = (User)session.getAttribute("principal");
User opponent = userService.searchByUserId(id);
int userId = principal.getUserId();
int roomId = 0;
// 친구와 만든 대화방이 있는지 없는지 검사
roomId = chatService.checkRoom1vs1(userId, id);
if(roomId != 0) {
model.addAttribute("roomId",roomId);
} else {
// 없다면 새로운 대화방을 만듬
ChatRoom chatRoom = ChatRoom.builder().name(principal.getNickname() + ","
+ opponent.getNickname()).build();
chatService.createChatRoom(chatRoom);
roomId = chatService.selectRoomId();
JoinRoomDTO userJoin = JoinRoomDTO.builder()
.userId(userId).roomId(roomId).build();
JoinRoomDTO opponentJoin = JoinRoomDTO.builder()
.userId(id).roomId(roomId).build();
chatService.joinChatRoom(userJoin);
chatService.joinChatRoom(opponentJoin);
model.addAttribute("roomId",roomId);
}
model.addAttribute("opponent",opponent);
return "chat/chatRoom";
}
신고 기능은 사용자가 참여중인 방의 id를 가져와 관리자가 대화기록을 읽을수있게 설계
-- 신고 테이블
create table report_tb(
id int primary key not null auto_increment,
type varchar(55) not null, -- 어디서 신고했는지
type_id int not null, -- 신고한 type의 id
reason varchar(200) not null, -- 이유
sender_id int not null, -- 신고한 사람
reciever_id int not null, -- 신고당한 사람
created_at timestamp default now() -- 신고 시간
);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.repository.ReportRepository">
<insert id="createReport">
insert into report_tb(type, type_id, reason, sender_id, reciever_id)
values(#{type}, #{typeId}, #{reason}, #{senderId}, #{recieverId})
</insert>
<select id="getReportList" resultType="com.example.demo.repository.model.Report">
select * from report_tb ORDERS LIMIT #{limit} offset #{offset}
</select>
<select id="getReportSize" resultType="Integer">
select count(*) from report_tb
</select>
<delete id="solvedReport">
delete from report_tb
where id = #{id}
</delete>
</mapper>
package com.example.demo.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.demo.dto.ReportDTO;
import com.example.demo.repository.model.User;
import com.example.demo.service.ChatService;
import com.example.demo.service.ReportService;
import com.example.demo.service.UserService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@Controller
@RequiredArgsConstructor
@RequestMapping("/report")
public class ReportController {
private final ChatService chatService;
private final UserService userService;
private final ReportService reportService;
@GetMapping()
public String matchReportPage(@RequestParam(name="roomId")int id,
@RequestParam(name="opponentId")int opponentId,
@RequestParam(name="type")String type, Model model) {
User opponent = userService.searchByUserId(opponentId);
model.addAttribute("type",type);
model.addAttribute("typeId",id);
model.addAttribute("opponent",opponent);
return "report/reportPage";
}
@PostMapping()
public ResponseEntity<String> postMethodName(ReportDTO dto) {
dto.setType("match");
int result = reportService.sendReport(dto);
if(result != 1) {
return
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Report submission failed");
} else {
// 성공 응답을 반환합니다.
return ResponseEntity.ok("Report submitted successfully");
}
}
}
'My Project > Final Project' 카테고리의 다른 글
2024-09-20 (알람 기능 완성) (0) | 2024.09.25 |
---|---|
2024-09-19(알림 기능 - 1) (0) | 2024.09.25 |
2024-09-09(친구 기능 완성) (1) | 2024.09.09 |
2024-09-06(친구 추가 기능, 알람 소켓) (0) | 2024.09.06 |
2024-09-05 (친구 찾기 기능 and 채팅 로그 저장) (1) | 2024.09.05 |