6464 RetrySendTimeout = 20 * time .Millisecond
6565 // MaxSendRetry defines the max retries for transient socket write issues.
6666 MaxSendRetry = 5
67- // ReadTimeout controls the pause between read attempts.
67+ // SendQueueSize controls the per-connection outbound message queue size.
68+ SendQueueSize = 100
69+ // ReadTimeout is deprecated and no longer used; reads block until a
70+ // message arrives or the connection is closed.
6871 ReadTimeout = 10 * time .Millisecond
6972)
7073
@@ -214,9 +217,7 @@ func (l *safeListeners) get(event string) []eventCallback {
214217 return make ([]eventCallback , 0 )
215218 }
216219
217- ret := make ([]eventCallback , 0 , len (l .list [event ]))
218- ret = append (ret , l .list [event ]... )
219- return ret
220+ return append ([]eventCallback (nil ), l .list [event ]... )
220221}
221222
222223var listeners = safeListeners {
@@ -241,7 +242,7 @@ func New(callback func(kws *Websocket), config ...websocket.Config) fiber.Handle
241242 Cookies : func (key string , defaultValue ... string ) string {
242243 return c .Cookies (key , defaultValue ... )
243244 },
244- queue : make (chan message , 100 ),
245+ queue : make (chan message , sendQueueSize () ),
245246 done : make (chan struct {}, 1 ),
246247 attributes : make (map [string ]interface {}),
247248 isAlive : true ,
@@ -422,6 +423,7 @@ func (kws *Websocket) Emit(message []byte, mType ...int) {
422423func (kws * Websocket ) Close () {
423424 kws .write (CloseMessage , []byte ("Connection closed" ))
424425 kws .fireEvent (EventClose , nil , nil )
426+ kws .disconnected (nil )
425427}
426428
427429// IsAlive reports whether the connection is active.
@@ -475,15 +477,25 @@ func (kws *Websocket) send(ctx context.Context) {
475477 case msg := <- kws .queue :
476478 if ! kws .hasConn () {
477479 if msg .retries <= MaxSendRetry {
478- go func (msg message ) {
479- time .Sleep (RetrySendTimeout )
480- msg .retries ++
481- select {
482- case kws .queue <- msg :
483- case <- ctx .Done ():
484- case <- kws .done :
485- }
486- }(msg )
480+ retryTimer := time .NewTimer (RetrySendTimeout )
481+ select {
482+ case <- retryTimer .C :
483+ case <- ctx .Done ():
484+ stopTimer (retryTimer )
485+ return
486+ case <- kws .done :
487+ stopTimer (retryTimer )
488+ return
489+ }
490+
491+ msg .retries ++
492+ select {
493+ case kws .queue <- msg :
494+ case <- ctx .Done ():
495+ return
496+ case <- kws .done :
497+ return
498+ }
487499 }
488500 continue
489501 }
@@ -522,42 +534,35 @@ func (kws *Websocket) run() {
522534 wg .Wait ()
523535}
524536
525- func (kws * Websocket ) read (ctx context.Context ) {
526- timeoutTicker := time .NewTicker (ReadTimeout )
527- defer timeoutTicker .Stop ()
537+ func (kws * Websocket ) read (_ context.Context ) {
528538 for {
529- select {
530- case <- timeoutTicker .C :
531- if ! kws .hasConn () {
532- continue
533- }
534-
535- mType , msg , err := kws .Conn .ReadMessage ()
539+ if ! kws .hasConn () {
540+ return
541+ }
536542
537- if mType == PingMessage {
538- kws .fireEvent (EventPing , nil , nil )
539- continue
540- }
543+ mType , msg , err := kws .Conn .ReadMessage ()
541544
542- if mType == PongMessage {
543- kws .fireEvent (EventPong , nil , nil )
544- continue
545- }
545+ if mType == PingMessage {
546+ kws .fireEvent (EventPing , nil , nil )
547+ continue
548+ }
546549
547- if mType == CloseMessage {
548- kws .disconnected ( nil )
549- return
550- }
550+ if mType == PongMessage {
551+ kws .fireEvent ( EventPong , nil , nil )
552+ continue
553+ }
551554
552- if err != nil {
553- kws .disconnected (err )
554- return
555- }
555+ if mType == CloseMessage {
556+ kws .disconnected (nil )
557+ return
558+ }
556559
557- kws . fireEvent ( EventMessage , msg , nil )
558- case <- ctx . Done ():
560+ if err != nil {
561+ kws . disconnected ( err )
559562 return
560563 }
564+
565+ kws .fireEvent (EventMessage , msg , nil )
561566 }
562567}
563568
@@ -597,6 +602,22 @@ func (kws *Websocket) randomUUID() string {
597602 return uuid .New ().String ()
598603}
599604
605+ func sendQueueSize () int {
606+ if SendQueueSize <= 0 {
607+ return 1
608+ }
609+ return SendQueueSize
610+ }
611+
612+ func stopTimer (timer * time.Timer ) {
613+ if ! timer .Stop () {
614+ select {
615+ case <- timer .C :
616+ default :
617+ }
618+ }
619+ }
620+
600621func fireGlobalEvent (event string , data []byte , err error ) {
601622 for _ , kws := range pool .all () {
602623 kws .fireEvent (event , data , err )
0 commit comments