Skip to content

Commit

Permalink
refactor: change rooms type
Browse files Browse the repository at this point in the history
  • Loading branch information
barabobBOB committed Jul 10, 2024
1 parent 81c8ebb commit 7448616
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 70 deletions.
6 changes: 3 additions & 3 deletions cmd/server/handler/chat_handler.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package handler

import (
"log"
"net/http"

"github.com/gorilla/websocket"
Expand Down Expand Up @@ -45,8 +44,9 @@ func (h *ChatHandler) ServerWebsocket(

conn, err2 := upgrader.Upgrade(w, r, nil)
if err2 != nil {
log.Println(err2)
return err2
return c.JSON(http.StatusInternalServerError, map[string]interface{}{
"error": err2.Error(),
})
}

client := h.initializeOrUpdateClient(conn, foundUser)
Expand Down
107 changes: 54 additions & 53 deletions internal/chat/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Client struct {
messageSender chan []byte
FbUID string `json:"id"`
Name string `json:"name"`
rooms map[*Room]bool
rooms map[int64]*Room
}

func NewClient(conn *websocket.Conn, wsServer *WebSocketServer, name, fbUID string) *Client {
Expand All @@ -42,7 +42,46 @@ func NewClient(conn *websocket.Conn, wsServer *WebSocketServer, name, fbUID stri
conn: conn,
wsServer: wsServer,
messageSender: make(chan []byte, 256),
rooms: make(map[*Room]bool),
rooms: make(map[int64]*Room),
}
}

func (client *Client) HandleRead(chatService *service.ChatService) *pnd.AppError {
defer client.disconnect()
client.setupConnection()

for {
_, jsonMessage, err := client.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
return pnd.NewAppError(err, http.StatusInternalServerError, pnd.ErrCodeUnknown, "예상치 못한 연결 종료 오류가 발생했습니다.")
}
break
}
client.handleNewMessage(jsonMessage, chatService)
}
return nil
}

func (client *Client) HandleWrite() {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
client.conn.Close()
}()

for {
select {
case message, ok := <-client.messageSender:
if !ok {
client.writeCloseMessage()
return
}
client.writeMessage(message)

case <-ticker.C:
client.sendPing()
}
}
}

Expand Down Expand Up @@ -89,45 +128,6 @@ func (client *Client) writeMessage(message []byte) *pnd.AppError {
return nil
}

func (client *Client) HandleRead(chatService *service.ChatService) *pnd.AppError {
defer client.disconnect()
client.setupConnection()

for {
_, jsonMessage, err := client.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
return pnd.NewAppError(err, http.StatusInternalServerError, pnd.ErrCodeUnknown, "예상치 못한 연결 종료 오류가 발생했습니다.")
}
break
}
client.handleNewMessage(jsonMessage, chatService)
}
return nil
}

func (client *Client) HandleWrite() {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
client.conn.Close()
}()

for {
select {
case message, ok := <-client.messageSender:
if !ok {
client.writeCloseMessage()
return
}
client.writeMessage(message)

case <-ticker.C:
client.sendPing()
}
}
}

