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 } } } }