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

Adding aspire apphost to samples #2037

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion .github/workflows/osx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: macOS-latest
strategy:
matrix:
dotnet-version: [ '8.0.x', '7.0.x', '6.0.x' ]
dotnet-version: [ '8.0.x' ]
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
Expand Down Expand Up @@ -41,6 +41,8 @@ jobs:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Display dotnet version
run: dotnet --version
- name: Install aspire workload
run: dotnet workload install aspire
- name: Build with dotnet
run: |
if [ "${{ matrix.dotnet-version }}" != "6.0.x" ]; then
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: [ '8.0.x', '7.0.x', '6.0.x' ]
dotnet-version: [ '8.0.x' ]
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
Expand Down Expand Up @@ -41,6 +41,8 @@ jobs:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Display dotnet version
run: dotnet --version
- name: Install aspire workload
run: dotnet workload install aspire
- name: Build with dotnet
run: "dotnet build AzureSignalR.sln /p:DisableNet461Tests=true"
if: steps.filter.outputs.src == 'true'
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: [windows-latest]
strategy:
matrix:
dotnet-version: [ '8.0.x', '7.0.x', '6.0.x' ]
dotnet-version: [ '8.0.x' ]
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
Expand Down Expand Up @@ -41,6 +41,8 @@ jobs:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Display dotnet version
run: dotnet --version
- name: Install aspire workload
run: dotnet workload install aspire
- name: Build with dotnet
run: "dotnet build AzureSignalR.sln"
if: steps.filter.outputs.src == 'true'
Expand Down
7 changes: 7 additions & 0 deletions AzureSignalR.sln
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatSample.Net70", "samples
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagementPublisher", "samples\ChatSample\ChatSample.ManagementPublisher\ManagementPublisher.csproj", "{0F32E624-7AC8-4CA7-8ED9-E1A877442020}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AppHost", "samples\Samples.AppHost\Samples.AppHost.csproj", "{66AA925F-2FFC-4CBF-906F-5BEDC1010062}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -203,6 +205,10 @@ Global
{0F32E624-7AC8-4CA7-8ED9-E1A877442020}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F32E624-7AC8-4CA7-8ED9-E1A877442020}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F32E624-7AC8-4CA7-8ED9-E1A877442020}.Release|Any CPU.Build.0 = Release|Any CPU
{66AA925F-2FFC-4CBF-906F-5BEDC1010062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66AA925F-2FFC-4CBF-906F-5BEDC1010062}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66AA925F-2FFC-4CBF-906F-5BEDC1010062}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66AA925F-2FFC-4CBF-906F-5BEDC1010062}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -237,6 +243,7 @@ Global
{594EC59A-7305-4A36-8BE6-4A928FBFD71B} = {C965ED06-6A17-4329-B3C6-811830F4F4ED}
{49634EE4-A0F4-4672-A8B3-B994CF81C9AB} = {C965ED06-6A17-4329-B3C6-811830F4F4ED}
{0F32E624-7AC8-4CA7-8ED9-E1A877442020} = {C965ED06-6A17-4329-B3C6-811830F4F4ED}
{66AA925F-2FFC-4CBF-906F-5BEDC1010062} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7945A4E4-ACDB-4F6E-95CA-6AC6E7C2CD59}
Expand Down
4 changes: 4 additions & 0 deletions build/dependencies.private.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@
<MicrosoftConfigurationUserSecretVersion>2.2.0</MicrosoftConfigurationUserSecretVersion>
<MicrosoftConfigurationEnvironmentVariablesVersion>2.2.0</MicrosoftConfigurationEnvironmentVariablesVersion>
<E2eTestUserSecretId>E2eTestUserSecret</E2eTestUserSecretId>

<AspireHostingAppHostPackageVersion>8.1.0</AspireHostingAppHostPackageVersion>
<AspireHostingAzureSignalRPackageVersion>8.1.0</AspireHostingAzureSignalRPackageVersion>

