/// <summary> /// 按照时间、设备状态等数据创建放大器采样数据文件, /// 写入文件头(格式定义在SampleDataFileFormat), /// 关闭时写入MD5校验值 /// </summary> /// <param name="state"></param> /// <param name="devId"></param> /// <param name="version"></param> /// <param name="bufferManager"></param> public FileResource(BrainDevState state, uint devId, byte version, SyncBufManager bufferManager) { _state = state; _devId = devId; _version = version; _bufferManager = bufferManager; }
public static (int, byte[]) Header(SyncBufManager bufferManager, byte version, uint devId, long startTick, BrainDevState state) { var buf = bufferManager.TakeBuffer(CntStartIndex); buf[0] = version; var ind = 1; unsafe { WritePrimitive((byte *)&devId, sizeof(uint), buf, ref ind); WritePrimitive((byte *)&startTick, sizeof(long), buf, ref ind); buf[ind++] = state.DevCode; buf[ind++] = state.ChannelCount; buf[ind++] = state.Gain; buf[ind++] = (byte)state.SampleRate; buf[ind++] = (byte)state.TrapOption; buf[ind++] = state.EnalbeFilter ? (byte)1 : (byte)0; for (var i = ind; i < CntStartIndex; i++) { buf[i] = 0; } } return(CntStartIndex, buf); }
ToDynamicFrameSubject(this Socket socket, ISimpleFrameEncoder encoder, IDynamicFrameDecoder decoder, SyncBufManager bufferManager, CancellationToken token) { return(Subject.Create <DisposableValue <ArraySegment <byte> >, DisposableValue <ArraySegment <byte> > >( socket.ToFrameClientObserver(encoder, token, bufferManager), socket.ToDynamicFrameObservable(bufferManager, decoder))); }
static BrainDeviceManager() { bufferManager = SyncBufManager.Create(2 << 16, 128, 32); encoder = new ClientFrameEncoder(0xA0, 0XC0); decoder = new FixedLenFrameDecoder(0xA0, 0XC0); _dataStream = new Subject <(byte, ArraySegment <int>, ArraySegment <byte>)>(); _stateStream = new Subject <BrainDevState>(); AppDomain.CurrentDomain.ProcessExit += ProcessExit; }
//version 1 (byte version, uint devId, long startTick,BrainDevState state,byte[] MD5Hash) public static (byte, uint, long, BrainDevState, byte[]) ReadHeader(this FileStream fs, SyncBufManager bufferManager) { var buf = bufferManager.TakeBuffer(CntStartIndex); var count = fs.Read(buf, 0, CntStartIndex); if (count < CntStartIndex) { throw new Exception("Invalid Sample Data File Format"); } var version = buf[0]; if (version != 1) { throw new Exception("not supported sample data format, only version 1 is supported"); } var ind = 1; uint devId; long startTick; var state = default(BrainDevState); unsafe { ReadPrimitive((byte *)&devId, sizeof(uint), buf, ref ind); ReadPrimitive((byte *)&startTick, sizeof(long), buf, ref ind); state.DevCode = buf[ind++]; state.ChannelCount = buf[ind++]; state.Gain = buf[ind++]; state.SampleRate = (SampleRateEnum)buf[ind++]; state.TrapOption = (TrapSettingEnum)buf[ind++]; state.EnalbeFilter = buf[ind++] == 1; } var md5Buf = new byte[Md5Len]; Buffer.BlockCopy(buf, ind, md5Buf, 0, Md5Len); bufferManager.ReturnBuffer(buf); return(version, devId, startTick, state, md5Buf); }
private static void OldTest(string[] args) { var endpoint = ProgramArgs.Parse(args, new[] { "127.0.0.1:9211" }).EndPoint; var cts = new CancellationTokenSource(); var bufferManager = SyncBufManager.Create(2 << 16, 128, 32); var encoder = new ClientFrameEncoder(0xA0, 0XC0); var decoder = new FixedLenFrameDecoder(0xA0, 0XC0); endpoint.ToConnectObservable() .ObserveOn(TaskPoolScheduler.Default) .Subscribe(socket => { var frameClientSubject = socket.ToFixedLenFrameSubject(encoder, decoder, bufferManager, cts.Token); var observerDisposable = frameClientSubject .ObserveOn(TaskPoolScheduler.Default) .Subscribe( managedBuffer => { var segment = managedBuffer.Value; if (!ReceivedDataProcessor.Instance.Process(segment) && segment.Array != null) { Console.WriteLine( "Echo: " + Encoding.UTF8.GetString(segment.Array, segment.Offset, segment.Count)); } managedBuffer.Dispose(); }, error => { Console.WriteLine("Error: " + error.Message); cts.Cancel(); }, () => { Console.WriteLine("OnCompleted: Frame Protocol Receiver"); cts.Cancel(); }); var cmdSender = new DevCommandSender(frameClientSubject, bufferManager, null); Console.In.ToLineObservable("exit") .Subscribe( line => { if (string.IsNullOrEmpty(line)) { return; } if (line == "start") { cmdSender.Start(); return; } if (line == "stop") { cmdSender.Stop(); return; } var writeBuffer = Encoding.UTF8.GetBytes(line); frameClientSubject.OnNext( DisposableValue.Create(new ArraySegment <byte>(writeBuffer), Disposable.Empty)); }, error => { Console.WriteLine("Error: " + error.Message); cts.Cancel(); }, () => { Console.WriteLine("OnCompleted: LineReader"); cts.Cancel(); }); cts.Token.WaitHandle.WaitOne(); observerDisposable.Dispose(); }, error => { Console.WriteLine("Failed to connect: " + error.Message); cts.Cancel(); }, cts.Token); cts.Token.WaitHandle.WaitOne(); }
public DevCommandSender(IObserver <DisposableValue <ArraySegment <byte> > > clientFrameSender, SyncBufManager bufMgr, IObservable <(bool, uint)> enableTimeoutConfig)
public static IObservable <DisposableValue <ArraySegment <byte> > > ToFixedLenFrameObservable(this Socket socket, SyncBufManager bufferManager, IFixedLenFrameDecoder decoder) { return(Observable.Create <DisposableValue <ArraySegment <byte> > >(async(observer, token) => { var receivedFlag = decoder.ReceivedFlags; var decoderLenByteCount = decoder.LenByteCount; var hc = 1 + decoderLenByteCount; var decoderHeader = decoder.Header; var decoderTail = decoder.Tail; var headerBuffer = new byte[hc]; try { while (!token.IsCancellationRequested) { if (await socket.ReceiveCompletelyAsync(headerBuffer, hc, receivedFlag, token) != hc) { break; } if (headerBuffer[0] != decoderHeader) { AppLogger.Warning($"corruted packet: invalid frame header"); break; } var length = LengthBitConverter.FromByte(headerBuffer, 1, decoderLenByteCount) - 1; var buffer = bufferManager.TakeBuffer(length); if (await socket.ReceiveCompletelyAsync(buffer, length, receivedFlag, token) != length) { break; } var arraySegment = new ArraySegment <byte>(buffer, 0, length); observer.OnNext( new DisposableValue <ArraySegment <byte> >(arraySegment, Disposable.Create(() => bufferManager.ReturnBuffer(buffer)))); if (await socket.ReceiveAsync(headerBuffer, 0, 1, receivedFlag) == 0) { break; } if (headerBuffer[0] != decoderTail) { AppLogger.Warning($"corruted packet: invalid frame tail," + headerBuffer[0].Show()); break; } } observer.OnCompleted(); } catch (Exception error) { observer.OnError(error); } })); }
public static IObserver <DisposableValue <ArraySegment <byte> > > ToFrameClientObserver(this Socket socket, ISimpleFrameEncoder encoder, CancellationToken token, SyncBufManager bufMgr) { return(Observer.Create <DisposableValue <ArraySegment <byte> > >(async disposableBuffer => { await socket.SendCompletelyAsync( encoder.EncoderSendFrame(disposableBuffer.Value), encoder.SendFlags, token, bufMgr); })); }
public static IObservable <DisposableValue <ArraySegment <byte> > > ToDynamicFrameObservable(this Socket socket, SyncBufManager bufferManager, IDynamicFrameDecoder decoder) { return(Observable.Create <DisposableValue <ArraySegment <byte> > >(async(observer, token) => { try { var state = decoder.InitState(); byte[] leftoverBuf = null; //rider suggestion is buggy: this variable must declare outside the loop in the case when receive length is zero int leftoverCount = 0; while (!token.IsCancellationRequested) { byte[] bufferArray; int startIdx; if (leftoverBuf != null) { bufferArray = leftoverBuf; startIdx = leftoverCount; leftoverBuf = null; } else { bufferArray = bufferManager.TakeBuffer(decoder.BufferSize); startIdx = 0; } var pair = await socket.ReceiveDynamicFrame(state, bufferArray, startIdx, decoder, token); var receiveLen = pair.Item1; leftoverCount = pair.Item2; if (receiveLen == 0) //no data received, and leftoverCount should be zero { var dropFrameStrategy = decoder.CheckDropFrame(state, bufferArray, startIdx); switch (dropFrameStrategy) { case DropFrameStrategyEnum.DropAndClose: //reclaim buffer array bufferManager.ReturnBuffer(bufferArray); break; case DropFrameStrategyEnum.DropAndRestart: //reclaim buffer array bufferManager.ReturnBuffer(bufferArray); continue; case DropFrameStrategyEnum.KeepAndContinue: //keep last received data leftoverBuf = bufferArray; leftoverCount = startIdx; continue; } if (dropFrameStrategy == DropFrameStrategyEnum.DropAndClose) { break; } } if (receiveLen == -1) //overflow,TODO support extensible frame in future { //reclaim buffer array bufferManager.ReturnBuffer(bufferArray); break; } //copy leftover if (leftoverCount > 0) { leftoverBuf = bufferManager.TakeBuffer(decoder.BufferSize); Buffer.BlockCopy(bufferArray, receiveLen - leftoverCount, leftoverBuf, 0, leftoverCount); } var arraySegment = decoder.BuildFrame(state, bufferArray, receiveLen, leftoverCount); observer.OnNext( new DisposableValue <ArraySegment <byte> >(arraySegment, Disposable.Create(() => bufferManager.ReturnBuffer(bufferArray)))); } observer.OnCompleted(); socket.Close(); } catch (Exception error) { observer.OnError(error); } })); }
public static async Task <int> SendCompletelyAsync(this Socket socket, IList <ArraySegment <byte> > buffers, SocketFlags socketFlags, CancellationToken token, SyncBufManager bufMgr) { token.ThrowIfCancellationRequested(); var sent = 0; var count = 0; for (var i = 0; i < buffers.Count; i++) { count += buffers[i].Count; } var copy = bufMgr.TakeBuffer(count); try { count = 0; for (var i = 0; i < buffers.Count; i++) { ArraySegment <byte> arraySegment = buffers[i]; Buffer.BlockCopy(arraySegment.Array, arraySegment.Offset, copy, count, arraySegment.Count); count += arraySegment.Count; } var bytes = await socket.SendCompletelyAsync(copy, count, socketFlags, token); sent += bytes; AppLogger.Debug($"SendCompletelyAsync:{sent},{buffers.Show()}"); return(sent); } finally { bufMgr.ReturnBuffer(copy); } }