@@ -169,6 +169,8 @@ public abstract class DbConnectionBase<DbConnection, Tables, Reducer> : IDbConne
169169 protected abstract IErrorContext ToErrorContext ( Exception errorContext ) ;
170170 protected abstract IProcedureEventContext ToProcedureEventContext ( ProcedureEvent procedureEvent ) ;
171171
172+ private Func < byte [ ] , byte [ ] [ ] > decodeTransportMessages = DecodeV2TransportMessages ;
173+
172174 private readonly ConcurrentDictionary < uint , TaskCompletionSource < OneOffQueryResult > > waitingOneOffQueries = new ( ) ;
173175
174176 private readonly ConcurrentDictionary < uint , PendingReducerCall > pendingReducerCalls = new ( ) ;
@@ -220,10 +222,16 @@ protected DbConnectionBase()
220222 {
221223 var options = new WebSocket . ConnectOptions
222224 {
223- Protocol = "v2.bsatn.spacetimedb"
225+ Protocols = WebSocketProtocols . Preferred
224226 } ;
225227 webSocket = new WebSocket ( options ) ;
226228 webSocket . OnMessage += OnMessageReceived ;
229+ webSocket . OnProtocolNegotiated += protocolVersion =>
230+ {
231+ decodeTransportMessages = protocolVersion == WebSocketProtocolVersion . V3
232+ ? WebSocketV3Payload . DecodeServerMessages
233+ : DecodeV2TransportMessages ;
234+ } ;
227235 webSocket . OnSendError += a => onSendError ? . Invoke ( a ) ;
228236#if UNITY_5_3_OR_NEWER
229237 webSocket . OnClose += ( e ) =>
@@ -289,6 +297,8 @@ internal struct ParsedMessage
289297
290298 private static readonly Status Committed = new Status . Committed ( default ) ;
291299
300+ private static byte [ ] [ ] DecodeV2TransportMessages ( byte [ ] payload ) => new [ ] { payload } ;
301+
292302 /// <summary>
293303 /// Get a description of a message suitable for storing in the tracker metadata.
294304 /// </summary>
@@ -427,9 +437,18 @@ void ParseOneOffQuery(OneOffQueryResult resp)
427437#endif
428438 try
429439 {
430- var message = _parseQueue . Take ( _parseCancellationToken ) ;
431- var parsedMessage = ParseMessage ( message ) ;
432- _applyQueue . Add ( parsedMessage , _parseCancellationToken ) ;
440+ var unparsed = _parseQueue . Take ( _parseCancellationToken ) ;
441+ var payload = CompressionHelpers . DecompressMessagePayload ( unparsed . bytes ) ;
442+ var decodedMessages = decodeTransportMessages ( payload ) ;
443+ stats . ParseMessageQueueTracker . FinishTrackingRequest (
444+ unparsed . parseQueueTrackerId ,
445+ $ "type=ws_payload,count={ decodedMessages . Length } "
446+ ) ;
447+ foreach ( var messageBytes in decodedMessages )
448+ {
449+ var parsedMessage = ParseMessage ( messageBytes , unparsed . timestamp ) ;
450+ _applyQueue . Add ( parsedMessage , _parseCancellationToken ) ;
451+ }
433452 }
434453 catch ( OperationCanceledException )
435454 {
@@ -452,13 +471,12 @@ void ParseOneOffQuery(OneOffQueryResult resp)
452471 }
453472 }
454473
455- ParsedMessage ParseMessage ( UnparsedMessage unparsed )
474+ ParsedMessage ParseMessage ( byte [ ] messageBytes , DateTime timestamp )
456475 {
457476 var dbOps = ParsedDatabaseUpdate . New ( ) ;
458- var message = CompressionHelpers . DecompressDecodeMessage ( unparsed . bytes ) ;
477+ var message = CompressionHelpers . DecodeServerMessage ( messageBytes ) ;
459478 var trackerMetadata = TrackerMetadataForMessage ( message ) ;
460479
461- stats . ParseMessageQueueTracker . FinishTrackingRequest ( unparsed . parseQueueTrackerId , trackerMetadata ) ;
462480 var parseStart = DateTime . UtcNow ;
463481
464482 ReducerEvent < Reducer > ? reducerEvent = default ;
@@ -469,11 +487,11 @@ ParsedMessage ParseMessage(UnparsedMessage unparsed)
469487 case ServerMessage . InitialConnection :
470488 break ;
471489 case ServerMessage . SubscribeApplied ( var subscribeApplied ) :
472- stats . SubscriptionRequestTracker . FinishTrackingRequest ( subscribeApplied . RequestId , unparsed . timestamp ) ;
490+ stats . SubscriptionRequestTracker . FinishTrackingRequest ( subscribeApplied . RequestId , timestamp ) ;
473491 dbOps = ParseSubscribeRows ( subscribeApplied . Rows ) ;
474492 break ;
475493 case ServerMessage . UnsubscribeApplied ( var unsubscribeApplied ) :
476- stats . SubscriptionRequestTracker . FinishTrackingRequest ( unsubscribeApplied . RequestId , unparsed . timestamp ) ;
494+ stats . SubscriptionRequestTracker . FinishTrackingRequest ( unsubscribeApplied . RequestId , timestamp ) ;
477495 if ( unsubscribeApplied . Rows != null )
478496 {
479497 dbOps = ParseUnsubscribeRows ( unsubscribeApplied . Rows ) ;
@@ -482,7 +500,7 @@ ParsedMessage ParseMessage(UnparsedMessage unparsed)
482500 case ServerMessage . SubscriptionError ( var subscriptionError ) :
483501 if ( subscriptionError . RequestId . HasValue )
484502 {
485- stats . SubscriptionRequestTracker . FinishTrackingRequest ( subscriptionError . RequestId . Value , unparsed . timestamp ) ;
503+ stats . SubscriptionRequestTracker . FinishTrackingRequest ( subscriptionError . RequestId . Value , timestamp ) ;
486504 }
487505 break ;
488506 case ServerMessage . TransactionUpdate ( var transactionUpdate ) :
@@ -492,7 +510,7 @@ ParsedMessage ParseMessage(UnparsedMessage unparsed)
492510 ParseOneOffQuery ( resp ) ;
493511 break ;
494512 case ServerMessage . ReducerResult ( var reducerResult ) :
495- if ( ! stats . ReducerRequestTracker . FinishTrackingRequest ( reducerResult . RequestId , unparsed . timestamp ) )
513+ if ( ! stats . ReducerRequestTracker . FinishTrackingRequest ( reducerResult . RequestId , timestamp ) )
496514 {
497515 Log . Warn ( $ "Failed to finish tracking reducer request: { reducerResult . RequestId } ") ;
498516 }
@@ -545,7 +563,7 @@ ParsedMessage ParseMessage(UnparsedMessage unparsed)
545563 procedureResult . RequestId
546564 ) ;
547565
548- if ( ! stats . ProcedureRequestTracker . FinishTrackingRequest ( procedureResult . RequestId , unparsed . timestamp ) )
566+ if ( ! stats . ProcedureRequestTracker . FinishTrackingRequest ( procedureResult . RequestId , timestamp ) )
549567 {
550568 Log . Warn ( $ "Failed to finish tracking procedure request: { procedureResult . RequestId } ") ;
551569 }
@@ -558,7 +576,7 @@ ParsedMessage ParseMessage(UnparsedMessage unparsed)
558576 stats . ParseMessageTracker . InsertRequest ( parseStart , trackerMetadata ) ;
559577 var applyTracker = stats . ApplyMessageQueueTracker . StartTrackingRequest ( trackerMetadata ) ;
560578
561- return new ParsedMessage { message = message , dbOps = dbOps , receiveTimestamp = unparsed . timestamp , applyQueueTrackerId = applyTracker , reducerEvent = reducerEvent , procedureEvent = procedureEvent } ;
579+ return new ParsedMessage { message = message , dbOps = dbOps , receiveTimestamp = timestamp , applyQueueTrackerId = applyTracker , reducerEvent = reducerEvent , procedureEvent = procedureEvent } ;
562580 }
563581 }
564582
@@ -609,6 +627,7 @@ void IDbConnection.Connect(string? token, string uri, string addressOrName, Comp
609627 {
610628 isClosing = false ;
611629 connectionClosed = false ;
630+ decodeTransportMessages = DecodeV2TransportMessages ;
612631 Identity = null ;
613632 initialConnectionId = null ;
614633 onConnectInvoked = false ;
0 commit comments