这里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 mainimport ( "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)}