더북(TheBook)

클라이언트 생성/종료

웹소켓 커넥션 정보와 접속한 사용자 정보, 채팅방 아이디를 전달하면 클라이언트 객체를 생성하는 newClient 함수를 만들어 보자.

▼ client.go

const messageBufferSize = 256
 
func newClient(conn *websocket.Conn, roomId string, u *User) {
    // 새로운 클라이언트 생성
    c := &Client{
        conn:   conn,
        send:   make(chan *Message, messageBufferSize),
        roomId: roomId,
        user:   u,
    }
     
    // clients 목록에 새로 생성한 클라이언트 추가
    clients = append(clients, c)
     
    // 메시지 수신/전송 대기
    go c.readLoop()
    go c.writeLoop()
}
 
func (c *Client) Close() {
    // clients 목록에서 종료된 클라이언트 제거
    for i, client := range clients {
        if client == c {
            clients = append(clients[:i], clients[i+1:]...)
            break
        }
    }
     
    // send 채널 닫음
    close(c.send)
     
    // 웹소켓 커넥션 종료
    c.conn.Close()
    log.Printf("close connection. addr: %s", c.conn.RemoteAddr())
}

한꺼번에 많은 메시지가 몰려도 메시지 전달 작업이 블록되지 않게 newClient() 함수에서 make(chan *Message, messageBufferSize)를 통해 send 채널을 버퍼드 채널로 만들었다. 클라이언트 객체를 생성하여 clients에 추가하고, 메시지 수신/전송을 대기하기 위한 루프를 시작한다. readLoop()writeLoop() 메서드는 뒤에서 설명한다.

Close() 메서드에서는 clients 목록에서 해당 클라이언트를 제거하고 send 채널과 웹소켓 커넥션을 닫는다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.