func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	so, err := newSocket(s.upgrader, w, r)
	if err != nil {
		log.Println("register:", err)
		return
	}
	s.sockets.Store(so.id, so)     
	defer so.close()               
	defer s.sockets.Delete(so.id)  
	if s.open != nil {
		s.open(so, NewMessage(EventConnected))
	}
	if s.close != nil {
		defer s.close(so, NewMessage(EventDisconnected))
	}
	for {
		m, err := so.readMessage()
		if err != nil {
			so.Send("error", "Failed to read message")
			return
		}
		go func() {
			if fn, ok := s.handlers[m.Type]; ok {
				if err := fn(so, m); err != nil {
					log.Println("fn:", err)
					return
				}
			} else {
				so.Send("error", "Unknown type")
			}
		}()
	}
}
ServeHTTP is the primary websocket handler method and conforms to the
http.Handler interface.
package msgkit
import (
	"log"
	"net/http"
	"sync"
	"github.com/gorilla/websocket"
)
const (
	EventConnected = "connected"
	EventDisconnected = "disconnected"
)
type Server struct {
	sockets  sync.Map                
	upgrader *websocket.Upgrader     
	open     HandlerFunc             
	close    HandlerFunc             
	handlers map[string]HandlerFunc  
}
type HandlerFunc func(so *Socket, msg *Message) error
func NewServer(u *websocket.Upgrader) *Server {
	if u == nil {
		u = &websocket.Upgrader{}
	}
	return &Server{
		upgrader: u,
		handlers: make(map[string]HandlerFunc),
	}
}
func (s *Server) Handle(name string, handler HandlerFunc) {
	switch name {
	case EventConnected:
		s.open = handler
	case EventDisconnected:
		s.close = handler
	default:
		if s.handlers == nil {
			s.handlers = make(map[string]HandlerFunc)
		}
		s.handlers[name] = handler
	}
}
func (s *Server) Broadcast(name, msg string) {
	s.sockets.Range(func(_, soi interface{}) bool {
		if so, ok := soi.(*Socket); ok {
			so.Send(name, msg)
		}
		return true
	})
}