public async Task RegisterClientAsync(IClientCredentals credentials, WebSocket socket, TaskCompletionSource <object> requestCompletedTcs, CancellationToken cancellationToken = default) { if (!credentials.Valid) { await socket.SendMessageAsync(Message.Error(Errors.InvalidWsParameters), cancellationToken); await socket.CloseAsync(Errors.InvalidWsParameters); requestCompletedTcs.TrySetResult(null); return; } if (!_world.TryGetValue(credentials.Key, out var realm)) { realm = new Realm(); _world.TryAdd(credentials.Key, realm); } var client = realm.GetClient(credentials.ClientId); if (client != null) { if (credentials.Token != client.GetToken()) { await socket.SendMessageAsync(Message.Create(MessageType.IdTaken, "Id is already used!")); await socket.CloseAsync(Errors.InvalidToken); requestCompletedTcs.TrySetResult(null); return; } client.SetSocket(socket); // TODO send queued messages } else { // TODO check concurrent limit options client = new Client(credentials, socket); realm.SetClient(client); await client.SendAsync(new Message { Type = MessageType.Open, }, cancellationToken); } // listen for incoming messages await AwaitReceiveAsync(client, realm, cancellationToken); // clean-up after socket close realm.RemoveClientById(client.GetId()); requestCompletedTcs.TrySetResult(null); }
public Client(IClientCredentals credentials, WebSocket socket) { _credentials = credentials; _socket = socket; _reportingTime = DateTime.UtcNow; }