Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XWorld.Server.Gateway
|
||||
{
|
||||
// pid -> Session。只在 actor 线程被改,故无锁。
|
||||
public sealed class SessionManager
|
||||
{
|
||||
private readonly Dictionary<int, Session> _byPid = new Dictionary<int, Session>();
|
||||
|
||||
public Session OnConnect(int pid, IClientConnection conn)
|
||||
{
|
||||
if (_byPid.TryGetValue(pid, out var s))
|
||||
{
|
||||
s.Connection = conn; // 重连:重绑新连接,保留 RoomId
|
||||
s.Connected = true;
|
||||
return s;
|
||||
}
|
||||
s = new Session { PlayerId = pid, Connection = conn, Connected = true };
|
||||
_byPid[pid] = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
public void OnDisconnect(int pid, IClientConnection conn, long currentTick)
|
||||
{
|
||||
// 仅当断的是"当前连接"才标离线,避免旧连接的迟到断线清掉已重连的新连接
|
||||
if (_byPid.TryGetValue(pid, out var s) && ReferenceEquals(s.Connection, conn))
|
||||
{
|
||||
s.Connected = false;
|
||||
s.DisconnectedAtTick = currentTick;
|
||||
}
|
||||
}
|
||||
|
||||
public IClientConnection GetConnection(int pid)
|
||||
=> _byPid.TryGetValue(pid, out var s) && s.Connected ? s.Connection : null;
|
||||
|
||||
public bool IsConnected(int pid) => _byPid.TryGetValue(pid, out var s) && s.Connected;
|
||||
|
||||
public Session Get(int pid) => _byPid.TryGetValue(pid, out var s) ? s : null;
|
||||
|
||||
/// <summary>移除断线且"严格越过"重连窗口的会话(currentTick - DisconnectedAtTick > windowTicks)。返回被移除的会话;无则空数组。</summary>
|
||||
public IReadOnlyList<Session> SweepExpired(long currentTick, long windowTicks)
|
||||
{
|
||||
List<Session> removed = null;
|
||||
foreach (var kv in _byPid)
|
||||
{
|
||||
var s = kv.Value;
|
||||
if (!s.Connected && currentTick - s.DisconnectedAtTick > windowTicks)
|
||||
(removed ??= new List<Session>()).Add(s);
|
||||
}
|
||||
if (removed != null)
|
||||
foreach (var s in removed) _byPid.Remove(s.PlayerId);
|
||||
return removed ?? (IReadOnlyList<Session>)Array.Empty<Session>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user