/// <summary> /// Read message /// </summary> /// <typeparam name="T">Type</typeparam> public T ReadMessage <T>() where T : TuringMessage { if (_Signal == null) { return(null); } TuringMessage ret = null; _Signal.WaitOne(); lock (_Readed) { while (_Readed != null && !_Readed.TryDequeue(out ret)) { Thread.Sleep(1); } } if (ret == null) { throw (new Exception("Disconnected")); } if (ret is T) { return((T)ret); } if (ret is ExceptionMessage) { throw (new Exception(((ExceptionMessage)ret).Error)); } throw (new Exception("Bad response")); }
void RaiseOnMessage(TuringSocket sender, TuringMessage message) { if (message == null) { return; } // Enqueue if (EnqueueMessages) { lock (_Readed) { _Readed.Enqueue(message); } _Signal.Set(); } OnMessage?.Invoke(sender, message); }
/// <summary> /// Check Data /// </summary> public TuringMessage CheckData(int read) { Index += read; switch (State) { case ETuringMessageState.ReadingHeader: { if (Index == TuringMessage.HeaderLength) { int length; ETuringMessageType type; if (TuringMessage.ParseHeader(Buffer, 0, TuringMessage.HeaderLength, out length, out type)) { Index = 0; Buffer = new byte[length]; MessageType = type; State = ETuringMessageState.ReadingData; if (length == 0) { Clear(); return(TuringMessage.Create(type, Buffer)); } } } break; } case ETuringMessageState.ReadingData: { if (Index == Buffer.Length) { TuringMessage ret = TuringMessage.Create(MessageType, Buffer); Clear(); return(ret); } break; } } return(null); }
void OnDataReceive(IAsyncResult result) { TuringMessageState state = (TuringMessageState)result.AsyncState; try { int bytesRead = state.Source._Socket.EndReceive(result); if (bytesRead > 0) { TuringMessage msg = state.CheckData(bytesRead); if (msg != null) { RaiseOnMessage(state.Source, msg); } ReadMessageAsync(state); } } catch// (Exception e) { state.Source.Dispose(); } }
/// <summary> /// Send a message /// </summary> /// <param name="message">Message</param> public void SendMessage(TuringMessage message) { if (message == null || _Socket == null) { return; } lock (_Socket) { byte[] data = message.GetData(); // http://stackoverflow.com/questions/5523565/socket-flush-by-temporarily-enabling-nodelay //_Socket.NoDelay = true; // Send header _Socket.Send(message.GetHeader(data == null ? 0 : data.Length), 0, TuringMessage.HeaderLength, SocketFlags.None); // Send data if (data != null) { _Socket.Send(data, 0, data.Length, SocketFlags.None); } //_Socket.NoDelay = false; } }