提问人:techno 提问时间:11/14/2023 更新时间:11/14/2023 访问量:29
当用户离开页面时,断开用户与 SignalR 中心的连接
Disconnect User from SignalR Hub when the User Navigates away from the page
问:
我有以下 SignalRHub
public class EODStatusHub : Hub {
public override Task OnConnectedAsync()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId);
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnectedAsync(exception);
}
}
public static class UserHandler
{
public static HashSet<string> ConnectedIds = new HashSet<string>();
}
我有一个后台服务,它每 5 秒从 API 获取一次数据,具体取决于是否有客户端连接到 Hub
public class TimedEODService : BackgroundService
{
private readonly ILogger<TimedEODService> _logger;
private readonly IHubContext<EODStatusHub> _eodStatusHubContext;
private readonly IEODService _eodService;
public TimedEODService( ILogger<TimedEODService> logger, IHubContext<EODStatusHub> eodStatusHubContext, IEODService eodService)
{
_logger = logger;
_eodStatusHubContext = eodStatusHubContext;
_eodService = eodService;
}
protected override async Task ExecuteAsync(CancellationToken token)
{
await Task.Yield();
while (token.IsCancellationRequested == false)
{
await Task.Delay(5000, token);
if (UserHandler.ConnectedIds.Count > 0)
{
StatusReport eodStatus = await _eodService.GetEODStatus();
_eodStatusHubContext.Clients.All.SendAsync("eodReceived",eodStatus);
}
}
}
}
连接器的 UI TypeScript 代码
import * as signalR from "@microsoft/signalr";
const URL = "https://localhost:7082/pochub"; //or whatever your backend port is
class Connector {
private connection: signalR.HubConnection;
public events: (onMessageReceived: ( message: any) => void) => void;
static instance: Connector;
constructor() {
this.connection = new signalR.HubConnectionBuilder()
.withUrl(URL)
.withAutomaticReconnect()
.build();
this.connection.start().catch(err => document.write(err));
this.events = (onMessageReceived) => {
this.connection.on("eodReceived", ( message) => {
onMessageReceived(message);
});
};
}
public newMessage = (messages: string) => {
this.connection.send("newMessage", "foo", messages).then(x => console.log("sent"))
}
public static getInstance(): Connector {
if (!Connector.instance)
Connector.instance = new Connector();
return Connector.instance;
}
}
export default Connector.getInstance;
当用户在页面上时,我需要建立连接并每 5 秒进行一次 API 调用。这工作正常,但用户在离开页面时不会断开连接。无论用户是否在页面中,都会每 5 秒调用一次 API。
这是 UI 页面的样子
const EODStatus = () => {
const { newMessage, events } = Connector();
const [message, setMessage] = useState("initial value");
const initialRender = useRef<boolean>(false);
useEffect(() => {
events((message) => setMessage(message));
}, []);
return (
<>
<span>message from signalR: <span style={{ color: "green" }}>{JSON.stringify(message)}
</span>
</>
}
答: 暂无答案
评论
visibilitychange
useEffect