这里 websocket 库用的是 github.com/lxzan/gws. 实现上十分的简介, 没有任何依赖; 事件驱动; 反对中间件; 每个连贯自带音讯队列, 不会被单条音讯的解决阻塞通信.
-
外围接口如下, 是不是相熟的滋味
type EventHandler interface {OnRecover(socket *Conn, exception interface{}) OnOpen(socket *Conn) OnClose(socket *Conn, code Code, reason []byte) OnMessage(socket *Conn, m *Message) OnError(socket *Conn, err error) OnPing(socket *Conn, m []byte) OnPong(socket *Conn, m []byte) }
-
聊天室代码
package main import ( "encoding/json" "github.com/lxzan/gws" "net/http" "sync" ) var handler = &Handler{sessions: sync.Map{}} type Handler struct {sessions sync.Map} func (h *Handler) OnRecover(socket *gws.Conn, exception interface{}) {} // 把连贯保留到 sync.Map, 用于 websocket 连贯之间的通信 func (h *Handler) OnOpen(socket *gws.Conn) {name, _ := socket.Storage.Get("name") h.sessions.Store(name.(string), socket) } func (h *Handler) OnClose(socket *gws.Conn, code gws.Code, reason []byte) {} // 通信格局 type Request struct { To string `json:"to"` Message string `json:"message"` } func (h *Handler) OnMessage(socket *gws.Conn, m *gws.Message) { var request Request json.Unmarshal(m.Bytes(), &request) me, _ := socket.Storage.Get("name") if me.(string) == request.To {socket.Write(m.MessageType(), m.Bytes()) m.Close()} else {if receiver, ok := h.sessions.Load(request.To); ok {h.OnMessage(receiver.(*gws.Conn), m) } } } func (h *Handler) OnError(socket *gws.Conn, err error) {} func (h *Handler) OnPing(socket *gws.Conn, m []byte) {} func (h *Handler) OnPong(socket *gws.Conn, m []byte) {} func main() { var upgrader = gws.Upgrader{ ServerOptions: &gws.ServerOptions{ LogEnabled: true, CompressEnabled: false, }, // 用户名由 url 带进来, 存到 storage 外面 CheckOrigin: func(r *gws.Request) bool {r.Storage.Put("name", r.URL.Query().Get("name")) return true }, } http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {upgrader.Upgrade(w, r, handler) }) http.ListenAndServe(":3000", nil) }