ホームページ >バックエンド開発 >Golang >golang ソケットを使用して 1 対 1 でチャットする

golang ソケットを使用して 1 対 1 でチャットする

王林
王林転載
2024-02-08 20:45:04406ブラウズ

与 golang 套接字一对一聊天

質問の内容

ユーザーが在庫状況を投稿し、他のユーザーが在庫状況を見つけて追加できるショッピング アプリを持っています。

現在、基本的にチャットを目的としたチャット サービスを利用しています。つまり、顧客は買い物客とチャットして詳細などを確認できます。このチャットは 1 対 1 で行う必要があります。したがって、5 人の顧客がショッピングの投稿について質問しているとします。顧客 A のショッピングに関するチャットは、同じショッピングに関する顧客 B のチャットとは別にする必要があるため、チャットを固有のものにしたいと考えています。買い物客はチャットを見て応答できる必要があります。

これは私が現在持っているものですが、これはリファレンス内の全員にメッセージをブロードキャストしているようです。他の人がチャットにアクセスできないように、買い物客が特定の送信者からのメッセージのみを受信できるようにしたいと考えています。

「client.go」

リーリー

「ハブ.ゴー」

リーリー

「ハンドラー.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
    }
}

正解


コードが同じ参照を持つ部屋にいる全員にメッセージをブロードキャストする主な理由は、あなたが ハブ にいるためです。 ##broadcast チャネル内でメッセージが処理される方法。現在の実装では、メッセージが送信されると、同じルーム内の (つまり、同じ参照を持つ) すべてのクライアントに転送されます。これは、hubrun メソッドで行われます: リーリー

スコアが1-1であることを願っています。参照はpostid

です

referencepostid で、買い物客 (在庫状況の投稿を投稿した人) と各顧客の間で 1 対 1 のコミュニケーションが必要な場合は、次のことを確認する必要があります。 each 各チャットは一意に識別可能です。 p>各チャット セッションの一意のキーは、

postid (reference) と顧客 ID (sender) の組み合わせである必要があります。これにより、各顧客はすべての投稿で買い物客と独自のチャット セッションを行うことができます。

その後、

client 構造を更新して、referencesender を組み合わせた chatid を含めることができます。 リーリー

ハブを更新して、ルームの代わりにチャット セッション マップ (chatid で識別される) を管理できます。 リーリー

チャットの構造は次のとおりです: リーリー

メッセージを処理するには、顧客がメッセージを送信すると、そのメッセージが買い物客に送信され、買い物客が返信すると、メッセージが顧客に送信されます。ルーティングは

chatid を使用して実行できます。

たとえば、

ブロードキャストロジックでは次のようになります: リーリー

m 変数のタイプは *message で、chatid フィールドはありません。 この問題を解決するには、
chatid フィールドを message 構造に追加することを検討する必要があります。

まず、

message 構造を変更します: リーリー

次に、

clientreadmessage メソッドで新しい message を構築すると、次のようになります。 リーリー チャットを初期化するとき:

リーリー

警告: これは機能の基本的な骨格にすぎませんが、顧客や買い物客が複数のデバイスを所有している可能性がある状況の処理、堅牢なエラー処理の確保など、追加の複雑さは考慮されていません。

以上がgolang ソケットを使用して 1 対 1 でチャットするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。