|
@ -11,19 +11,71 @@ using Microsoft.Extensions.Caching.Memory; |
|
|
|
|
|
|
|
|
namespace CellularManagement.Infrastructure.WebSocket; |
|
|
namespace CellularManagement.Infrastructure.WebSocket; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// WebSocket服务实现类
|
|
|
|
|
|
/// 负责管理WebSocket连接的生命周期、消息发送和接收
|
|
|
|
|
|
/// 使用分布式缓存存储连接信息,本地缓存存储WebSocket实例
|
|
|
|
|
|
/// </summary>
|
|
|
public class WebSocketService : IWebSocketService |
|
|
public class WebSocketService : IWebSocketService |
|
|
{ |
|
|
{ |
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 日志记录器,用于记录WebSocket服务的操作日志
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly ILogger<WebSocketService> _logger; |
|
|
private readonly ILogger<WebSocketService> _logger; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// WebSocket指标监控,用于记录连接、消息等指标
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly WebSocketMetrics _metrics; |
|
|
private readonly WebSocketMetrics _metrics; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// WebSocket消息池,用于复用消息上下文对象
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly WebSocketMessagePool _messagePool; |
|
|
private readonly WebSocketMessagePool _messagePool; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 分布式缓存,用于存储连接信息
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly IDistributedCache _distributedCache; |
|
|
private readonly IDistributedCache _distributedCache; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 本地缓存服务,用于存储WebSocket实例
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly ICacheService _cacheService; |
|
|
private readonly ICacheService _cacheService; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 当前节点ID,用于标识服务实例
|
|
|
|
|
|
/// </summary>
|
|
|
private readonly string _nodeId; |
|
|
private readonly string _nodeId; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// WebSocket连接信息在缓存中的键前缀
|
|
|
|
|
|
/// </summary>
|
|
|
private const string CONNECTION_PREFIX = "ws_connection_"; |
|
|
private const string CONNECTION_PREFIX = "ws_connection_"; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// WebSocket实例在缓存中的键前缀
|
|
|
|
|
|
/// </summary>
|
|
|
private const string WEBSOCKET_PREFIX = "ws_socket_"; |
|
|
private const string WEBSOCKET_PREFIX = "ws_socket_"; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用户关联信息在缓存中的键前缀
|
|
|
|
|
|
/// </summary>
|
|
|
private const string USER_PREFIX = "ws_user_"; |
|
|
private const string USER_PREFIX = "ws_user_"; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 节点信息在缓存中的键前缀
|
|
|
|
|
|
/// </summary>
|
|
|
private const string NODE_PREFIX = "ws_node_"; |
|
|
private const string NODE_PREFIX = "ws_node_"; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构造函数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="logger">日志记录器,用于记录服务操作日志</param>
|
|
|
|
|
|
/// <param name="metrics">WebSocket指标监控,用于记录连接和消息指标</param>
|
|
|
|
|
|
/// <param name="messagePool">消息池,用于复用消息上下文对象</param>
|
|
|
|
|
|
/// <param name="distributedCache">分布式缓存,用于存储连接信息</param>
|
|
|
|
|
|
/// <param name="cacheService">本地缓存服务,用于存储WebSocket实例</param>
|
|
|
public WebSocketService( |
|
|
public WebSocketService( |
|
|
ILogger<WebSocketService> logger, |
|
|
ILogger<WebSocketService> logger, |
|
|
WebSocketMetrics metrics, |
|
|
WebSocketMetrics metrics, |
|
@ -36,45 +88,62 @@ public class WebSocketService : IWebSocketService |
|
|
_messagePool = messagePool; |
|
|
_messagePool = messagePool; |
|
|
_distributedCache = distributedCache; |
|
|
_distributedCache = distributedCache; |
|
|
_cacheService = cacheService; |
|
|
_cacheService = cacheService; |
|
|
_nodeId = Guid.NewGuid().ToString(); |
|
|
_nodeId = Guid.NewGuid().ToString(); // 生成唯一的节点ID
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 接受新的WebSocket连接
|
|
|
|
|
|
/// 创建连接信息并存储到缓存中
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="webSocket">WebSocket实例</param>
|
|
|
|
|
|
/// <returns>新创建的连接ID</returns>
|
|
|
public async Task<string> AcceptConnectionAsync(System.Net.WebSockets.WebSocket webSocket) |
|
|
public async Task<string> AcceptConnectionAsync(System.Net.WebSockets.WebSocket webSocket) |
|
|
{ |
|
|
{ |
|
|
var connectionId = Guid.NewGuid().ToString(); |
|
|
var connectionId = Guid.NewGuid().ToString(); |
|
|
var connection = WebSocketConnection.Create(connectionId); |
|
|
var connection = WebSocketConnection.Create(connectionId); |
|
|
|
|
|
|
|
|
|
|
|
// 生成缓存键
|
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var webSocketKey = $"{WEBSOCKET_PREFIX}{connectionId}"; |
|
|
var webSocketKey = $"{WEBSOCKET_PREFIX}{connectionId}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
|
|
|
|
|
|
|
|
|
|
// 将连接信息存储到分布式缓存
|
|
|
await _distributedCache.SetStringAsync( |
|
|
await _distributedCache.SetStringAsync( |
|
|
connectionKey, |
|
|
connectionKey, |
|
|
JsonSerializer.Serialize(connection), |
|
|
JsonSerializer.Serialize(connection), |
|
|
new DistributedCacheEntryOptions |
|
|
new DistributedCacheEntryOptions |
|
|
{ |
|
|
{ |
|
|
SlidingExpiration = TimeSpan.FromMinutes(30) |
|
|
SlidingExpiration = TimeSpan.FromMinutes(30) // 设置30分钟滑动过期
|
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 将WebSocket实例存储到本地缓存
|
|
|
_cacheService.Set(webSocketKey, webSocket, new MemoryCacheEntryOptions |
|
|
_cacheService.Set(webSocketKey, webSocket, new MemoryCacheEntryOptions |
|
|
{ |
|
|
{ |
|
|
SlidingExpiration = TimeSpan.FromMinutes(30) |
|
|
SlidingExpiration = TimeSpan.FromMinutes(30) |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 将连接添加到当前节点
|
|
|
await AddConnectionToNodeAsync(connectionId); |
|
|
await AddConnectionToNodeAsync(connectionId); |
|
|
_metrics.ConnectionEstablished(); |
|
|
_metrics.ConnectionEstablished(); // 记录连接建立指标
|
|
|
_logger.LogInformation("WebSocket connection accepted: {ConnectionId} on node {NodeId}", |
|
|
_logger.LogInformation("WebSocket连接已建立: {ConnectionId} 在节点 {NodeId}", |
|
|
connectionId, _nodeId); |
|
|
connectionId, _nodeId); |
|
|
|
|
|
|
|
|
return connectionId; |
|
|
return connectionId; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关闭WebSocket连接
|
|
|
|
|
|
/// 清理连接相关的所有缓存信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">要关闭的连接ID</param>
|
|
|
|
|
|
/// <returns>是否成功关闭连接</returns>
|
|
|
public async Task<bool> CloseConnectionAsync(string connectionId) |
|
|
public async Task<bool> CloseConnectionAsync(string connectionId) |
|
|
{ |
|
|
{ |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var webSocketKey = $"{WEBSOCKET_PREFIX}{connectionId}"; |
|
|
var webSocketKey = $"{WEBSOCKET_PREFIX}{connectionId}"; |
|
|
var userKey = $"{USER_PREFIX}{connectionId}"; |
|
|
var userKey = $"{USER_PREFIX}{connectionId}"; |
|
|
|
|
|
|
|
|
|
|
|
// 获取连接信息
|
|
|
var connectionJson = await _distributedCache.GetStringAsync(connectionKey); |
|
|
var connectionJson = await _distributedCache.GetStringAsync(connectionKey); |
|
|
if (_cacheService.TryGetValue(webSocketKey, out System.Net.WebSockets.WebSocket? webSocket)) |
|
|
if (_cacheService.TryGetValue(webSocketKey, out System.Net.WebSockets.WebSocket? webSocket)) |
|
|
{ |
|
|
{ |
|
@ -87,17 +156,18 @@ public class WebSocketService : IWebSocketService |
|
|
{ |
|
|
{ |
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
|
|
|
// 如果WebSocket处于打开状态,则正常关闭
|
|
|
if (webSocket.State == WebSocketState.Open || webSocket.State == WebSocketState.CloseReceived) |
|
|
if (webSocket.State == WebSocketState.Open || webSocket.State == WebSocketState.CloseReceived) |
|
|
{ |
|
|
{ |
|
|
await webSocket.CloseAsync( |
|
|
await webSocket.CloseAsync( |
|
|
WebSocketCloseStatus.NormalClosure, |
|
|
WebSocketCloseStatus.NormalClosure, |
|
|
"Connection closed by server", |
|
|
"服务器关闭连接", |
|
|
CancellationToken.None); |
|
|
CancellationToken.None); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
catch (Exception ex) |
|
|
catch (Exception ex) |
|
|
{ |
|
|
{ |
|
|
_logger.LogError(ex, "Error closing WebSocket connection: {ConnectionId}", connectionId); |
|
|
_logger.LogError(ex, "关闭WebSocket连接时出错: {ConnectionId}", connectionId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
connection.Close(); |
|
|
connection.Close(); |
|
@ -107,20 +177,27 @@ public class WebSocketService : IWebSocketService |
|
|
} |
|
|
} |
|
|
catch (Exception ex) |
|
|
catch (Exception ex) |
|
|
{ |
|
|
{ |
|
|
_logger.LogWarning(ex, "Failed to deserialize WebSocketConnection for connection: {ConnectionId}, continuing with cleanup", connectionId); |
|
|
_logger.LogWarning(ex, "反序列化WebSocketConnection失败: {ConnectionId}, 继续清理", connectionId); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 清理连接相关的所有缓存
|
|
|
await RemoveConnectionFromNodeAsync(connectionId); |
|
|
await RemoveConnectionFromNodeAsync(connectionId); |
|
|
await _distributedCache.RemoveAsync(connectionKey); |
|
|
await _distributedCache.RemoveAsync(connectionKey); |
|
|
_cacheService.Remove(webSocketKey); |
|
|
_cacheService.Remove(webSocketKey); |
|
|
await _distributedCache.RemoveAsync(userKey); |
|
|
await _distributedCache.RemoveAsync(userKey); |
|
|
|
|
|
|
|
|
_metrics.ConnectionClosed(); |
|
|
_metrics.ConnectionClosed(); // 记录连接关闭指标
|
|
|
_logger.LogInformation("WebSocket connection closed: {ConnectionId}", connectionId); |
|
|
_logger.LogInformation("WebSocket连接已关闭: {ConnectionId}", connectionId); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向指定连接发送消息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">目标连接ID</param>
|
|
|
|
|
|
/// <param name="message">要发送的消息内容</param>
|
|
|
|
|
|
/// <returns>是否成功发送消息</returns>
|
|
|
public async Task<bool> SendMessageAsync(string connectionId, byte[] message) |
|
|
public async Task<bool> SendMessageAsync(string connectionId, byte[] message) |
|
|
{ |
|
|
{ |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
@ -144,30 +221,37 @@ public class WebSocketService : IWebSocketService |
|
|
true, |
|
|
true, |
|
|
CancellationToken.None); |
|
|
CancellationToken.None); |
|
|
|
|
|
|
|
|
_metrics.MessageProcessed(TimeSpan.Zero); |
|
|
_metrics.MessageProcessed(TimeSpan.Zero); // 记录消息处理指标
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
catch (Exception ex) |
|
|
catch (Exception ex) |
|
|
{ |
|
|
{ |
|
|
_logger.LogError(ex, "Error sending message to connection: {ConnectionId}", connectionId); |
|
|
_logger.LogError(ex, "发送消息到连接时出错: {ConnectionId}", connectionId); |
|
|
_metrics.ErrorOccurred("SendMessage"); |
|
|
_metrics.ErrorOccurred("SendMessage"); // 记录错误指标
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
catch (Exception ex) |
|
|
catch (Exception ex) |
|
|
{ |
|
|
{ |
|
|
_logger.LogWarning(ex, "Failed to deserialize WebSocketConnection for connection: {ConnectionId}, skipping message send", connectionId); |
|
|
_logger.LogWarning(ex, "反序列化WebSocketConnection失败: {ConnectionId}, 跳过消息发送", connectionId); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 广播消息到所有连接
|
|
|
|
|
|
/// 遍历所有节点上的所有连接并发送消息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="message">要广播的消息内容</param>
|
|
|
|
|
|
/// <returns>是否所有消息都发送成功</returns>
|
|
|
public async Task<bool> BroadcastMessageAsync(byte[] message) |
|
|
public async Task<bool> BroadcastMessageAsync(byte[] message) |
|
|
{ |
|
|
{ |
|
|
var nodes = await GetAllNodesAsync(); |
|
|
var nodes = await GetAllNodesAsync(); |
|
|
var success = true; |
|
|
var success = true; |
|
|
|
|
|
|
|
|
|
|
|
// 遍历所有节点上的所有连接
|
|
|
foreach (var node in nodes) |
|
|
foreach (var node in nodes) |
|
|
{ |
|
|
{ |
|
|
var nodeKey = $"{NODE_PREFIX}{node}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{node}"; |
|
@ -188,11 +272,18 @@ public class WebSocketService : IWebSocketService |
|
|
return success; |
|
|
return success; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向指定用户的所有连接发送消息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="userId">目标用户ID</param>
|
|
|
|
|
|
/// <param name="message">要发送的消息内容</param>
|
|
|
|
|
|
/// <returns>是否所有消息都发送成功</returns>
|
|
|
public async Task<bool> SendMessageToUserAsync(string userId, byte[] message) |
|
|
public async Task<bool> SendMessageToUserAsync(string userId, byte[] message) |
|
|
{ |
|
|
{ |
|
|
var userConnections = await GetUserConnectionsAsync(userId); |
|
|
var userConnections = await GetUserConnectionsAsync(userId); |
|
|
var success = true; |
|
|
var success = true; |
|
|
|
|
|
|
|
|
|
|
|
// 向用户的所有连接发送消息
|
|
|
foreach (var connection in userConnections) |
|
|
foreach (var connection in userConnections) |
|
|
{ |
|
|
{ |
|
|
if (!await SendMessageAsync(connection.ConnectionId, message)) |
|
|
if (!await SendMessageAsync(connection.ConnectionId, message)) |
|
@ -204,6 +295,12 @@ public class WebSocketService : IWebSocketService |
|
|
return success; |
|
|
return success; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将连接与用户关联
|
|
|
|
|
|
/// 更新连接信息和用户关联缓存
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">连接ID</param>
|
|
|
|
|
|
/// <param name="userId">用户ID</param>
|
|
|
public async Task AssociateUserAsync(string connectionId, string userId) |
|
|
public async Task AssociateUserAsync(string connectionId, string userId) |
|
|
{ |
|
|
{ |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
@ -222,6 +319,11 @@ public class WebSocketService : IWebSocketService |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定连接的信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">连接ID</param>
|
|
|
|
|
|
/// <returns>连接信息,如果不存在则返回null</returns>
|
|
|
public async Task<WebSocketConnection?> GetConnectionAsync(string connectionId) |
|
|
public async Task<WebSocketConnection?> GetConnectionAsync(string connectionId) |
|
|
{ |
|
|
{ |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
|
var connectionKey = $"{CONNECTION_PREFIX}{connectionId}"; |
|
@ -231,11 +333,17 @@ public class WebSocketService : IWebSocketService |
|
|
: null; |
|
|
: null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定用户的所有连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="userId">用户ID</param>
|
|
|
|
|
|
/// <returns>用户的所有连接信息</returns>
|
|
|
public async Task<IEnumerable<WebSocketConnection>> GetUserConnectionsAsync(string userId) |
|
|
public async Task<IEnumerable<WebSocketConnection>> GetUserConnectionsAsync(string userId) |
|
|
{ |
|
|
{ |
|
|
var connections = new List<WebSocketConnection>(); |
|
|
var connections = new List<WebSocketConnection>(); |
|
|
var nodes = await GetAllNodesAsync(); |
|
|
var nodes = await GetAllNodesAsync(); |
|
|
|
|
|
|
|
|
|
|
|
// 遍历所有节点,查找用户的连接
|
|
|
foreach (var node in nodes) |
|
|
foreach (var node in nodes) |
|
|
{ |
|
|
{ |
|
|
var nodeKey = $"{NODE_PREFIX}{node}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{node}"; |
|
@ -257,6 +365,10 @@ public class WebSocketService : IWebSocketService |
|
|
return connections; |
|
|
return connections; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将连接添加到当前节点
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">要添加的连接ID</param>
|
|
|
private async Task AddConnectionToNodeAsync(string connectionId) |
|
|
private async Task AddConnectionToNodeAsync(string connectionId) |
|
|
{ |
|
|
{ |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
@ -267,6 +379,10 @@ public class WebSocketService : IWebSocketService |
|
|
JsonSerializer.Serialize(connections)); |
|
|
JsonSerializer.Serialize(connections)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 从当前节点移除连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="connectionId">要移除的连接ID</param>
|
|
|
private async Task RemoveConnectionFromNodeAsync(string connectionId) |
|
|
private async Task RemoveConnectionFromNodeAsync(string connectionId) |
|
|
{ |
|
|
{ |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
@ -277,6 +393,10 @@ public class WebSocketService : IWebSocketService |
|
|
JsonSerializer.Serialize(connections)); |
|
|
JsonSerializer.Serialize(connections)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取当前节点的所有连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>当前节点的所有连接ID列表</returns>
|
|
|
private async Task<List<string>> GetNodeConnectionsAsync() |
|
|
private async Task<List<string>> GetNodeConnectionsAsync() |
|
|
{ |
|
|
{ |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
|
var nodeKey = $"{NODE_PREFIX}{_nodeId}"; |
|
@ -286,6 +406,11 @@ public class WebSocketService : IWebSocketService |
|
|
: new List<string>(); |
|
|
: new List<string>(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取所有节点ID
|
|
|
|
|
|
/// 目前仅返回当前节点ID,后续需要实现服务发现机制
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>所有节点ID列表</returns>
|
|
|
private async Task<List<string>> GetAllNodesAsync() |
|
|
private async Task<List<string>> GetAllNodesAsync() |
|
|
{ |
|
|
{ |
|
|
// 这里需要实现服务发现机制
|
|
|
// 这里需要实现服务发现机制
|
|
|