WriteLoop pumps messages from the hub to the websocket connection. A goroutine running WriteLoop is started for each connection. The application ensures that there is at most one writer to a connection by executing all writes from this goroutine.
()
| 97 | // application ensures that there is at most one writer to a connection by |
| 98 | // executing all writes from this goroutine. |
| 99 | func (c *Client) WriteLoop() { |
| 100 | ticker := time.NewTicker(pingPeriod) |
| 101 | defer func() { |
| 102 | ticker.Stop() |
| 103 | c.conn.Close() |
| 104 | }() |
| 105 | for { |
| 106 | select { |
| 107 | case message, ok := <-c.Send: |
| 108 | _ = c.conn.SetWriteDeadline(time.Now().Add(writeWait)) |
| 109 | if !ok { |
| 110 | // The hub closed the channel. |
| 111 | _ = c.conn.WriteMessage(websocket.CloseMessage, []byte{}) |
| 112 | return |
| 113 | } |
| 114 | |
| 115 | w, err := c.conn.NextWriter(websocket.TextMessage) |
| 116 | if err != nil { |
| 117 | return |
| 118 | } |
| 119 | _, err = w.Write(message) |
| 120 | if err != nil { |
| 121 | log.Printf("could not send message: %s",err) |
| 122 | w.Close() |
| 123 | return |
| 124 | } |
| 125 | |
| 126 | if err := w.Close(); err != nil { |
| 127 | return |
| 128 | } |
| 129 | |
| 130 | case <-ticker.C: |
| 131 | c.conn.SetWriteDeadline(time.Now().Add(writeWait)) |
| 132 | if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil { |
| 133 | return |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | } |