2017-04-12 7 views
1

私は、ブロードキャストの代わりに特定のクライアントにメッセージを送信するようにゴリラのチャットの例を変更しようとしています。まず、特定のクライアントをハブに格納します。Websocketはブロードキャストの代わりに特定のクライアントに送信します

Hub.go

type Hub struct { 
     Clients map[int]*Client // Changed this piece to store id (int) 
     Broadcast chan []byte 
     Register chan *Client 
     Unregister chan *Client 
} 

func (h *Hub) Run() { 
     for { 
        select { 
        case client := <-h.Register: 
           fmt.Println("hub client register") 
           h.Clients[client.Id] = client 
        case client := <-h.Unregister: 
           fmt.Println("hub client Unregister") 
           fmt.Println(h.Clients[client.Id]) 
           if h.Clients[client.Id] != nil { 
              delete(h.Clients, client.Id) 
              close(client.Send) 
           } 
        case message := <-h.Broadcast: 
           fmt.Println("to send to a specific client", string(message)) 
        } 
     } 
} 

私は

type Client struct { 
     Hub *Hub 
     Conn *websocket.Conn 
     Send chan []byte  
     Id int // Id of the client, 
} 

func (c *Client) readPump() { 
     defer func() { 
        c.Hub.Unregister <- c 
        c.Conn.Close() 
     }() 
     c.Conn.SetReadLimit(maxMessageSize) 
     c.Conn.SetReadDeadline(time.Now().Add(pongWait)) 
     c.Conn.SetPongHandler(func(string) error { c.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) 
     for { 
        _, message, err := c.Conn.ReadMessage() 
        if err != nil { 
           if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { 
              log.Printf("error: %v", err) 
           } 
           break 
        } 
        message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1)) 

        fmt.Println("client read message", string(message), "from", c.Id) 
     // {"to":512,"message":"Hi there."} 
        c.Hub.Broadcast <- message 
     } 
} 

は何のメッセージを送信したクライアントを知っているクライアントにフィールドID int型を追加しました

クライアントブロードキャストではなく特定のクライアントにメッセージを送信できるようにするための次のステップ。

メッセージ自体は、誰から送信するのか、どのメッセージを送信するのかを指定する 'to'を指定して、クライアントからJSONとして送信されます。

{"to":512,"message":"Hi there."} 

答えて

0

メッセージを表すタイプを定義します。

type Message struct { 
    id int 
    data []byte 
} 

はハブへのフィールドの追加:

Send chan Message 

をハブの他のチャネルと一緒にチャネルを初期化します。

ハブの選択するには、次のケースを追加します。

c.Hub.Send <- Message{id: id, data: data} 
+0

ありがとう:クライアントのIDとメッセージデータを取得し、ハブにそれを送信するためにJSONを解析し、ループを受け取るには

case m := <-h.Send: c, ok := clients[m.id] if ok { select { case c.send <- m.data: default: delete(h.Clients, c.Id) close(c.Send) } } 

を。デフォルトの節が必要ですか?私は同じことをやっているハブのハンドラの登録を解除しました。教えてください。 – Developer

+0

default句を追加しないと、ハブはデッド・クライアントをブロックできます。元の例のクライアントの送信チャネルは、1より大きな容量を持っています(正確な値は忘れています)。チャネルが容量を満たしていれば、クライアントの送信ループはおそらくピアへの書き込みに固執しています。クライアントを落としてから、ハブを停止する方が良いでしょう。 –

関連する問題