对于在Go中实现聊天功能,推荐使用以下库:
- gorilla/websocket - 最流行的WebSocket库
import "github.com/gorilla/websocket"
// 创建WebSocket升级器
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// 处理WebSocket连接
func serveWs(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
// 处理消息
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
// 广播消息
broadcastMessage(p)
}
}
- gobwas/ws - 高性能WebSocket库
import "github.com/gobwas/ws"
func handleConnection(conn net.Conn) {
// 升级到WebSocket
_, err := ws.Upgrade(conn)
if err != nil {
log.Fatal(err)
}
// 处理WebSocket帧
for {
header, err := ws.ReadHeader(conn)
if err != nil {
log.Println(err)
return
}
payload := make([]byte, header.Length)
_, err = io.ReadFull(conn, payload)
if err != nil {
log.Println(err)
return
}
// 处理消息
handleMessage(header, payload)
}
}
- centrifugo/centrifuge - 完整的实时通信框架
import "github.com/centrifugal/centrifuge"
// 创建节点
node, err := centrifuge.New(cfg)
if err != nil {
log.Fatal(err)
}
// 处理客户端连接
node.OnConnect(func(client *centrifuge.Client) {
client.OnSubscribe(func(e centrifuge.SubscribeEvent) {
// 处理订阅
log.Printf("Client subscribed to %s", e.Channel)
})
client.OnPublish(func(e centrifuge.PublishEvent) {
// 处理发布的消息
log.Printf("Message from client: %s", e.Data)
})
})
// 启动节点
if err := node.Run(); err != nil {
log.Fatal(err)
}
- melody - 基于gorilla/websocket的简化框架
import "github.com/olahol/melody"
m := melody.New()
// 处理连接
m.HandleConnect(func(s *melody.Session) {
log.Println("New connection")
})
// 处理消息
m.HandleMessage(func(s *melody.Session, msg []byte) {
// 广播给所有连接
m.Broadcast(msg)
})
// 集成到HTTP服务器
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
m.HandleRequest(w, r)
})
- nhooyr/websocket - net/http兼容的WebSocket库
import "nhooyr.io/websocket"
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
c, err := websocket.Accept(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer c.Close(websocket.StatusInternalError, "closed")
ctx := r.Context()
for {
mt, msg, err := c.Read(ctx)
if err != nil {
break
}
// 处理消息
log.Printf("Received: %s", msg)
// 发送响应
err = c.Write(ctx, mt, msg)
if err != nil {
break
}
}
})
对于快速实现,推荐使用gorilla/websocket或melody。gorilla/websocket提供完整的控制,而melody提供了更简单的API。如果需要完整的聊天解决方案,centrifuge是更好的选择。