해결된 질문
24.05.20 01:44 작성
·
154
1
안녕하세요 go 서버 구축 이후 프론트 연결하여 채팅을 전송하면 같은 메시지가 두 번씩 전송되는 현상이 발생합니다.
강의를 여러 번 체크하면서 봤는데 소스 코드가 다른 점은 찾지 못했습니다.
제가 작성한 socket.go 코드인데 어떤 부분이 문제가 있을까요
package network
import (
"chat_server_golang/types"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
var upgrader = &websocket.Upgrader{ReadBufferSize: types.SocketBufferSize, WriteBufferSize: types.MessageBufferSize,
CheckOrigin: func(r *http.Request) bool {return true},
} // http 요청을 websocket 통신으로 업그레이드 해준다.
type message struct {
Name string
Message string
Time int64
}
type Room struct {
Forward chan *message
Join chan *client
Leave chan *client
Clients map[*client]bool
}
type client struct {
Send chan *message
Room *Room
Name string
Socket *websocket.Conn
}
func NewRoom() *Room {
return &Room {
Forward: make(chan *message),
Join: make(chan *client),
Leave: make(chan *client),
Clients: make(map[*client]bool),
}
}
func (c *client) Read() {
// 클라이언트가 들어오는 멧세지를 읽는 작업
defer c.Socket.Close()
for {
var msg message
err := c.Socket.ReadJSON(&msg)
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
break
}
panic(err)
} else {
log.Println("READ : ", msg, "client", c.Name)
log.Println()
msg.Time = time.Now().Unix()
msg.Name = c.Name
c.Room.Forward <- &msg
}
msg.Name = c.Name
c.Room.Forward <- &msg
}
}
func (c *client) Write() {
// 클라이언트가 나가는 메시지를 전송하는 작업
defer c.Socket.Close()
for msg := range c.Send {
log.Println("WRITE : ", msg, "client", c.Name)
log.Println()
err := c.Socket.WriteJSON(msg)
if err != nil {
panic(err)
}
}
}
func (r *Room) RunInit() {
// room 에 있는 모든 채널 값을 받는 작업
// join leave 등의 메시지 큐를 처리, 무한반복문을 돌면서 처리
for {
log.Println(r.Clients)
log.Println(r.Forward)
select {
case client := <-r.Join:
r.Clients[client] = true
case client := <-r.Leave:
r.Clients[client] = false
close(client.Send)
delete(r.Clients, client)
case msg := <-r.Forward:
for client := range r.Clients {
client.Send <- msg
}
}
}
}
func (r *Room) SocketServe(c *gin.Context) {
socket, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
panic(err)
}
userCookie, err := c.Request.Cookie("auth")
if err != nil {
panic(err)
}
log.Println("userCookie", userCookie)
client := &client{
Socket: socket,
Send: make(chan *message, types.MessageBufferSize),
Room: r,
Name: userCookie.Value,
}
r.Join <- client // 채팅방에 클라이언트가 들어왔다고 알림
defer func() { r.Leave <- client }() // 클라이언트가 나갔다고 알림, 클라이언트가 나가면서 defer 함수가 실행된다.
go client.Write()
client.Read()
}
2024/05/20 01:39:17 userCookie auth=one
2024/05/20 01:39:17 map[0x14000512600:true]
2024/05/20 01:39:17 0x14000192600
2024/05/20 01:39:21 READ : { hi 0} client one
2024/05/20 01:39:21
2024/05/20 01:39:21 map[0x14000512600:true]
2024/05/20 01:39:21 0x14000192600
2024/05/20 01:39:21 map[0x14000512600:true]
2024/05/20 01:39:21 0x14000192600
2024/05/20 01:39:21 WRITE : &{one hi 1716136761} client one
2024/05/20 01:39:21
2024/05/20 01:39:21 WRITE : &{one hi 1716136761} client one
2024/05/20 01:39:21
답변 1
1
2024. 05. 20. 06:47
안녕하세요 👋
메시지가 두개씩 나오는 이유로 질문을 주셨습니다.
소스를 확인해보니 의심할 부분이 보이는거 같아요.
Read함수를 보시면 Forward에 두번 전송을 하고 있습니다.
그러면 채널이 두개의 값을 전달받아 처리가 될 우려가 있어요!! 🤔🤔
그러니 한번의 전송만 진행하게 코드를 수정해보시면 어떨까싶네요.🎉
한번 진행해보시고 해결이 안된다면 다시 질문 부탁드립니다.
늦은시간까지 열심히 하시네요!! 화이팅👏
2024. 06. 02. 23:21
한 곳의 msg forward를 제거하니 정상적으로 동작했습니다. 감사합니다.