public override void ReceiveLog(LogRecord record, string kind) { MemoryBuffer <byte> buf = new MemoryBuffer <byte>(); record.WriteRecordToBuffer(this.LogInfoOptions, buf); MasterBuffer.NonStopWriteWithLock(buf.Memory, true, FastStreamNonStopWriteMode.DiscardExistingData); lock (LockObj) { foreach (var pipe in this.SubscribersList) { pipe.CounterPart._NullCheck(); lock (pipe.CounterPart.StreamWriter.LockObj) { if (pipe.CounterPart.StreamWriter.NonStopWriteWithLock(buf.Memory, false, FastStreamNonStopWriteMode.DiscardExistingData) != 0) { // To avoid deadlock, CompleteWrite() must be called from other thread. // (CompleteWrite() ==> Disconnect ==> Socket Log will recorded ==> ReceiveLog() ==> this function will be called!) TaskUtil.StartSyncTaskAsync(() => pipe.CounterPart.StreamWriter.CompleteWrite(false), false, false)._LaissezFaire(true); } } } } }
public TelnetStreamWatcherBase(TelnetStreamWatcherOptions options) { this.Options = options; Listener = TcpIp.CreateTcpListener(new TcpListenParam(async(listener, sock) => { try { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Connected: {sock.EndPointInfo._GetObjectDump()}"); await using (var destStream = sock.GetStream()) { if (sock.Info.Ip.RemoteIPAddress == null || Options.IPAccessFilter(sock.Info.Ip.RemoteIPAddress) == false) { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Access denied: {sock.EndPointInfo._GetObjectDump()}"); await destStream.WriteAsync("You are not allowed to access to this service.\r\n\r\n"._GetBytes_Ascii()); await Task.Delay(100); return; } using (var pipePoint = await SubscribeImplAsync()) { // ソケットから Enter キー入力を待機する Task keyInputTask = TaskUtil.StartAsyncTaskAsync(async() => { using StreamReader lineReader = new StreamReader(destStream); while (true) { string?line = await lineReader.ReadLineAsync(); if (line == null) { break; } line = line.Trim(); if (line._IsSamei("s")) { // Socket リストの表示 var list = LocalNet.GetSockList().OrderBy(x => x.Connected); StringWriter w = new StringWriter(); w.WriteLine(); foreach (var sock in list) { string tmp = sock._GetObjectDump(); w.WriteLine(tmp); } w.WriteLine(); w.WriteLine($"Total sockets: {list.Count()}"); w.WriteLine(); byte[] data = w.ToString()._GetBytes_Ascii(); var pipe = pipePoint; if (pipe.CounterPart != null) { lock (pipe.CounterPart.StreamWriter.LockObj) { if (pipe.CounterPart.StreamWriter.NonStopWriteWithLock(data, false, FastStreamNonStopWriteMode.DiscardExistingData) != 0) { // To avoid deadlock, CompleteWrite() must be called from other thread. // (CompleteWrite() ==> Disconnect ==> Socket Log will recorded ==> ReceiveLog() ==> this function will be called!) TaskUtil.StartSyncTaskAsync(() => pipe.CounterPart.StreamWriter.CompleteWrite(false), false, false)._LaissezFaire(true); } } } } else if (line._IsSamei("0")) { // GC Dbg.WriteLine($"Manual GC0 is called by the administrator."); long start = Time.HighResTick64; GC.Collect(0, GCCollectionMode.Forced, true, true); long end = Time.HighResTick64; long spentTime = end - start; Dbg.WriteLine($"Manual GC0 Took Time: {spentTime} msecs."); } else if (line._IsSamei("1")) { // GC Dbg.WriteLine($"Manual GC1 is called by the administrator."); long start = Time.HighResTick64; GC.Collect(1, GCCollectionMode.Forced, true, true); long end = Time.HighResTick64; long spentTime = end - start; Dbg.WriteLine($"Manual GC1 Took Time: {spentTime} msecs."); } else { // GC Dbg.WriteLine($"Manual GC is called by the administrator."); long start = Time.HighResTick64; Dbg.GcCollect(); long end = Time.HighResTick64; long spentTime = end - start; Dbg.WriteLine($"Manual GC Took Time: {spentTime} msecs."); } } }); try { // ソケットに対して、pipePoint のストリームをそのまま非同期で流し込む await using (var pipeStub = pipePoint.GetNetAppProtocolStub()) await using (var srcStream = pipeStub.GetStream()) { await srcStream.CopyToAsync(destStream, sock.GrandCancel); } } finally { await UnsubscribeImplAsync(pipePoint); await pipePoint.CleanupAsync(new DisconnectedException()); await keyInputTask._TryAwait(noDebugMessage: true); } } } } finally { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Disconnected: {sock.EndPointInfo._GetObjectDump()}"); } }, "TelnetStreamWatcher", this.Options.EndPoints.ToArray())); this.AddIndirectDisposeLink(this.Listener); }