我的应用程序使用 .NET Core 6 构建,部署在 Docker Swarm 上,多个副本分布在不同节点上。该应用程序利用 SignalR 消息传递进行实时通信,并采用 Redis 来管理会话数据。
当应用程序在单个副本上运行时,与 Redis 的连接可以正常工作。然而,当应用程序扩展到多个副本时,与 Redis 的连接变得零星且不可预测。我无法确定此问题的根源,它导致应用程序行为不一致。
为了更好地理解这个问题,我创建了一个简单的应用程序来模拟相同的场景。该应用程序的代码如下:
Program.cs 文件
using WebSocketApp.Hubs;
namespace WebSocketApp
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
})
.AddStackExchangeRedis("10.128.116.21:4009,password=1234", options =>
{
options.Configuration.ChannelPrefix = "WebSoketTest";
options.Configuration.AbortOnConnectFail = false;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseWebSockets();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chatHub"); // Map SignalR hub
endpoints.MapFallbackToFile("index.html");
});
app.MapGet("/", () => "Hello World!");
app.Run();
}
}
}
文件 ChatHub.cs
namespace WebSocketApp.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string message)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
}
文件index.html
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Chat</title>
</head>
<body>
<div>
<input type="text" id="messageInput" />
<button onclick="sendMessage()">Send</button>
</div>
<div id="chatBox"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/5.0.0/signalr.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();
// Log incoming messages from the server
connection.on("ReceiveMessage", (message) => {
console.log("Received message from server:", message);
const chatBox = document.getElementById("chatBox");
const messageDiv = document.createElement("div");
messageDiv.textContent = message;
chatBox.appendChild(messageDiv);
});
async function sendMessage() {
const messageInput = document.getElementById("messageInput");
const message = messageInput.value;
if (message.trim() !== "") {
// Log outgoing messages to the server
console.log("Sending message to server:", message);
await connection.invoke("SendMessage", message);
messageInput.value = "";
}
}
connection.start()
.then(() => console.log("WebSocket connection established"))
.catch(console.error);
</script>
</body>
</html>
在一个副本连接上正常,在多个容器上不起作用。
我已经检查了所有网络是否存在可能的泄漏或问题,但没有发现任何问题。我还使用不同版本的 .NET Core 进行了测试,但结果仍然相同。