protected override async ValueTask DisposeAsync(bool disposing) { if (_isDisposed) { return; } await ConnectionsLock.TryLockAsync( async() => { foreach (var connection in _connections) { ClearListeners(connection); await connection.DisposeAsync(); } _connections.Clear(); }, 5000, true); _isDisposed = true; await base.DisposeAsync(disposing); }
public override async ValueTask <bool> AddConnectionAsync(IConnection connection, CancellationToken cancellationToken = default) { if (_isDisposed) { return(false); } var address = connection.RemoteAddress; if (_banned.TryGetValue(address, out DateTime date) && date > DateTime.UtcNow) { await connection.SendMessageAsync( new Message( $"{SystemMessages.Refuse}\n{_localizer[nameof(R.ConnectionDenied)]}{(date == DateTime.MaxValue ? "" : ($" {_localizer[nameof(R.Until)]} " + date.ToString(_localizer.Culture)))}\r\n", NetworkConstants.GameName) ); DropConnection(connection); return(false); } await base.AddConnectionAsync(connection, cancellationToken); await ConnectionsLock.WithLockAsync( () => { _connections.Add(connection); }, cancellationToken); return(true); }
public static GroupDetails GetOrCreateGroup(string group) { try { ConnectionsLock.EnterUpgradeableReadLock(); GroupDetails groupdetails = null; if (!Connections.TryGetValue(group, out groupdetails)) { try { ConnectionsLock.EnterWriteLock(); if (!Connections.TryGetValue(group, out groupdetails)) { groupdetails = new GroupDetails(groupname: group); Connections.Add(group, groupdetails); } } finally { ConnectionsLock.ExitWriteLock(); } } return(groupdetails); } finally { ConnectionsLock.ExitUpgradeableReadLock(); } }
public async ValueTask KickAsync(string name, bool ban = false) { IConnection connectionToClose = null; await ConnectionsLock.WithLockAsync(() => { foreach (var connection in _connections) { if (connection.UserName == name) { var address = connection.RemoteAddress; if (address.Length > 0) { _banned[address] = ban ? DateTime.MaxValue : DateTime.UtcNow.AddMinutes(5.0); } connectionToClose = connection; break; } } }); if (connectionToClose != null) { Connection_ConnectionClosed(connectionToClose, false); } }
/// <summary> /// Клиент отправляет сообщение /// </summary> /// <param name="obj">Отправляемое сообщение</param> private async void Client_SendingMessage(IClient sender, Message m) { if (string.IsNullOrWhiteSpace(m.Receiver)) { return; } try { if (m.Receiver[0] == AnonymousSenderPrefix) { // Анонимное сообщение (серверу) var connection = await ConnectionsLock.WithLockAsync(() => Connections.FirstOrDefault(conn => conn.Id == m.Receiver.Substring(1))); if (connection != null) { await connection.SendMessageAsync( new Message(m.Text, m.Sender, NetworkConstants.Everybody, m.IsSystem, m.IsPrivate)); } } else { await ProcessOutgoingMessageAsync(m); } } catch (ObjectDisposedException) { } catch (TaskCanceledException exc) { OnError(exc, true); } catch (TimeoutException exc) { OnError(exc, true); } catch (WebSocketException exc) { OnError(exc, true); } catch (IOException exc) { OnError(exc, true); } catch (InvalidOperationException exc) { OnError(exc, true); } catch (Exception exc) { OnError(exc, false); } }
/// <summary> /// Закрытие сервера /// </summary> protected virtual ValueTask DisposeAsync(bool disposing) { var clientArray = _clients.Values.ToArray(); _clients.Clear(); foreach (var client in clientArray) { client.Dispose(); } ConnectionsLock.Dispose(); return(default);
private async ValueTask ProcessIncomingMessageAsync(Message message) { foreach (var client in _clients.Values) { Debug.WriteLine($"Checking client: {client.Name}; message.Receiver = {message.Receiver}."); if (message.Receiver == client.Name || message.Receiver == NetworkConstants.Everybody || string.IsNullOrEmpty(client.Name) || !message.IsSystem && !message.IsPrivate) { Debug.WriteLine($"Message added to client: {client.Name}"); client.AddIncomingMessage(message); } else if (!IsMain && !_wrongUserMessageShown) { _wrongUserMessageShown = true; OnError(new Exception(string.Format(_localizer["WrongReceiver"], message.Receiver, client.Name)), true); } } if (IsMain) { // Надо переслать это сообщение остальным await ConnectionsLock.WithLockAsync(async() => { foreach (var connection in Connections) { bool send; if (IsMain) { send = (connection.UserName != message.Sender) && ((connection.UserName == message.Receiver) || message.Receiver == NetworkConstants.Everybody && connection.IsAuthenticated); } else { lock (connection.ClientsSync) { send = !connection.Clients.Contains(message.Sender) && (connection.Clients.Contains(message.Receiver) || message.Receiver == NetworkConstants.Everybody && connection.IsAuthenticated); } } if (send) { await connection.SendMessageAsync(message); } } }); } }
public static bool TryGetGroup(string group, out GroupDetails groupdetails) { try { ConnectionsLock.EnterReadLock(); if (Connections.TryGetValue(group, out groupdetails)) { return(true); } return(false); } finally { ConnectionsLock.ExitReadLock(); } }
protected override async ValueTask DisposeAsync(bool disposing) { await ConnectionsLock.TryLockAsync( async() => { if (HostServer != null) { await HostServer.DisposeAsync(); HostServer = null; } }, 5000, true); await base.DisposeAsync(disposing); }
public override async ValueTask RemoveConnectionAsync( IConnection connection, bool withError, CancellationToken cancellationToken = default) { await ConnectionsLock.WithLockAsync( () => { if (_connections.Contains(connection)) { _connections.Remove(connection); } }, cancellationToken); await base.RemoveConnectionAsync(connection, withError, cancellationToken); }
public override async ValueTask RemoveConnectionAsync(IConnection connection, bool withError, CancellationToken cancellationToken = default) { await ConnectionsLock.WithLockAsync( () => { if (HostServer == connection) { connection.Reconnecting -= OnReconnecting; connection.Reconnected -= OnReconnected; HostServer = null; } }, cancellationToken); await base.RemoveConnectionAsync(connection, withError, cancellationToken); }
public override ValueTask <bool> AddConnectionAsync(IConnection connection, CancellationToken cancellationToken = default) => ConnectionsLock.WithLockAsync( async() => { if (HostServer != null && HostServer != connection) { await RemoveConnectionAsync(HostServer, false, cancellationToken); } HostServer = connection; connection.Reconnecting += OnReconnecting; connection.Reconnected += OnReconnected; return(await base.AddConnectionAsync(connection, cancellationToken)); }, cancellationToken);
private ValueTask ProcessOutgoingMessageAsync(Message message) { foreach (var client in _clients.Values) { if ((message.Receiver == client.Name || client.Name.Length == 0 || message.Receiver == NetworkConstants.Everybody || !message.IsSystem && !message.IsPrivate) && client.Name != message.Sender) { client.AddIncomingMessage(message); } } return(ConnectionsLock.WithLockAsync(async() => { foreach (var connection in Connections) { bool send; if (IsMain) { send = (connection.UserName != message.Sender) && (message.Receiver == NetworkConstants.Everybody && connection.IsAuthenticated || (connection.UserName == message.Receiver)); } else { lock (connection.ClientsSync) { send = !connection.Clients.Contains(message.Sender) && (message.Receiver == NetworkConstants.Everybody && connection.IsAuthenticated || connection.Clients.Contains(message.Receiver)); } } if (send) { await connection.SendMessageAsync(message); } } })); }
public static bool TryGetGroupByUser(string connectionid, out GroupDetails groupdetails, out UserDetails userdetails) { try { ConnectionsLock.EnterReadLock(); foreach (var connection in Connections.Values) { if (connection.TryGetUser(connectionid, out userdetails)) { groupdetails = connection; return(true); } } groupdetails = null; userdetails = null; return(false); } finally { ConnectionsLock.ExitReadLock(); } }