@@ -19,14 +19,17 @@ public sealed class DashScopeClientWebSocket : IDisposable
1919 AllowSynchronousContinuations = true
2020 } ;
2121
22- private readonly ClientWebSocket _socket = new ( ) ;
22+ private readonly IClientWebSocket _socket ;
2323 private Task ? _receiveTask ;
2424 private TaskCompletionSource < bool > _taskStartedSignal = new ( ) ;
25+ private Channel < byte > ? _binaryOutput ;
2526
2627 /// <summary>
2728 /// The binary output.
2829 /// </summary>
29- public Channel < byte > BinaryOutput { get ; private set ; } = Channel . CreateUnbounded < byte > ( UnboundedChannelOptions ) ;
30+ public ChannelReader < byte > BinaryOutput
31+ => _binaryOutput ? . Reader
32+ ?? throw new InvalidOperationException ( "Please call ResetOutput() before accessing output" ) ;
3033
3134 /// <summary>
3235 /// A task that completed when received task-started event.
@@ -45,6 +48,7 @@ public sealed class DashScopeClientWebSocket : IDisposable
4548 /// <param name="workspaceId">Optional workspace id.</param>
4649 public DashScopeClientWebSocket ( string apiKey , string ? workspaceId = null )
4750 {
51+ _socket = new ClientWebSocketWrapper ( new ClientWebSocket ( ) ) ;
4852 _socket . Options . SetRequestHeader ( "X-DashScope-DataInspection" , "enable" ) ;
4953 _socket . Options . SetRequestHeader ( "Authorization" , $ "bearer { apiKey } ") ;
5054 if ( string . IsNullOrEmpty ( workspaceId ) == false )
@@ -53,6 +57,15 @@ public DashScopeClientWebSocket(string apiKey, string? workspaceId = null)
5357 }
5458 }
5559
60+ /// <summary>
61+ /// Initiate a <see cref="DashScopeClientWebSocket"/> with a pre-configured <see cref="ClientWebSocket"/>.
62+ /// </summary>
63+ /// <param name="socket">Pre-configured <see cref="ClientWebSocket"/>.</param>
64+ internal DashScopeClientWebSocket ( IClientWebSocket socket )
65+ {
66+ _socket = socket ;
67+ }
68+
5669 /// <summary>
5770 /// Start a websocket connection.
5871 /// </summary>
@@ -74,8 +87,9 @@ public async Task ConnectAsync<TOutput>(Uri uri, CancellationToken cancellationT
7487 /// </summary>
7588 public void ResetOutput ( )
7689 {
77- BinaryOutput . Writer . TryComplete ( ) ;
78- BinaryOutput = Channel . CreateUnbounded < byte > ( UnboundedChannelOptions ) ;
90+ _binaryOutput ? . Writer . TryComplete ( ) ;
91+ _binaryOutput = Channel . CreateUnbounded < byte > ( UnboundedChannelOptions ) ;
92+ _taskStartedSignal . TrySetResult ( false ) ;
7993 _taskStartedSignal = new TaskCompletionSource < bool > ( ) ;
8094 }
8195
@@ -129,7 +143,7 @@ public Task SendMessageAsync<TInput, TParameter>(
129143 {
130144 for ( var i = 0 ; i < result . Count ; i ++ )
131145 {
132- await BinaryOutput . Writer . WriteAsync ( buffer [ i ] , cancellationToken ) ;
146+ await _binaryOutput ! . Writer . WriteAsync ( buffer [ i ] , cancellationToken ) ;
133147 }
134148
135149 return null ;
@@ -177,7 +191,7 @@ public async Task ReceiveMessagesAsync<TOutput>(CancellationToken cancellationTo
177191 break ;
178192 case "task-finished" :
179193 State = DashScopeWebSocketState . Ready ;
180- BinaryOutput . Writer . Complete ( ) ;
194+ _binaryOutput ? . Writer . Complete ( ) ;
181195 break ;
182196 case "task-failed" :
183197 await CloseAsync ( cancellationToken ) ;
@@ -216,7 +230,7 @@ private void Dispose(bool disposing)
216230 {
217231 // Dispose managed resources.
218232 _socket . Dispose ( ) ;
219- BinaryOutput . Writer . TryComplete ( ) ;
233+ _binaryOutput ? . Writer . TryComplete ( ) ;
220234 }
221235 }
222236
0 commit comments