在 Docker Swarm 中的多个副本上运行 SignalR 的 AspnetCore Web 应用程序无法连接到 Redis 服务器

问题描述 投票:0回答:0

我的应用程序使用 .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 进行了测试,但结果仍然相同。

signalr
© www.soinside.com 2019 - 2024. All rights reserved.