</PropertyGroup>
</Project>
43 changes: 29 additions & 14 deletions samples/ChatSample/ChatSample.CSharpClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,49 @@ class Program
{
static async Task Main(string[] args)
{
var url = "http://localhost:5050";
var url = Environment.GetEnvironmentVariable("ServerEndpoint") ?? "http://localhost:5050";
Enum.TryParse<Mode>(Environment.GetEnvironmentVariable("MODE"), out var mode);
var proxy = await ConnectAsync(url + "/chat", Console.Out);
var currentUser = Guid.NewGuid().ToString("N");

Mode mode = Mode.Broadcast;
if (args.Length > 0)
{
Enum.TryParse(args[0], true, out mode);
}

Console.WriteLine($"Logged in as user {currentUser}");
var input = Console.ReadLine();
while (!string.IsNullOrEmpty(input))
if (mode == Mode.Auto)
{
switch (mode)
// auto mode
while (true)
{
case Mode.Broadcast:
await proxy.InvokeAsync("BroadcastMessage", currentUser, input);
break;
case Mode.Echo:
await proxy.InvokeAsync("echo", input);
break;
default:
break;
Console.WriteLine("Broadcasting...");
await proxy.InvokeAsync("BroadcastMessage", currentUser, $"Current time: {DateTime.Now}");
await Task.Delay(5000);
}
}
else
{
var input = Console.ReadLine();
while (!string.IsNullOrEmpty(input))
{
switch (mode)
{
case Mode.Broadcast:
await proxy.InvokeAsync("BroadcastMessage", currentUser, input);
break;
case Mode.Echo:
await proxy.InvokeAsync("echo", input);
break;
default:
break;
}

input = Console.ReadLine();
input = Console.ReadLine();
}
}
}

private static async Task<HubConnection> ConnectAsync(string url, TextWriter output, CancellationToken cancellationToken = default)
{
var connection = new HubConnectionBuilder()
Expand Down Expand Up @@ -101,6 +115,7 @@ private enum Mode
{
Broadcast,
Echo,
Auto
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"profiles": {
"ChatSample.CSharpClient": {
"commandName": "Project"
},
"auto": {
"commandName": "Project",
"environmentVariables": {
"MODE": "Auto"
},
"distributionName": ""
}
}
}
3 changes: 2 additions & 1 deletion samples/ChatSample/ChatSample.Net60/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR().AddAzureSignalR();
builder.Services.AddSignalR()
.AddNamedAzureSignalR("signalr1");

// uncomment for streaming outside the scope
// builder.Services.AddHostedService<StreamingService>();
Expand Down
41 changes: 41 additions & 0 deletions samples/ChatSample/ChatSample.Net60/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Run the samples

[.NET Aspire](https://learn.microsoft.com/dotnet/aspire/get-started/aspire-overview#orchestration) is used to orchestrate the samples.

## Run with aspire ready in visual studio

To work with .NET Aspire, you need the following installed locally:
- [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)
- .NET Aspire workload:
- Installed with the [Visual Studio installer](../fundamentals/setup-tooling.md?tabs=visual-studio#install-net-aspire) or [the .NET CLI workload](../fundamentals/setup-tooling.md?tabs=dotnet-cli#install-net-aspire).
- An OCI compliant container runtime, such as:
- [Docker Desktop](https://www.docker.com/products/docker-desktop) or [Podman](https://podman.io/).

In Visual Studio, set **samples/Samples.AppHost** project as the Startup Project. Right click **Connected Services** and select **Azure Resource Provisioning Settings** and select your Azure subscription, region and resource group to use.

![Azure Resource Provisiong Settings](../../images/add-azure-provisioning.png)

Alternatively, you could add Azure related configurations in the appsettings.json file:
```json
{
"Azure": {
"SubscriptionId": "your subscription",
"Location": "your location"
}
}
```

Run the project and use Aspire dashboard to navigate to different samples:
![Aspire Dashboard](../../images/aspire-dashboard.png)

## Run without aspire

Aspire helps you to automatically provision a new Azure SignalR resource and set the connection strings for the sample to use automatically. You could still use the traditional way to set the connection strings by yourself and run the sample directly. Samples now use named connection string `AddNamedAzureSignalR("signalr1")`. Set your connection string to `signalr1:Azure:SignalR:ConnectionString`, or `ConnectionStrings:signalr1`:

```
dotnet user-secrets set Azure:SignalR:signalr1:ConnectionString "<Your connection string>"
```

```
dotnet user-secrets set ConnectionStrings:signalr1 "<Your connection string>"
```
2 changes: 1 addition & 1 deletion samples/ChatSample/ChatSample.Net70/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
builder.Services.AddSignalR(o =>
{
o.MaximumParallelInvocationsPerClient = 2;
}).AddAzureSignalR("<connection-string>");
}).AddNamedAzureSignalR("signalr1");

var app = builder.Build();

Expand Down
46 changes: 37 additions & 9 deletions samples/ChatSample/ChatSample.Net70/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,46 @@ Requires NET7.0 Preview7 or later SDK/Runtime. Please installed from https://dot

### Usage

Update `Program.cs` file of below lines to replace the placeholder `<connection-string>` with your Azure SignalR Service connection string.
[.NET Aspire](https://learn.microsoft.com/dotnet/aspire/get-started/aspire-overview#orchestration) is used to orchestrate the samples.

```cs
builder.Services.AddSignalR(o =>
{
o.MaximumParallelInvocationsPerClient = 2;
}).AddAzureSignalR("<connection-string>");
```
#### Run with aspire ready in visual studio

To work with .NET Aspire, you need the following installed locally:
- [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)
- .NET Aspire workload:
- Installed with the [Visual Studio installer](../fundamentals/setup-tooling.md?tabs=visual-studio#install-net-aspire) or [the .NET CLI workload](../fundamentals/setup-tooling.md?tabs=dotnet-cli#install-net-aspire).
- An OCI compliant container runtime, such as:
- [Docker Desktop](https://www.docker.com/products/docker-desktop) or [Podman](https://podman.io/).

In Visual Studio, set **samples/Samples.AppHost** project as the Startup Project. Right click **Connected Services** and select **Azure Resource Provisioning Settings** and select your Azure subscription, region and resource group to use.

![Azure Resource Provisiong Settings](../../images/add-azure-provisioning.png)

Alternatively, you could add Azure related configurations in the appsettings.json file:
```json
{
"Azure": {
"SubscriptionId": "your subscription",
"Location": "your location"
}
}
```

Run the project and use Aspire dashboard to navigate to different samples:

![Aspire Dashboard](../../images/aspire-dashboard.png)

Run dotnet command to start the server.
#### Run without aspire

```bash
Aspire helps you to automatically provision a new Azure SignalR resource and set the connection strings for the sample to use automatically. You could still use the traditional way to set the connection strings by yourself and run the sample directly. Samples now use named connection string `AddNamedAzureSignalR("signalr1")`. Set your connection string to `signalr1:Azure:SignalR:ConnectionString`, or `ConnectionStrings:signalr1`:

```
dotnet user-secrets set Azure:SignalR:signalr1:ConnectionString "<Your connection string>"
dotnet run
```

```
dotnet user-secrets set ConnectionStrings:signalr1 "<Your connection string>"
dotnet run
```

Expand Down
42 changes: 42 additions & 0 deletions samples/ChatSample/ChatSample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Run the samples

[.NET Aspire](https://learn.microsoft.com/dotnet/aspire/get-started/aspire-overview#orchestration) is used to orchestrate the samples.

## Run with aspire ready in visual studio

To work with .NET Aspire, you need the following installed locally:
- [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)
- .NET Aspire workload:
- Installed with the [Visual Studio installer](../fundamentals/setup-tooling.md?tabs=visual-studio#install-net-aspire) or [the .NET CLI workload](../fundamentals/setup-tooling.md?tabs=dotnet-cli#install-net-aspire).
- An OCI compliant container runtime, such as:
- [Docker Desktop](https://www.docker.com/products/docker-desktop) or [Podman](https://podman.io/).

In Visual Studio, set **samples/Samples.AppHost** project as the Startup Project. Right click **Connected Services** and select **Azure Resource Provisioning Settings** and select your Azure subscription, region and resource group to use.

![Azure Resource Provisiong Settings](../../images/add-azure-provisioning.png)

Alternatively, you could add Azure related configurations in the appsettings.json file:
```json
{
"Azure": {
"SubscriptionId": "your subscription",
"Location": "your location"
}
}
```

Run the project and use Aspire dashboard to navigate to different samples:

![Aspire Dashboard](../../images/aspire-dashboard.png)

## Run without aspire

Aspire helps you to automatically provision a new Azure SignalR resource and set the connection strings for the sample to use automatically. You could still use the traditional way to set the connection strings by yourself and run the sample directly. Samples now use named connection string `AddNamedAzureSignalR("signalr1")`. Set your connection string to `signalr1:Azure:SignalR:ConnectionString`, or `ConnectionStrings:signalr1`:

```
dotnet user-secrets set Azure:SignalR:signalr1:ConnectionString "<Your connection string>"
```

```
dotnet user-secrets set ConnectionStrings:signalr1 "<Your connection string>"
```
22 changes: 12 additions & 10 deletions samples/ChatSample/ChatSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ public class Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSignalR()
.AddAzureSignalR(option =>
{
option.GracefulShutdown.Mode = GracefulShutdownMode.WaitForClientsClose;
option.GracefulShutdown.Timeout = TimeSpan.FromSeconds(30);
var builder = services.AddSignalR()
.AddNamedAzureSignalR("signalr1");
builder.Services.Configure<ServiceOptions>(option =>
{
option.GracefulShutdown.Mode = GracefulShutdownMode.WaitForClientsClose;
option.GracefulShutdown.Timeout = TimeSpan.FromSeconds(30);

option.GracefulShutdown.Add<Chat>(async (c) =>
{
await c.Clients.All.SendAsync("exit");
});
})
option.GracefulShutdown.Add<Chat>(async (c) =>
{
await c.Clients.All.SendAsync("exit");
});
});
builder
.AddMessagePackProtocol();
}

Expand Down
20 changes: 20 additions & 0 deletions samples/Samples.AppHost/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Projects;

var builder = DistributedApplication.CreateBuilder(args);

#pragma warning disable AZPROVISION001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var signalr = builder.AddAzureSignalR("signalr1", (_, _, k) => k.AssignProperty(i => i.Sku.Name, "'Standard_S1'"));
#pragma warning restore AZPROVISION001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

var chatServer = builder.AddProject<ChatSample>("chat").WithReference(signalr).WithExternalHttpEndpoints().WithHttpsEndpoint();

builder.AddProject<ChatSample_CSharpClient>("csharp-client-for-chat", "auto")
.WithEnvironment("ServerEndpoint", chatServer.GetEndpoint("https"));

builder.AddProject<ChatSample_Net60>("chat-net6").WithReference(signalr).WithExternalHttpEndpoints();
builder.AddProject<ChatSample_Net70>("chat-net7-client-invocation").WithReference(signalr).WithExternalHttpEndpoints();

builder.Build().Run();
Loading
Loading