Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebPubSub]Init pr for webpubsub client sdk: Add public interface #32406

Merged
10 commits merged into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,15 @@
"words": [
"Orgs"
]
}
},
{
"filename": "**/sdk/webpubsub/**/*.cs",
"words": [
"protobuf",
"Ackable",
"awps"
]
}
],
"allowCompoundWords": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Messaging.WebPubSub.Client", "src\Azure.Messaging.WebPubSub.Client.csproj", "{845299CD-399C-4296-9F61-D4E02679363E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Messaging.WebPubSub.Client.Tests", "tests\Azure.Messaging.WebPubSub.Client.Tests.csproj", "{0B6AAD06-F541-4931-A661-16BE3BE24EEF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E5726134-6AA7-4AED-A654-53C92F09485A}"
ProjectSection(SolutionItems) = preProject
tests\test.runsettings = tests\test.runsettings
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|x64.ActiveCfg = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|x64.Build.0 = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|x86.ActiveCfg = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Debug|x86.Build.0 = Debug|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|Any CPU.Build.0 = Release|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|x64.ActiveCfg = Release|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|x64.Build.0 = Release|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|x86.ActiveCfg = Release|Any CPU
{845299CD-399C-4296-9F61-D4E02679363E}.Release|x86.Build.0 = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|x64.Build.0 = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|x86.ActiveCfg = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Debug|x86.Build.0 = Debug|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|Any CPU.Build.0 = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|x64.ActiveCfg = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|x64.Build.0 = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|x86.ActiveCfg = Release|Any CPU
{0B6AAD06-F541-4931-A661-16BE3BE24EEF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {72FA37A6-5914-405F-9A01-605ED24270D3}
EndGlobalSection
EndGlobal
4 changes: 4 additions & 0 deletions sdk/webpubsub/Azure.Messaging.WebPubSub.Client/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Release History

## 1.0.0-beta.1 (Unreleased)
- Initial beta release
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Add any shared properties you want for the projects under this package directory that need to be set before the auto imported Directory.Build.props
-->
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory).., Directory.Build.props))\Directory.Build.props" />
</Project>
195 changes: 195 additions & 0 deletions sdk/webpubsub/Azure.Messaging.WebPubSub.Client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Azure Web PubSub client library for .NET

