private void TryJoinToSession(ServerSideMsgPipe pipe, string nickName) { var joiningSession = _sessions.FirstOrDefault(s => s.NeedClient); switch (joiningSession) { case null when _sessions.Count >= _maxSessions: ClosePipeWithError(pipe, ServerErrorId.ServerIsBusy); _log?.Error($"Failed to add client {pipe.Id} into session: server is busy"); return; case null: var sendBufferSize = _sessionPlayers * 512; joiningSession = new ServerSession(_random, _lastSessionId++, _sessionPlayers, _tps, sendBufferSize, _log); _sessions.Add(joiningSession); break; case {} session when session.HasClientWithName(nickName): ClosePipeWithError(pipe, ServerErrorId.NickIsBusy); _log?.Error($"Failed to add client {pipe.Id} into session: nickname is busy"); return; } try { pipe.SendMessageUsingBuffer(new ServerMsgJoined(), _sendBuffer); joiningSession.AddClient(pipe, nickName); } catch (Exception e) { ClosePipeWithError(pipe, ServerErrorId.InternalError); _log?.Error($"Failed to add client {pipe.Id} into session: internal error"); _log?.Exception(e); } }
private void ClosePipeWithError(ServerSideMsgPipe pipe, ServerErrorId error) { try { pipe.SendMessageUsingBuffer(new ServerMsgError(error), _sendBuffer); } finally { pipe.Close(); } }
public void ClientShouldReceiveAllServerMessages() { var msgOrder = new[] { ServerMsgId.KeepAlive, ServerMsgId.Error, ServerMsgId.Joined, ServerMsgId.Start, ServerMsgId.Inputs, ServerMsgId.Finish }; _serverSidePipe.SendMessageUsingBuffer(new ServerMsgKeepAlive(), _sendBuffer); _serverSidePipe.SendMessageUsingBuffer(new ServerMsgError(ServerErrorId.InternalError), _sendBuffer); _serverSidePipe.SendMessageUsingBuffer(new ServerMsgJoined(), _sendBuffer); _clientSidePipe.ReceiveMessages(); _serverSidePipe.SendMessageUsingBuffer(new ServerMsgStart(0, new [] { "foo", "bar" }, 1, 25), _sendBuffer); _serverSidePipe.SendMessageUsingBuffer(new ServerMsgInput(3, 2, 1), _sendBuffer); _serverSidePipe.SendMessageUsingBuffer(new ServerMsgFinish(new [] { 0u, 1u }, new [] { 2, 3 }), _sendBuffer); _clientSidePipe.ReceiveMessages(); Assert.True(_clientSidePipe.ReceiveOrder.Count == msgOrder.Length); foreach (var msgId in msgOrder) { Assert.True(msgId == _clientSidePipe.ReceiveOrder.Dequeue()); switch (msgId) { case ServerMsgId.KeepAlive: case ServerMsgId.Joined: break; case ServerMsgId.Error: _clientSidePipe.ErrorMessages.Dequeue(); break; case ServerMsgId.Start: _clientSidePipe.StartMessages.Dequeue(); break; case ServerMsgId.Inputs: _clientSidePipe.InputMessages.Dequeue(); break; case ServerMsgId.Finish: _clientSidePipe.FinishMessages.Dequeue(); break; default: throw new ArgumentOutOfRangeException(); } } }