package clients import ( "encoding/json" "fmt" "io" "log" "sync" "time" "git.loafle.net/overflow/overflow_gateway_websocket/clients/protocol" "git.loafle.net/overflow/overflow_gateway_websocket/websocket" "github.com/valyala/fasthttp" ) type Client interface { ID() string Conn() *websocket.Conn RequestCtx() *fasthttp.RequestCtx } type client struct { id string o *Options fastHTTPCtx *fasthttp.RequestCtx conn *websocket.Conn messageType int writeMTX sync.Mutex } func New(id string, o *Options, ctx *fasthttp.RequestCtx, conn *websocket.Conn) Client { c := &client{ id: id, o: o, fastHTTPCtx: ctx, conn: conn, messageType: websocket.TextMessage, } c.run() return c } func (c *client) ID() string { return c.id } func (c *client) Conn() *websocket.Conn { return c.conn } func (c *client) RequestCtx() *fasthttp.RequestCtx { return c.fastHTTPCtx } func (c *client) run() { hasReadTimeout := c.o.ReadTimeout > 0 c.conn.SetReadLimit(c.o.MaxMessageSize) // defer func() { // c.o.OnDisconnected(c) // }() for { if hasReadTimeout { c.conn.SetReadDeadline(time.Now().Add(c.o.ReadTimeout)) } // messageType, data, err := c.conn.ReadMessage() messageType, r, err := c.conn.NextReader() if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { //c.fireError(err) } break } else { c.onMessage(messageType, r) } } } func (c *client) onMessage(messageType int, r io.Reader) { var err error req := &protocol.ServerRequest{} err = json.NewDecoder(r).Decode(req) if err != nil { } if nil != req.Id { c.onRequest(req) } else { c.onNotify(req) } } func (c *client) onRequest(req *protocol.ServerRequest) { var err error result, err := c.o.OnRequest(c, req.Method, req.Params) res := &protocol.ServerResponse{ Id: req.Id, Result: result, Error: err, } c.writeMTX.Lock() if writeTimeout := c.o.WriteTimeout; writeTimeout > 0 { err := c.conn.SetWriteDeadline(time.Now().Add(writeTimeout)) log.Println(fmt.Errorf("%v", err)) return } j, err := json.Marshal(res) if nil != err { log.Println(fmt.Errorf("%v", err)) } err = c.conn.WriteMessage(c.messageType, j) c.writeMTX.Unlock() if nil != err { } } func (c *client) onNotify(req *protocol.ServerRequest) { err := c.o.OnNotify(c, req.Method, req.Params) if nil != err { log.Println(fmt.Errorf("%v", err)) } } func (c *client) sendError() { }