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客户端,您可以检查其ConnectionIdUserId属性,例如。

下一步可能是加入一些组

IWebSocketeerGroup group = await socketeer.JoinAsync("MyGroup");

IWebSocketeerGroupReadOnlyMemory<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 已计算。
兼容目标框架
包含目标框架(在包中)
了解更多关于 目标框架.NET Standard

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