dotnet add package WebSocketeer --version 1.0.0
NuGet\Install-Package WebSocketeer -Version 1.0.0
<PackageReference Include="WebSocketeer" Version="1.0.0" />
paket add WebSocketeer --version 1.0.0
#r "nuget: WebSocketeer, 1.0.0"
// Install WebSocketeer as a Cake Addin #addin nuget:?package=WebSocketeer&version=1.0.0 // Install WebSocketeer as a Cake Tool #tool nuget:?package=WebSocketeer&version=1.0.0
为Azure Web PubSub protobuf子协议提供一个瘦、直观、惯用和高性能的API。
使用方法
首先使用官方客户端API获取适当的Azure Web PubSub客户端访问URI,例如
var serviceClient = new WebPubSubServiceClient([WEB_PUB_SUB_CONNECTION_STRING], [HUB_NAME]);
var serviceUri = serviceClient.GenerateClientAccessUri(
userId: Guid.NewGuid().ToString("N"),
roles: new[]
{
"webpubsub.joinLeaveGroup",
"webpubsub.sendToGroup"
});
然后简单地连接到WebSocketeer
await using IWebSocketeer socketeer = WebSocketeer.ConnectAsync(serviceUri);
注意:
IWebSocketeer
接口实现了IAsyncDisposable
,这允许使用上面的await using
模式,同时也实现了IDisposable
接口。前者将执行优雅的WebSocket
断开/关闭。后者将简单地释放底层的WebSocket
。
此时,socketeer
变量包含了一个适当连接的Web PubSub客户端,您可以检查其ConnectionId
和UserId
属性,例如。
下一步可能是加入一些组
IWebSocketeerGroup group = await socketeer.JoinAsync("MyGroup");
IWebSocketeerGroup
是ReadOnlyMemory<byte>
的可观察对象,它公开了该组传入的消息,并且它还提供了一个SendAsync(ReadOnlyMemory<byte> message)
方法来向该组发送消息。
要将该组所有传入的消息都写入控制台,您可以编写
using var subscription = group.Subscribe(bytes =>
Console.WriteLine(Encoding.UTF8.GetString(bytes.Span)));
不过,要开始处理传入的消息,您首先需要启动socketeer的“消息循环”。这通常会在单独的线程上完成,例如使用Task.Run
。
var started = Task.Run(() => socketeer.RunAsync());
RunAsync
返回的任务将在 Socketeer 被释放,或底层的 WebSocket
被关闭(无论是由客户端还是服务器完成),或者传递给它的可取消令牌被取消之前保持进行状态。
您还可以通过 IWebSocketeer.SendAsync
方法向尚未加入的群组发送消息(前提是在打开连接时指定的角色允许这样做)。
await socketeer.SendAsync("YourGroup", Encoding.UTF8.GetBytes("Hello World"));
高级方案
访问已加入的群组
有时,提前执行群组加入是有用的,但在稍后的某个时间点,您可能还需要从同一个 IWebSocketeer
实例获取先前已加入的群组。
IWebSocketeer socketeer = /* connect, join some groups, etc. */;
// If group hasn't been joined previously, no incoming messages would arrive in this case.
IWebSocketeerGroup group = socketeer.Joined("incoming");
group.Subscribe(x => /* process incoming */);
处理 WebSocket
您也可以自行处理 WebSocket
。您不是将服务 Uri
传递给 ConnectAsync
,而是可以手动创建和连接一个 WebSocket
,并将其传递给 WebSocketeer.ConnectAsync(WebSocket, CancellationToken)
覆载。
在这种情况下,重要的是要记住添加所需的子协议 protobuf.webpubsub.azure.v1
。
using Devlooped.Net;
var client = new ClientWebSocket();
client.Options.AddSubProtocol("protobuf.webpubsub.azure.v1");
await client.ConnectAsync(serverUri, CancellationToken.None);
await using var socketeer = WebSocketeer.ConnectAsync(client);
拆分请求/响应组
您可能想在 Socketeer 上模拟请求/响应通信模式。在这种情况下,您通常会执行以下操作:
- 服务器加入了特定于客户端的群组,例如
SERVER_ID-CLIENT_ID
(格式为[TO]-[FROM]
,因此 TO=服务器,FROM=客户端)。 - 服务器响应该组中的请求,通过向
CLIENT_ID-SERVER_ID
发送响应(TO=客户端,FROM=服务器); - 客户端加入响应组
CLIENT_ID-SERVER_ID
,并根据需要发送请求到SERVER_ID-CLIENT_ID
。
请注意,客户端 不能 加入 SERVER_ID-CLIENT_ID
组,否则它也会收到只能发送给服务器的自己的消息。同样,服务器也无法加入 CLIENT_ID-SERVER_ID
组。这就是为什么这种模式可能比看起来更加常见。
服务器端
IWebSocketeer socketeer = ...;
var serverId = socketeer.UserId;
// Perhaps from an initial exchange over a shared channel
var clientId = ...;
await using IWebSocketeerGroup clientChannel = socketeer.Split(
await socketeer.JoinAsync($"{serverId}-{clientId}"),
$"{clientId}-{serverId}");
clientChannel.Subscribe(async x =>
{
// do some processing on incoming requests.
...
// send a response via the outgoing group
await clientChannel.SendAsync(response);
});
客户端
IWebSocketeer socketeer = ...;
var clientId = socketeer.UserId;
// Perhaps a known identifier, or looked up somehow
var serverId = ...;
await using IWebSocketeerGroup serverChannel = socketeer.Split(
await socketeer.JoinAsync($"{clientId}-{serverId}""),
$"{serverId}-{clientId}");
serverChannel.Subscribe(async x => /* process responses */);
await serverChannel.SendAsync(request);
产品 | 版本兼容的和额外的目标框架版本。 |
---|---|
.NET | net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
-
net6.0
- Google.Protobuf (≥ 3.21.4)
- WebSocketChannel (≥ 0.9.2)
NuGet 包
此包未被任何 NuGet 包使用。
GitHub 仓库
此包未被任何流行的 GitHub 仓库使用。
版本 | 下载 | 最后更新 |
---|---|---|
1.0.0 | 790 | 8/8/2022 |
0.9.0 | 938 | 10/15/2021 |
0.9.0-beta | 714 | 10/15/2021 |
0.9.0-alpha | 199 | 10/15/2021 |