68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
package fabricproto
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type WebSocketTransportConfig struct {
|
|
MaxPayload int
|
|
WriteTimeout time.Duration
|
|
}
|
|
|
|
func (l TransportLoop) RunWebSocket(ctx context.Context, conn *websocket.Conn, cfg WebSocketTransportConfig) error {
|
|
if l.Session == nil {
|
|
return ErrSessionNotConfigured
|
|
}
|
|
maxPayload := cfg.MaxPayload
|
|
if maxPayload <= 0 {
|
|
maxPayload = DefaultMaxPayload
|
|
}
|
|
writeTimeout := cfg.WriteTimeout
|
|
if writeTimeout <= 0 {
|
|
writeTimeout = 5 * time.Second
|
|
}
|
|
conn.SetReadLimit(int64(HeaderSize + maxPayload))
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
default:
|
|
}
|
|
|
|
messageType, payload, err := conn.ReadMessage()
|
|
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if messageType != websocket.BinaryMessage {
|
|
continue
|
|
}
|
|
frame, err := UnmarshalFrame(payload, maxPayload)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
responses, err := l.HandleFrame(ctx, frame)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, response := range responses {
|
|
encoded, err := MarshalFrame(response)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := conn.SetWriteDeadline(time.Now().Add(writeTimeout)); err != nil {
|
|
return err
|
|
}
|
|
if err := conn.WriteMessage(websocket.BinaryMessage, encoded); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|