SignalR 在尝试调用方法后断开连接

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

连接工作正常,但是当我尝试调用一个方法时,它最终会调用断开连接方法,并出现错误,提示找不到“ParseMessage”。我有 2 个独立的 .NET 7 应用程序。 1 个用于服务器,1 个用于客户端。这只是一个测试来调用方法。

当我按下“开始计时器”按钮时,它就会断开我的连接。

服务器中心:

using Microsoft.AspNetCore.SignalR;

namespace SignalRTest;

public class MyHub : Hub
{
    // This dictionary could map user connections to active timers if needed for multiple users
    private static readonly Dictionary<string, CancellationTokenSource> UserTimers = new Dictionary<string, CancellationTokenSource>();

    // This method is called when a client successfully connects to the hub.
    public override async Task OnConnectedAsync()
    {
        // You can retrieve the connection ID or perform any startup logic here
        string connectionId = Context.ConnectionId;
        Console.WriteLine($"Client connected: {connectionId}");

        // You can also send a message back to the client on connection
        await Clients.Client(connectionId).SendAsync("ReceiveMessage", $"Welcome! Your connection ID is {connectionId}");

        // Call the base class method to ensure proper connection handling
        await base.OnConnectedAsync();
    }

    // This method is called when a client disconnects from the hub.
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        string connectionId = Context.ConnectionId;
        Console.WriteLine($"Client disconnected: {connectionId}");

        if (exception != null)
        {
            Console.WriteLine($"Disconnected due to an error: {exception.Message}");
        }

        if (UserTimers.ContainsKey(connectionId))
        {
            UserTimers[connectionId].Cancel();
            UserTimers.Remove(connectionId);
        }

        // Call the base class method to ensure proper disconnection handling
        await base.OnDisconnectedAsync(exception);
    }

    // Method called by the client to start the timer
    public async Task StartTimer()
    {
        var connectionId = Context.ConnectionId;

        // Ensure only one timer per connection
        if (UserTimers.ContainsKey(connectionId))
        {
            await Clients.Caller.SendAsync("ReceiveMessage", "Timer already running.");
            return;
        }

        // Create a cancellation token for this user's timer
        var cts = new CancellationTokenSource();
        UserTimers[connectionId] = cts;

        await Clients.Caller.SendAsync("ReceiveMessage", "Timer started.");

        // Start a loop to send updates every 5 seconds
        int counter = 0;
        while (!cts.Token.IsCancellationRequested)
        {
            counter += 5;
            await Clients.Caller.SendAsync("ReceiveTimerUpdate", counter);
            try
            {
                await Task.Delay(5000, cts.Token); // Wait 5 seconds
            }
            catch (TaskCanceledException)
            {
                break; // If the task is canceled, exit the loop
            }
        }
    }

    // Method called by the client to stop the timer
    public async Task StopTimer()
    {
        var connectionId = Context.ConnectionId;
        if (UserTimers.ContainsKey(connectionId))
        {
            UserTimers[connectionId].Cancel();
            UserTimers.Remove(connectionId);
            await Clients.Caller.SendAsync("ReceiveMessage", "Timer stopped.");
        }
        else
        {
            await Clients.Caller.SendAsync("ReceiveMessage", "No active timer found.");
        }
    }
}

客户索引.html

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SignalR Timer Example</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.7/signalr.js"></script>
</head>
<body>
    <button id="startButton">Start Timer</button>
    <button id="stopButton">Stop Timer</button>
    <div id="timerOutput"></div>

    <script>
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("https://localhost:7156/my-hub", {
                withCredentials: true // Allows credentials like cookies or authentication tokens to be sent
            })
            .withAutomaticReconnect()
            .build();

        connection.start().then(() => {
            console.log("Connected to SignalR");
        }).catch(err => console.error(err));

        document.getElementById("startButton").addEventListener("click", () => {
            connection.invoke("StartTimer").catch(err => console.error(err));
        });

        document.getElementById("stopButton").addEventListener("click", () => {
            connection.invoke("StopTimer").catch(err => console.error(err));
        });

        connection.on("ReceiveTimerUpdate", (counter) => {
            document.getElementById("timerOutput").innerText = `Time: ${counter} seconds`;
        });

        connection.on("ReceiveMessage", (message) => {
            console.log(message);
        });
    </script>
</body>
</html>
.net signalr asp.net-core-signalr
1个回答
0
投票

我用的是python所以我不知道。您确定您拥有最新版本的 .net 吗?

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