- Introduced a buffered write channel and a dedicated write worker goroutine to serialize write operations, preventing concurrent write panics. - Updated the Write and WriteControl methods to send messages through the write channel, improving error handling and connection stability. - Refactored ping and pong handlers to utilize the new write channel for sending control messages. - Enhanced publisher logic to manage write channels for WebSocket connections, ensuring efficient message delivery and error handling. - Bumped version to v0.23.0 to reflect these changes.
68 lines
1.3 KiB
Go
68 lines
1.3 KiB
Go
package publish
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"next.orly.dev/pkg/encoders/event"
|
|
"next.orly.dev/pkg/interfaces/publisher"
|
|
"next.orly.dev/pkg/interfaces/typer"
|
|
)
|
|
|
|
// WriteRequest represents a write operation to be performed by the write worker
|
|
type WriteRequest struct {
|
|
Data []byte
|
|
MsgType int
|
|
IsControl bool
|
|
Deadline time.Time
|
|
}
|
|
|
|
// WriteChanSetter defines the interface for setting write channels
|
|
type WriteChanSetter interface {
|
|
SetWriteChan(*websocket.Conn, chan<- WriteRequest)
|
|
GetWriteChan(*websocket.Conn) (chan<- WriteRequest, bool)
|
|
}
|
|
|
|
// S is the control structure for the subscription management scheme.
|
|
type S struct {
|
|
publisher.Publishers
|
|
}
|
|
|
|
// New creates a new publish.S.
|
|
func New(p ...publisher.I) (s *S) {
|
|
s = &S{Publishers: p}
|
|
return
|
|
}
|
|
|
|
var _ publisher.I = &S{}
|
|
|
|
func (s *S) Type() string { return "publish" }
|
|
|
|
func (s *S) Deliver(ev *event.E) {
|
|
for _, p := range s.Publishers {
|
|
p.Deliver(ev)
|
|
}
|
|
}
|
|
|
|
func (s *S) Receive(msg typer.T) {
|
|
t := msg.Type()
|
|
for _, p := range s.Publishers {
|
|
if p.Type() == t {
|
|
p.Receive(msg)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetSocketPublisher returns the socketapi publisher instance
|
|
func (s *S) GetSocketPublisher() WriteChanSetter {
|
|
for _, p := range s.Publishers {
|
|
if p.Type() == "socketapi" {
|
|
if socketPub, ok := p.(WriteChanSetter); ok {
|
|
return socketPub
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|