[Azure Web PubSub Service](https://aka.ms/awps/doc) is an Azure-managed service that helps developers easily build web applications with real-time features and publish-subscribe pattern. Any scenario that requires real-time publish-subscribe messaging between server and clients or among clients can use Azure Web PubSub service. Traditional real-time features that often require polling from server or submitting HTTP requests can also use Azure Web PubSub service.

You can use this library in your client side to manage the WebSocket client connections, as shown in below diagram:

![overflow](https://user-images.githubusercontent.com/668244/140014067-25a00959-04dc-47e8-ac25-6957bd0a71ce.png)

Use this library to:

- Send messages to groups
- Send event to event handlers
- Join and leave groups
- Listen messages from groups and servers

Details about the terms used here are described in [Key concepts](#key-concepts) section.

[Source code](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/webpubsub/Azure.Messaging.WebPubSub.Client/src) |
[API reference documentation](https://aka.ms/awps/sdk/csharp) |
[Product documentation](https://aka.ms/awps/doc) |

## Getting started

### Install the package

Install the client library from [NuGet](https://www.nuget.org/):

```dotnetcli
dotnet add package Azure.Messaging.WebPubSub.Client
```

### Prerequisites

- An [Azure subscription][azure_sub].
- An existing Azure Web PubSub service instance.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Authenticate the client

In order to interact with the service, you'll need to create an instance of the `WebPubSubClient` class. To make this possible, you'll need the access token. You can copy and paste the access token from Azure portal which you can access in the Azure portal.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Construct
var client = new WebPubSubClient(new Uri("<client-access-uri>"));
```

And in production, you usually get `ClientAccessUri` from a negotiate server.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Construct2
var client = new WebPubSubClient(new WebPubSubClientCredential(token =>
zackliu marked this conversation as resolved.
Show resolved Hide resolved
{
// In common practice, you will have a negotiation server for generating token. Client should fetch token from it.
return FetchClientAccessTokenFromServerAsync(token);
}));
```

## Key concepts
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Connection

A connection, also known as a client or a client connection, represents an individual WebSocket connection connected to the Web PubSub service. When successfully connected, a unique connection ID is assigned to this connection by the Web PubSub service.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Recovery

If using reliable protocols, a new websocket will try to connect and reuse the connection ID of previous dropped connection. If the websocket connection is successfully connected, the connection is recovered. And all group context will be restored and unreceived messages will be resent.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Hub

A hub is a logical concept for a set of client connections. Usually you use one hub for one purpose, for example, a chat hub, or a notification hub. When a client connection is created, it connects to a hub, and during its lifetime, it belongs to that hub. Different applications can share one Azure Web PubSub service by using different hub names.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Group

A group is a subset of connections to the hub. You can add a client connection to a group, or remove the client connection from the group, anytime you want. For example, when a client joins a chat room, or when a client leaves the chat room, this chat room can be considered to be a group. A client can join multiple groups, and a group can contain multiple clients.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### User

Connections to Web PubSub can belong to one user. A user might have multiple connections, for example when a single user is connected across multiple devices or multiple browser tabs.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Message

When a client is connected, it can send messages to the upstream application, or receive messages from the upstream application, through the WebSocket connection. Also, it can send messages to groups and receive message from joined groups.
zackliu marked this conversation as resolved.
Show resolved Hide resolved
zackliu marked this conversation as resolved.
Show resolved Hide resolved

zackliu marked this conversation as resolved.
Show resolved Hide resolved
## Examples

### Send to groups

```C# Snippet:WebPubSubClient_SendToGroup
// Send message to group "testGroup"
await client.SendToGroupAsync("testGroup", BinaryData.FromString("hello world"), WebPubSubDataType.Text);
```

### Send events to event handler

```C# Snippet:WebPubSubClient_SendEvent
// Send custom event to server
await client.SendEventAsync("testEvent", BinaryData.FromString("hello world"), WebPubSubDataType.Text);
```

### Handle Connected
zackliu marked this conversation as resolved.
Show resolved Hide resolved

The `Connected` event is called after the client receives connected message. The event will be triggered every reconnection.

```C# Snippet:WebPubSubClient_Subscribe_Connected
client.Connected += e =>
zackliu marked this conversation as resolved.
Show resolved Hide resolved
{
Console.WriteLine($"Connection {e.ConnectionId} is connected");
return Task.CompletedTask;
};
```

### Handle Disconnected

The `Disconnected` is triggered every time the connection closed and can't be recovered
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Subscribe_Disconnected
client.Disconnected += e =>
{
Console.WriteLine($"Connection is disconnected");
return Task.CompletedTask;
};
```

### Handle Stopped

The `Stopped` is triggered when the client is stopped. The client won't try to reconnect after stopped. Usually it happenes when you call `StopAsync`
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Subscribe_Stopped
client.Stopped += e =>
{
Console.WriteLine($"Client is stopped");
return Task.CompletedTask;
};
```

### Handle Server message

The `ServerMessageReceived` is triggered when there's a message from server.

```C# Snippet:WebPubSubClient_Subscribe_ServerMessage
client.ServerMessageReceived += e =>
{
Console.WriteLine($"Receive message: {e.Message.Data}");
return Task.CompletedTask;
};
```

### Handle Group message

The `GroupMessageReceived` is triggered when there's a message from groups. You must join the group before you can receive messages from it.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Subscribe_GroupMessage
client.GroupMessageReceived += e =>
{
Console.WriteLine($"Receive group message from {e.Message.Group}: {e.Message.Data}");
return Task.CompletedTask;
};
```

### Handle restore failure

The `RestoreGroupFailed` is triggered when you enabled `AutoRestoreGroups` and operation of joining group failed after reconnection.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

```C# Snippet:WebPubSubClient_Subscribe_RestoreFailed
client.RestoreGroupFailed += e =>
{
Console.WriteLine($"Restore group failed");
return Task.CompletedTask;
};
```

## Troubleshooting
zackliu marked this conversation as resolved.
Show resolved Hide resolved

### Setting up console logging

You can also easily [enable console logging](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/samples/Diagnostics.md#logging) if you want to dig deeper into the requests you're making against the service.
zackliu marked this conversation as resolved.
Show resolved Hide resolved

## Next steps

You can also find [more samples here][awps_sample].

## Contributing

This project welcomes contributions and suggestions.
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution.
For details, visit <https://cla.microsoft.com.>

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment).
Simply follow the instructions provided by the bot.
You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Ftemplate%2FAzure.Template%2FREADME.png)

[azure_sub]: https://azure.microsoft.com/free/dotnet/
[awps_sample]: https://github.com/Azure/azure-webpubsub/tree/main/samples/csharp
Loading