using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace WIDESEAWCS_Tasks.SocketServer { public partial class TcpSocketServer { public IReadOnlyList GetClientIds() { lock (_syncRoot) { return _clients.Keys.ToList(); } } public string? GetClientIdByDevice(string deviceId) { lock (_syncRoot) { return _deviceBindings.TryGetValue(deviceId, out var cid) ? cid : null; } } public Task SendToDeviceAsync(string deviceId, string message) { var clientId = GetClientIdByDevice(deviceId); if (clientId == null) return Task.FromResult(false); return SendToClientAsync(clientId, message); } public async Task SendToClientAsync(string clientId, string message) { TcpClient? client; SemaphoreSlim? sem = null; Encoding? enc = null; lock (_syncRoot) { _clients.TryGetValue(clientId, out client); _clientLocks.TryGetValue(clientId, out sem); _clientEncodings.TryGetValue(clientId, out enc); } if (client == null || !client.Connected) { return false; } enc ??= _textEncoding; if (sem != null) await sem.WaitAsync(); try { var ns = client.GetStream(); var data = enc.GetBytes((message ?? string.Empty) + "\n"); await ns.WriteAsync(data, 0, data.Length); } finally { if (sem != null) sem.Release(); } return true; } public async Task BroadcastAsync(string message) { List clients; lock (_syncRoot) { clients = _clients.Values.ToList(); } await Task.WhenAll(clients.Select(c => Task.Run(async () => { try { await SendAsync(c, message); } catch { } }))); } public static async Task SendAsync(TcpClient client, string message) { if (client == null || !client.Connected) { return; } NetworkStream stream = client.GetStream(); var data = Encoding.UTF8.GetBytes((message ?? string.Empty) + "\n"); await stream.WriteAsync(data, 0, data.Length); } } }