private bool UpdateSpeakerStates(ReceivingState state, bool allClosing, bool forceReset, int channelSession, ushort sequenceNumber, ushort senderId, string playerName) { if (forceReset || state.ExpectedChannelSession != channelSession) { state.ExpectedChannelSession = channelSession; Log.Trace( state.Open ? "Channel Session has changed: {0} => {1} (Triggering forced playback reset)" : "Channel Session has changed: {0} => {1}", state.ExpectedChannelSession, channelSession ); //If there is an open session force it closed (we will re-open it instantly) if (state.Open) { _client.OnPlayerStoppedSpeaking(playerName); state.Open = false; } } //If this player does not currently have an open channel, open it (and reset sequence numbers etc) if (!state.Open) { // check for old sequence numbers and discard if (state.BaseSequenceNumber.WrappedDelta(sequenceNumber) < 0) { return(false); } state.PlayerId = senderId; state.BaseSequenceNumber = sequenceNumber; state.LocalSequenceNumber = 0; state.LastReceiptTicks = DateTime.Now.Ticks; state.Open = true; _client.OnPlayerStartedSpeaking(playerName); } var sequenceDelta = state.BaseSequenceNumber.WrappedDelta(sequenceNumber); if (state.LocalSequenceNumber + sequenceDelta < 0) { // we must have received our first packet out of order // this "old" packet will give us a negative local sequence number, which will wrap when cast into the uint // discard the packet return(false); } state.LastReceiptTicks = DateTime.Now.Ticks; state.LocalSequenceNumber = (uint)(state.LocalSequenceNumber + sequenceDelta); state.BaseSequenceNumber = sequenceNumber; state.Open = !allClosing; return(true); }
private static void Receive(Socket clientSocket) { // Создаем объект для callback. ReceivingState receivingState = new ReceivingState(); receivingState.ClientSocket = clientSocket; // Начинаем асинхронно получать данные от клиента. // Передаем буфер, куда будут складываться полученные байты. clientSocket.BeginReceive(receivingState.Buffer, 0, ReceivingState.BufferSize, SocketFlags.None, ReceiveCallback, receivingState); }
private void ReadChannelStates(ref PacketReader reader, ReceivingState state, ushort numChannels, out bool positional, out bool allClosing, out bool forceReset, out ChannelPriority priority) { positional = true; allClosing = true; int forcingReset = 0; priority = ChannelPriority.None; for (var i = 0; i < numChannels; i++) { byte channelBitfield; ushort channelRecipient; reader.ReadVoicePacketChannel(out channelBitfield, out channelRecipient); var channel = new ChannelBitField(channelBitfield); var compositeId = (int)(channel.Type) | channelRecipient << 8; _tmpCompositeIdBuffer.Add(compositeId); int previousSession; if (state.ExpectedPerChannelSessions.TryGetValue(compositeId, out previousSession)) { if (previousSession != channel.SessionId) { forcingReset++; } } state.ExpectedPerChannelSessions[compositeId] = channel.SessionId; if (ChannelAddressesUs(channel, channelRecipient)) { if (!channel.IsPositional) { positional = false; } if (!channel.IsClosing) { allClosing = false; } if (channel.Priority > priority) { priority = channel.Priority; } } } forceReset = forcingReset == numChannels; state.ClearChannels(_tmpCompositeIdBuffer); _tmpCompositeIdBuffer.Clear(); }
private void ProcessCommands(string messageType, int BytesRead) { switch (messageType) { case "IMG": Debug.Assert(state == ReceivingState.NONE, "Connector.cs: state should be NONE, was " + state.ToString() + ", bytes read: " + BytesRead); state = ReceivingState.IMG; // If packet came with "IMG|" + data, handle below if (BytesRead > 4) { for (int i = 4; i < BytesRead; i++) { imgBuffer[imgByteOffset + i - 4] = readBuffer[i]; } imgByteOffset += (BytesRead - 4); if (imgByteOffset >= IMG_SIZE) { imgByteOffset = 0; state = ReceivingState.NONE; } } break; case "": // string.Empty if (state == ReceivingState.IMG) { for (int i = 0; i < BytesRead; i++) { imgBuffer[imgByteOffset + i] = readBuffer[i]; } imgByteOffset += BytesRead; if (imgByteOffset >= IMG_SIZE) { imgByteOffset = 0; state = ReceivingState.NONE; } } break; default: Debug.Assert(false, "Connector.cs: messageType (" + messageType + ") was not valid"); break; } }
private ReceivingState FindState(ushort senderId, bool reset = false) { if (senderId < _receiving.Count) { if (reset) { _receiving[senderId] = new ReceivingState(); } } else { while (_receiving.Count <= senderId) { _receiving.Add(new ReceivingState()); } } return(_receiving[senderId]); }
private static void ReceiveCallback(IAsyncResult asyncResult) { // Достаем клиентский сокет из параметра callback. ReceivingState receivingState = (ReceivingState)asyncResult.AsyncState; Socket clientSocket = receivingState.ClientSocket; // Читаем данные из клиентского сокета. int bytesReceived = clientSocket.EndReceive(asyncResult); if (bytesReceived > 0) { // В буфер могли поместиться не все данные. // Все данные от клиента складываем в другой буфер - ReceivedData. receivingState.ReceivedData.AddRange(receivingState.Buffer.Take(bytesReceived)); // Пытаемся распарсить Request из полученных данных. byte[] receivedBytes = receivingState.ReceivedData.ToArray(); Request request = Request.StupidParse(receivedBytes); if (request == null) { // request не распарсился, значит получили не все данные. // Запрашиваем еще. clientSocket.BeginReceive(receivingState.Buffer, 0, ReceivingState.BufferSize, SocketFlags.None, ReceiveCallback, receivingState); } else { // Все данные были получены от клиента. // Для удобства выведем их на консоль. Console.WriteLine( $">>> Received {receivedBytes.Length} bytes from {clientSocket.RemoteEndPoint}. Data:\n" + Encoding.ASCII.GetString(receivedBytes)); // Сформируем ответ. byte[] responseBytes = ProcessRequest(request); // Отправим ответ клиенту. Send(clientSocket, responseBytes); } } }
public StateChangedEventArgs(RunningState runningState, ReceivingState receivingState) { RunningState = runningState; ReceivingState = receivingState; }