How to setup session affinity in Google Cloud Run with an internal load balancer and configure SignalR to use the session affinity cookie.
---
title: Configure SignalR client to use session affinity cookie
subtitle: How to setup session affinity in Google Cloud Run with an internal load balancer and configure SignalR to use the session affinity cookie.
author: Jon LaBelle
date: September 29, 2024
source: https://jonlabelle.com/snippets/view/markdown/configure-signalr-client-to-use-session-affinity-cookie
notoc: false
---
To set up session affinity in Google Cloud Run with an internal load balancer
and configure SignalR to use the session affinity cookie, follow these steps:
### Step 1: Set Up Session Affinity in Google Cloud Load Balancer
1. **Create a Backend Service with Session Affinity:**
- Go to the Google Cloud Console.
- Navigate to the **Load balancing** section.
- Create or edit a backend service.
- In the backend service settings, enable **Session Affinity** and choose **Client IP** or **Generated Cookie** as the affinity type.
2. **Configure the Backend Service:**
- Ensure that the backend service is associated with your Cloud Run service.
- Save the configuration.
### Step 2: Configure SignalR in .NET Core 8 API
1. **Install SignalR NuGet Package:**
```bash
dotnet add package Microsoft.AspNetCore.SignalR
```
2. **Configure SignalR in `Startup.cs`:**
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
// Other service configurations
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<YourHub>("/yourHub");
// Other endpoint mappings
});
}
```
3. **Create a SignalR hub:**
**Override Hub Methods for Error Handling:** Override methods like `OnConnectedAsync`, `OnDisconnectedAsync`, and `OnReconnectedAsync` to handle connection events and errors. Use logging to capture and log errors for further analysis.
```csharp
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
public class YourHub : Hub
{
private readonly ILogger<YourHub> _logger;
public YourHub(ILogger<YourHub> logger)
{
_logger = logger;
}
public override async Task OnConnectedAsync()
{
_logger.LogInformation("Client connected: {ConnectionId}", Context.ConnectionId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
if (exception != null)
{
_logger.LogError(exception, "Client disconnected with error: {ConnectionId}", Context.ConnectionId);
}
else
{
_logger.LogInformation("Client disconnected: {ConnectionId}", Context.ConnectionId);
}
await base.OnDisconnectedAsync(exception);
}
public override async Task OnReconnectedAsync()
{
_logger.LogInformation("Client reconnected: {ConnectionId}", Context.ConnectionId);
await base.OnReconnectedAsync();
}
// Example method to handle client messages
public async Task SendMessage(string message)
{
_logger.LogInformation("Received message: {Message}", message);
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
```
### Step 3: Configure SignalR Client in Vue.js 3
1. **Install SignalR Client Library:**
```bash
npm install @microsoft/signalr
```
2. **Configure SignalR Client to Use Session Affinity Cookie:**
```javascript
import * as signalR from '@microsoft/signalr';
// Create the connection
const connection = new signalR.HubConnectionBuilder()
.withUrl('https://your-api-url/yourHub', {
withCredentials: true // Ensure cookies are sent with requests
})
.build();
// Start the connection
connection
.start()
.then(() => console.log('SignalR connected'))
.catch((err) => console.error('SignalR connection error: ', err));
// Handle connection close
connection.onclose((error) => {
if (error) {
console.error('SignalR connection closed with error: ', error);
} else {
console.log('SignalR connection closed.');
}
// Optionally, attempt to reconnect
setTimeout(
() =>
connection
.start()
.catch((err) => console.error('Reconnection failed: ', err)),
5000
);
});
// Handle reconnecting
connection.onreconnecting((error) => {
console.warn('SignalR reconnecting due to error: ', error);
// Optionally, display a message to the user
});
// Handle reconnected
connection.onreconnected((connectionId) => {
console.log('SignalR reconnected. Connection ID: ', connectionId);
// Optionally, notify the user that the connection has been re-established
});
```
### Summary
1. **Google Cloud Load Balancer:**
- Enable session affinity in the backend service settings.
2. **.NET Core 8 API:**
- Install and configure SignalR in your API.
3. **Vue.js 3 Client:**
- Install SignalR client library and configure it to use session affinity cookies.
This setup ensures that SignalR connections are maintained and not dropped due to load balancing.