本文主要是介绍gorilla/websocket的chat示例代码简单分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
代码地址:https://github.com/gorilla/websocket/tree/main/examples/chat
文件包含:main.go、hub.go、client.go、home.html
main.go文件
func main() {flag.Parse()hub := newHub() // 实例化Hubgo hub.run() // 使用chan处理 增删Hub的连接 和 广播消息http.HandleFunc("/", serveHome) // 访问home.html页面// 处理websockethttp.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {serveWs(hub, w, r)})server := &http.Server{Addr: *addr,ReadHeaderTimeout: 3 * time.Second,}err := server.ListenAndServe()if err != nil {log.Fatal("ListenAndServe: ", err)}
}
hub.go文件
// 相当于连接池
type Hub struct {// Registered clients.clients map[*Client]bool // 存放所有websocket连接// Inbound messages from the clients.broadcast chan []byte // 广播消息// Register requests from the clients.register chan *Client // 添加websocket连接// Unregister requests from clients.unregister chan *Client // 删除websocket连接
}// 实例化Hub
func newHub() *Hub {return &Hub{broadcast: make(chan []byte),register: make(chan *Client),unregister: make(chan *Client),clients: make(map[*Client]bool),}
}// 使用chan处理 增删Hub的连接 和 广播消息
func (h *Hub) run() {for {select {case client := <-h.register:h.clients[client] = true // 添加连接case client := <-h.unregister:if _, ok := h.clients[client]; ok {delete(h.clients, client) // 删除连接close(client.send)}case message := <-h.broadcast:for client := range h.clients {select {case client.send <- message: // 广播消息default:close(client.send)delete(h.clients, client)}}}}
}
client.go文件
// 连接
type Client struct {hub *Hub // 引用Hub// The websocket connection.conn *websocket.Conn // websocket连接// Buffered channel of outbound messages.send chan []byte // 消息发送chan
}// readPump pumps messages from the websocket connection to the hub.
//
// The application runs readPump in a per-connection goroutine. The application
// ensures that there is at most one reader on a connection by executing all
// reads from this goroutine.
func (c *Client) readPump() { // 读数据defer func() {c.hub.unregister <- cc.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, websocket.CloseAbnormalClosure) {log.Printf("error: %v", err)}break}message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))c.hub.broadcast <- message // 将消息发送到广播消息chan}
}// writePump pumps messages from the hub to the websocket connection.
//
// A goroutine running writePump 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.
func (c *Client) writePump() { // 写数据ticker := time.NewTicker(pingPeriod)defer func() {ticker.Stop()c.conn.Close()}()for {select {case message, ok := <-c.send: // 从连接的chan接收消息c.conn.SetWriteDeadline(time.Now().Add(writeWait))if !ok {// The hub closed the channel.c.conn.WriteMessage(websocket.CloseMessage, []byte{})return}w, err := c.conn.NextWriter(websocket.TextMessage)if err != nil {return}w.Write(message) // 发送消息// Add queued chat messages to the current websocket message.n := len(c.send)for i := 0; i < n; i++ {w.Write(newline)w.Write(<-c.send)}if err := w.Close(); err != nil {return}case <-ticker.C:c.conn.SetWriteDeadline(time.Now().Add(writeWait))if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {return}}}
}// serveWs handles websocket requests from the peer.
func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {log.Println(err)return}// 初始化Clientclient := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}client.hub.register <- client// Allow collection of memory referenced by the caller by doing all work in// new goroutines.go client.writePump() // 写数据go client.readPump() // 读数据
}
其他chat参考:
https://github.com/android-coco/chat
https://github.com/GoLangFengShen/chat
https://www.golangblogs.com/read/im/date-2023.02.19.09.38.24
这篇关于gorilla/websocket的chat示例代码简单分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!