Skip to content

Commit 5ceb823

Browse files
committed
fix: wip
1 parent 8015f9f commit 5ceb823

File tree

12 files changed

+240
-27
lines changed

12 files changed

+240
-27
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
22
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002ESample_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
33
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002ESdk_002ESnapshotGenerator_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
4-
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002ESdk_002EUnitTests_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
4+
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002ESdk_002EUnitTests_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
5+
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002EWebSample_002EClient_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
6+
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Cnblogs_002EDashScope_002EWebSample_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

sample/Cnblogs.DashScope.WebSample.Client/Pages/Counter.razor

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55

66
<h1>Counter</h1>
77

8-
<p role="status">Current count: @currentCount</p>
8+
<p role="status">Current count: @_currentCount</p>
99

1010
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
1111

1212
@code {
13-
private int currentCount = 0;
13+
private int _currentCount;
1414

1515
private void IncrementCount()
1616
{
17-
currentCount++;
17+
_currentCount++;
1818
}
1919

2020
}

sample/Cnblogs.DashScope.WebSample/Components/Pages/Weather.razor

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<p>This component demonstrates showing data.</p>
99

10-
@if (forecasts == null)
10+
@if (_forecasts == null)
1111
{
1212
<p>
1313
<em>Loading...</em>
@@ -25,7 +25,7 @@ else
2525
</tr>
2626
</thead>
2727
<tbody>
28-
@foreach (var forecast in forecasts)
28+
@foreach (var forecast in _forecasts)
2929
{
3030
<tr>
3131
<td>@forecast.Date.ToShortDateString()</td>
@@ -39,7 +39,7 @@ else
3939
}
4040

4141
@code {
42-
private WeatherForecast[]? forecasts;
42+
private WeatherForecast[]? _forecasts;
4343

4444
protected override async Task OnInitializedAsync()
4545
{
@@ -48,7 +48,7 @@ else
4848

4949
var startDate = DateOnly.FromDateTime(DateTime.Now);
5050
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
51-
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
51+
_forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
5252
{
5353
Date = startDate.AddDays(index),
5454
TemperatureC = Random.Shared.Next(-20, 55),

sample/Cnblogs.DashScope.WebSample/Program.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Cnblogs.DashScope.WebSample.Client.Pages;
21
using Cnblogs.DashScope.WebSample.Components;
32

43
var builder = WebApplication.CreateBuilder(args);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly:InternalsVisibleTo("Cnblogs.DashScope.Sdk.UnitTests")]
4+
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

src/Cnblogs.DashScope.Core/DashScopeClientWebSocket.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/Cnblogs.DashScope.Core/DashScopeClientWebSocketWrapper.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public sealed record DashScopeClientWebSocketWrapper(DashScopeClientWebSocket So
1111
/// <summary>
1212
/// The binary output.
1313
/// </summary>
14-
public IAsyncEnumerable<byte> BinaryOutput => Socket.BinaryOutput.Reader.ReadAllAsync();
14+
public IAsyncEnumerable<byte> BinaryOutput => Socket.BinaryOutput.ReadAllAsync();
1515

1616
/// <summary>
1717
/// The task that completes when received task-started event from server.
@@ -48,6 +48,9 @@ public void Dispose()
4848
GC.SuppressFinalize(this);
4949
}
5050

51+
/// <summary>
52+
/// Finalizer.
53+
/// </summary>
5154
~DashScopeClientWebSocketWrapper()
5255
{
5356
Dispose();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("Cnblogs.DashScope.Sdk.UnitTests")]
4+
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Net.WebSockets;
2+
3+
namespace Cnblogs.DashScope.Core.Internals;
4+
5+
internal sealed class ClientWebSocketWrapper(ClientWebSocket socket) : IClientWebSocket
6+
{
7+
/// <inheritdoc />
8+
public void Dispose()
9+
{
10+
socket.Dispose();
11+
}
12+
13+
/// <inheritdoc />
14+
public ClientWebSocketOptions Options => socket.Options;
15+
16+
/// <inheritdoc />
17+
public WebSocketCloseStatus? CloseStatus => socket.CloseStatus;
18+
19+
/// <inheritdoc />
20+
public Task ConnectAsync(Uri uri, CancellationToken cancellation) => socket.ConnectAsync(uri, cancellation);
21+
22+
/// <inheritdoc />
23+
public Task SendAsync(
24+
ArraySegment<byte> buffer,
25+
WebSocketMessageType messageType,
26+
bool endOfMessage,
27+
CancellationToken cancellationToken)
28+
=> socket.SendAsync(buffer, messageType, endOfMessage, cancellationToken);
29+
30+
/// <inheritdoc />
31+
public Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
32+
=> socket.ReceiveAsync(buffer, cancellationToken);
33+
34+
/// <inheritdoc />
35+
public Task CloseAsync(
36+
WebSocketCloseStatus closeStatus,
37+
string? statusDescription,
38+
CancellationToken cancellationToken)
39+
=> socket.CloseAsync(closeStatus, statusDescription, cancellationToken);
40+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Net.WebSockets;
2+
3+
namespace Cnblogs.DashScope.Core.Internals;
4+
5+
/// <summary>
6+
/// Extract <see cref="ClientWebSocket"/> for testing purpose.
7+
/// </summary>
8+
internal interface IClientWebSocket : IDisposable
9+
{
10+
public ClientWebSocketOptions Options { get; }
11+
12+
public WebSocketCloseStatus? CloseStatus { get; }
13+
14+
public Task ConnectAsync(Uri uri, CancellationToken cancellation);
15+
16+
public Task SendAsync(
17+
ArraySegment<byte> buffer,
18+
WebSocketMessageType messageType,
19+
bool endOfMessage,
20+
CancellationToken cancellationToken);
21+
22+
Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken);
23+
24+
Task CloseAsync(WebSocketCloseStatus closeStatus, string? statusDescription, CancellationToken cancellationToken);
25+
}

0 commit comments

Comments
 (0)