func (client *Client) writeCloseMessage() *pnd.AppError {
err := client.conn.SetWriteDeadline(time.Now().Add(writeWait))
if err != nil {
Expand All @@ -152,7 +152,8 @@ func (client *Client) sendPing() *pnd.AppError {

func (client *Client) disconnect() *pnd.AppError {
client.wsServer.unregister <- client
for room := range client.rooms {
for roomID := range client.rooms {
room := client.rooms[roomID]
room.unregister <- client
}
close(client.messageSender)
Expand All @@ -170,14 +171,14 @@ func (client *Client) handleNewMessage(jsonMessage []byte, chatService *service.
message.Sender = client
switch message.Action {
case SendMessageAction:
roomID := message.Target.GetID()
roomID := message.Room.GetID()
if room := client.wsServer.findRoomByID(roomID); room != nil {
room.broadcast <- &message
}
case JoinRoomAction:
client.handleJoinRoomMessage(message, chatService)
case LeaveRoomAction:
client.handleLeaveRoomMessage(message.Target.GetID())
client.handleLeaveRoomMessage(message.Room.GetID())
}
return nil
}
Expand All @@ -187,15 +188,15 @@ func (client *Client) handleJoinRoomMessage(message Message, chatService *servic
return pnd.NewAppError(nil, http.StatusInternalServerError, pnd.ErrCodeUnknown, "WebSocket 서버가 nil입니다.")
}

if message.Target == nil {
if message.Room == nil {
return pnd.NewAppError(nil, http.StatusBadRequest, pnd.ErrCodeInvalidBody, "채팅방 정보가 nil입니다.")
}

room := client.wsServer.findRoomByID(message.Target.GetID())
room := client.wsServer.findRoomByID(message.Room.GetID())
if room == nil {
log.Info().Msgf("ID %d의 방을 찾을 수 없어 새 방을 생성합니다.", message.Target.GetID())
log.Info().Msgf("ID %d의 방을 찾을 수 없어 새 방을 생성합니다.", message.Room.GetID())
var err *pnd.AppError
room, err = client.wsServer.createRoom(message.Target.Name, message.Target.RoomType, chatService)
room, err = client.wsServer.createRoom(message.Room.Name, message.Room.RoomType, chatService)
if err != nil {
log.Error().Err(err.Err).Msg("방 생성에 실패했습니다.")
return err
Expand All @@ -206,12 +207,12 @@ func (client *Client) handleJoinRoomMessage(message Message, chatService *servic
return pnd.NewAppError(nil, http.StatusBadRequest, pnd.ErrCodeInvalidBody, "보낸 사람이 nil입니다.")
}

if !client.isInRoom(room) {
if _, ok := client.rooms[message.Room.GetID()]; !ok {
if room.register == nil {
return pnd.NewAppError(nil, http.StatusInternalServerError, pnd.ErrCodeUnknown, "방 등록 채널이 nil입니다.")
}

client.rooms[room] = true
client.rooms[message.Room.GetID()] = room
room.register <- client
err := client.notifyRoomJoined(room, message.Sender)
if err != nil {
Expand All @@ -224,19 +225,19 @@ func (client *Client) handleJoinRoomMessage(message Message, chatService *servic

func (client *Client) handleLeaveRoomMessage(roomID int64) {
room := client.wsServer.findRoomByID(roomID)
delete(client.rooms, room)
delete(client.rooms, room.ID)
room.unregister <- client
}

func (client *Client) isInRoom(room *Room) bool {
_, ok := client.rooms[room]
_, ok := client.rooms[room.ID]
return ok
}

func (client *Client) notifyRoomJoined(room *Room, sender *Client) *pnd.AppError {
message := Message{
Action: RoomJoinedAction,
Target: room,
Room: room,
Sender: sender,
}

Expand Down
2 changes: 1 addition & 1 deletion internal/chat/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func InitializeWebSocketServer(

// 클라이언트를 방에 등록
if !client.isInRoom(room) {
client.rooms[room] = true
client.rooms[room.ID] = room
room.register <- client
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/chat/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ type Message struct {
Action string `json:"action"`
Message string `json:"message"`
MessageType chat.MessageType `json:"messageType"`
Target *Room `json:"target"`
Room *Room `json:"room"`
Sender *Client `json:"sender"`
}

func (message *Message) encode() ([]byte, *pnd.AppError) {
bytes, err := json.Marshal(message)
if err != nil {
return nil, pnd.NewAppError(err, http.StatusInternalServerError, pnd.ErrCodeMessageEncodingFailed, "메시지 인코딩에 실패했습니다")
return nil, pnd.NewAppError(err, http.StatusInternalServerError, pnd.ErrCodeMessageEncodingFailed, "메시지 인코딩에 실패했습니다.")
}
return bytes, nil
}
10 changes: 5 additions & 5 deletions internal/chat/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
)

type Room struct {
ID int64 `json:"id"` // 방 ID
Name string `json:"name"` // 방 이름
RoomType chat.RoomType `json:"roomType"` // 방 유형
clients map[string]*Client // 방에 있는 유저 목록
ID int64 `json:"id"`
Name string `json:"name"`
RoomType chat.RoomType `json:"roomType"`
clients map[string]*Client

register chan *Client // 클라이언트 등록 채널
unregister chan *Client // 클라이언트 해제 채널
Expand Down Expand Up @@ -103,7 +103,7 @@ func (room *Room) broadcastToClientsInRoom(message *Message, chatService *servic
func (room *Room) notifyClientJoined(client *Client, chatService *service.ChatService) *pnd.AppError {
message := &Message{
Action: SendMessageAction,
Target: room,
Room: room,
Message: fmt.Sprintf(welcomeMessage, client.GetName()),
MessageType: chat.MessageTypeNormal,
Sender: client,
Expand Down
6 changes: 0 additions & 6 deletions internal/chat/web_socket_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,23 @@ func (server *WebSocketServer) Run() {
}
}

// 새로운 클라이언트 등록
func (server *WebSocketServer) RegisterClient(client *Client) {
server.notifyClientJoined(client)
server.listOnlineClients(client)
server.clients[client.FbUID] = client
}

// 클라이언트 해제
func (server *WebSocketServer) unregisterClient(client *Client) {
if _, ok := server.clients[client.FbUID]; ok {
delete(server.clients, client.FbUID)
server.notifyClientLeft(client)
}
}

// UID로 클라이언트 찾음
func (server *WebSocketServer) FindClientByUID(uid string) *Client {
return server.clients[uid]
}

// 클라이언트가 접속했음을 모든 클라이언트에게 알림
func (server *WebSocketServer) notifyClientJoined(client *Client) *pnd.AppError {
message := &Message{
Action: UserJoinedAction,
Expand All @@ -72,7 +68,6 @@ func (server *WebSocketServer) notifyClientJoined(client *Client) *pnd.AppError
return nil
}

// 클라이언트가 떠났음을 모든 클라이언트에게 알림
func (server *WebSocketServer) notifyClientLeft(client *Client) *pnd.AppError {
message := &Message{
Action: UserLeftAction,
Expand All @@ -86,7 +81,6 @@ func (server *WebSocketServer) notifyClientLeft(client *Client) *pnd.AppError {
return nil
}

// 현재 온라인 상태인 클라이언트들을 새 클라이언트에게 전송
func (server *WebSocketServer) listOnlineClients(newClient *Client) *pnd.AppError {
for _, client := range server.clients {
message := &Message{
Expand Down

0 comments on commit 7448616

Please sign in to comment.