>백엔드 개발 >Golang >golang 소켓으로 일대일 채팅

golang 소켓으로 일대일 채팅

王林
王林앞으로
2024-02-08 20:45:04403검색

与 golang 套接字一对一聊天

질문 내용

사용자가 재고를 게시하고 다른 사용자가 이를 찾아 재고를 추가할 수 있는 쇼핑 앱이 있습니다.

이제 기본적으로 채팅을 위한 채팅 서비스가 생겼습니다. 즉, 고객은 쇼핑객과 채팅을 통해 세부 사항이나 기타 사항을 확인할 수 있습니다. 이 채팅은 일대일로 이루어져야 합니다. 따라서 쇼핑 게시물에 대해 질문하는 고객이 5명이 있을 수 있으며 구매에 대한 고객 A의 채팅은 동일한 구매에 대한 고객 B의 채팅과 분리되어야 하기 때문에 채팅을 고유하게 만들고 싶습니다. 쇼핑객은 채팅을 보고 응답할 수 있어야 합니다.

현재 가지고 있는게 이거인데 참고자료에 있는 모든분들께 메시지를 방송하는거 같네요. 쇼핑객이 다른 사람이 채팅에 액세스할 수 없도록 하고 특정 발신자로부터 메시지만 받기를 원합니다.

"client.go"

으아악

"hub.go"

으아악

"handler.go"

으아악

"route.go"

으아악
type client struct {
    conn           *websocket.conn
    chatrepository chat.chatrepository
    message        chan *message
    id             string `json:"id"`
    reference      string `json:"reference"`
    username       string `json:"username"`
    sender         string `json:"sender"`
    recipient      string `json:"recipient"`
}

type message struct {
    content   string `json:"content"`
    reference string `json:"reference"`
    // username  string `json:"username"`
    sender string `json:"sender"`
}

func (c *client) writemessage() {
    defer func() {
        c.conn.close()
    }()

    for {
        message, ok := <-c.message
        if !ok {
            return
        }
        uuid, err := uuid.newv4()
        if err != nil {
            log.fatalf("failed to generate uuid: %v", err)
        }
        chatmessage := chat.chatmessage{
            id:     uuid.string(),
            sender: message.sender,
            // recipient: recipient,
            timestamp: time.now(),
            content:   message.content,
        }
        if c.sender == message.sender {
            _, errx := c.chatrepository.addmessage(message.reference, chatmessage)
            if err != nil {
                log.fatalf("failed to generate uuid: %v", errx)
            }
        }
        c.conn.writejson(chatmessage)
    }
}

func (c *client) readmessage(hub *hub) {
    defer func() {
        hub.unregister <- c
        c.conn.close()
    }()

    for {
        _, m, err := c.conn.readmessage()
        if err != nil {
            if websocket.isunexpectedcloseerror(err, websocket.closegoingaway, websocket.closeabnormalclosure) {
                log.printf("error: %v", err)
            }
            break
        }

        msg := &message{
            content:   string(m),
            reference: c.reference,
            sender:    c.sender,
            // username:  c.username,
        }

        hub.broadcast <- msg
    }
}

정답


귀하의 코드가 동일한 참조로 방에 있는 모든 사람에게 메시지를 브로드캐스트하는 주된 이유는 hub broadcast 频道中处理消息的方式。在当前的实现中,当发送消息时,它会被转发到同一房间中的每个客户端(即具有相同的引用)。这是在 hubrun 메소드에서 수행하기 때문입니다.

으아악

점수가 1-1이길 바랍니다. 견적이 게시되었습니다

referencepostid 쇼핑객(구매 가능 여부 게시물을 게시한 사람)과 각 고객 간의 일대일 통신을 원하는 경우 각 채팅을 고유하게 식별할 수 있는지 확인해야 합니다. p>

각 채팅 세션의 고유 키는 postid (reference) 和客户 id (sender)의 조합이어야 합니다. 이를 통해 각 고객은 모든 게시물에서 쇼핑객과 고유한 채팅 세션을 가질 수 있습니다.

그런 다음 client 结构,使其具有 chatid ,它是 referencesender의 조합을 업데이트할 수 있습니다.

으아악

방 대신 hub 来管理聊天会话地图(由 chatid로고)를 업데이트하실 수 있습니다.

으아악

chat의 구조는 다음과 같습니다.

으아악

메시지 처리를 위해 고객이 메시지를 보내면 해당 메시지가 쇼퍼에게 전송되고, 쇼퍼가 응답하면 해당 메시지가 고객에게 전송됩니다. 라우팅은 chatid를 사용하여 수행할 수 있습니다.

예를 들어 broadcast 논리에서:

으아악

m 변수는 *message 유형이며 m 变量的类型为 *message,它没有 chatid 필드가 없습니다.
이 문제를 해결하려면 chatid 字段添加到 message 구조에

필드를 추가하는 것을 고려해야 합니다.

message먼저

구조를 수정합니다:

으아악 clientreadmessage 方法中构造一个新的 message그런 다음 클라이언트readmessage 메소드에서 새

를 구성할 때:

으아악

채팅 초기화 시:

으아악

경고: 이는 기능의 기본 골격일 뿐이지만 고객이나 쇼핑객이 여러 장치를 보유할 수 있는 상황 처리, 강력한 오류 처리 보장 등과 같은 추가 복잡성을 고려하지 않습니다. 🎜

위 내용은 golang 소켓으로 일대일 채팅의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제