package overflow_gateway_websocket import ( "log" "net/http" "sync" "git.loafle.net/overflow/overflow_gateway_websocket/websocket" "github.com/valyala/fasthttp" ) type () type Server interface { ListenAndServe(addr string) error HandleClient(pattern string, o *ClientOptions) } type server struct { _option *ServerOptions _upgrader *websocket.Upgrader _handlers map[string]*ClientOptions _clients map[string]Client _cMtx sync.Mutex } func NewServer(o *ServerOptions) Server { s := &server{ _option: o.Validate(), _handlers: make(map[string]*ClientOptions, 1), _clients: make(map[string]Client, 100), } s._upgrader = &websocket.Upgrader{ HandshakeTimeout: s._option.HandshakeTimeout, ReadBufferSize: s._option.ReadBufferSize, WriteBufferSize: s._option.WriteBufferSize, CheckOrigin: s._option.OnCheckOrigin, Error: s.onError, EnableCompression: s._option.EnableCompression, } return s } func (s *server) onPush(cb OnPushFunc) { } func (s *server) onError(ctx *fasthttp.RequestCtx, status int, reason error) { } func (s *server) onDisconnected(c Client) { delete(s._clients, c.ID()) s._option.OnDisconnected(c) } func (s *server) onConnection(ctx *fasthttp.RequestCtx) { path := string(ctx.Path()) co, ok := s._handlers[path] if !ok { ctx.Response.Header.Set("Sec-Websocket-Version", "13") ctx.Error(http.StatusText(fasthttp.StatusNotFound), fasthttp.StatusNotFound) log.Printf("Path[%s] is not exist.", path) return } s._upgrader.Upgrade(ctx, nil, func(conn *websocket.Conn, err error) { if err != nil { log.Print("upgrade:", err) return } s._cMtx.Lock() cid := s._option.IDGenerator(ctx) c := NewClient(cid, path, co, conn) s._clients[cid] = c s._cMtx.Unlock() s._option.OnConnection(c) }) } func (s *server) HandleClient(pattern string, o *ClientOptions) { o.onDisconnected = s.onDisconnected s._handlers[pattern] = o.Validate() } func (s *server) ListenAndServe(addr string) error { return fasthttp.ListenAndServe(addr, s.onConnection) }