doxp30826 2017-04-12 19:41 采纳率: 0%
浏览 224
已采纳

Websocket发送到特定客户端而不是广播

I'm trying to modify the gorilla chat example to to send a message to a specific client instead of broadcast. First I'm storing the specific client in the hub against it's Id.

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))
                    }
        }
}

Client

I've added a field Id int to Client to know which client has sent a 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
        }
}

What are the next steps to take to be able to send the message to a specific client instead of broadcasting.

the message itself is coming as JSON from the client specifying 'to' indicating who to send and what message to send.

{"to":512,"message":"Hi there."}
  • 写回答

1条回答

  • douzhun5971 2017-04-12 20:44
    关注

    Define a type representing a message:

    type Message struct {
        id int
        data []byte
    }
    

    Add a field to Hub:

    Send chan Message
    

    and initialize the channel along with the hub's other channels.

    Add the following case to the hub's select:

    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)
            }
        }
    

    In the client's receive loop, parse the JSON to get the id and message data and send it to the hub:

        c.Hub.Send <- Message{id: id, data: data}
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!