protected sealed override async Task ConnectAndGetValueImplAsync(CancellationToken cancel = default) { await Task.Yield(); ComPortClient?client = null; try { client = new ComPortClient(this.Settings.ComSettings); await using ShellClientSock sock = await client.ConnectAndGetSockAsync(cancel); await TaskUtil.DoAsyncWithTimeout(async (c) => { await Task.Yield(); await GetValueFromComPortImplAsync(sock, c); return(0); }, cancelProc : () => { sock._DisposeSafe(new OperationCanceledException()); }, cancel : cancel); } catch { await client._DisposeSafeAsync(); throw; } }
// シリアルポート --> 抽象 Stream protected override async Task <bool> StreamReadFromObjectImplAsync(FastStreamBuffer fifo, CancellationToken cancel) { if (this.SerialPort.IsOpen == false) { throw new FastBufferDisconnectedException(); } await TaskUtil.DoAsyncWithTimeout( async c => { using (MemoryHelper.FastAllocMemoryWithUsing(RecvTmpBufferSize, out Memory <byte> buffer)) { int recvSize = await this.Stream.ReadAsync(buffer, cancel); if (recvSize <= 0) { fifo.Disconnect(); return(0); } fifo.EnqueueWithLock(buffer._SliceHead(recvSize)._CloneMemory(), true); } return(0); }, cancelProc : () => { this.SerialPort.Close(); }, cancel : cancel); return(true); }
public static async Task WriteAsyncWithTimeout(this Stream stream, byte[] buffer, int offset = 0, int?count = null, int?timeout = null, CancellationToken cancel = default(CancellationToken), params CancellationToken[] cancel_tokens) { if (timeout == null) { timeout = stream.WriteTimeout; } if (timeout <= 0) { timeout = Timeout.Infinite; } int target_write_size = count ?? (buffer.Length - offset); if (target_write_size == 0) { return; } try { await TaskUtil.DoAsyncWithTimeout <int>(async (cancel_for_proc) => { await stream.WriteAsync(buffer, offset, target_write_size, cancel_for_proc); return(0); }, timeout : (int)timeout, cancel : cancel, cancel_tokens : cancel_tokens); } catch { stream.TryCloseNonBlock(); throw; } }
protected override async Task StreamWriteToObjectImplAsync(FastStreamBuffer fifo, CancellationToken cancel) { await TaskUtil.DoAsyncWithTimeout( async c => { bool flush = false; using (MemoryHelper.FastAllocMemoryWithUsing(SendTmpBufferSize, out Memory <byte> buffer)) { while (true) { int size = fifo.DequeueContiguousSlowWithLock(buffer); if (size == 0) { break; } var dataToSend = buffer.Slice(0, size); await Stream.WriteAsync(dataToSend, cancel); flush = true; } } if (flush) { await Stream.FlushAsync(cancel); } return(0); }, cancel: cancel); }
protected override Task <SendPingReply> SendPingImplAsync(IPAddress target, byte[] data, int timeout, CancellationToken cancel) { // 現時点で SendAsync メソッドはキャンセルや厳密なタイムアウトを実現していないので DoAsyncWithTimeout() を用いて無理矢理実現する return(TaskUtil.DoAsyncWithTimeout((c) => { return Legacy.SendPing.SendAsync(target, data, timeout); }, timeout: timeout + 1000, cancel: cancel)); }
public static async Task <int> ReadAsyncWithTimeout(this Stream stream, byte[] buffer, int offset = 0, int?count = null, int?timeout = null, bool?read_all = false, CancellationToken cancel = default(CancellationToken), params CancellationToken[] cancel_tokens) { if (timeout == null) { timeout = stream.ReadTimeout; } if (timeout <= 0) { timeout = Timeout.Infinite; } int target_read_size = count ?? (buffer.Length - offset); if (target_read_size == 0) { return(0); } try { int ret = await TaskUtil.DoAsyncWithTimeout <int>(async (cancel_for_proc) => { if (read_all == false) { return(await stream.ReadAsync(buffer, offset, target_read_size, cancel_for_proc)); } else { int current_read_size = 0; while (current_read_size != target_read_size) { int sz = await stream.ReadAsync(buffer, offset + current_read_size, target_read_size - current_read_size, cancel_for_proc); if (sz == 0) { return(0); } } return(current_read_size); } }, timeout : (int)timeout, cancel : cancel, cancel_tokens : cancel_tokens); if (ret <= 0) { throw new EndOfStreamException("The NetworkStream is disconnected."); } return(ret); } catch { stream.TryCloseNonBlock(); throw; } }
// 抽象 Stream --> シリアルポート protected override async Task StreamWriteToObjectImplAsync(FastStreamBuffer fifo, CancellationToken cancel) { if (this.SerialPort.IsOpen == false) { throw new FastBufferDisconnectedException(); } await TaskUtil.DoAsyncWithTimeout( async c => { bool flush = false; using (MemoryHelper.FastAllocMemoryWithUsing(SendTmpBufferSize, out Memory <byte> buffer)) { while (true) { int size = fifo.DequeueContiguousSlowWithLock(buffer); if (size == 0) { break; } await Stream.WriteAsync(buffer.Slice(0, size), cancel); flush = true; } } if (flush) { await Stream.FlushAsync(cancel); } return(0); }, cancelProc : () => { this.SerialPort.Close(); }, cancel : cancel); }
public async Task StartWebSocketClientAsync(string uri, CancellationToken cancel = default) { if (Started.IsFirstCall() == false) { throw new ApplicationException("Already started."); } LowerStream.ReadTimeout = Options.TimeoutOpen; LowerStream.WriteTimeout = Options.TimeoutOpen; Uri u = new Uri(uri); HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, uri); byte[] nonce = Secure.Rand(16); string requestKey = Convert.ToBase64String(nonce); req.Headers.Add("Host", u.Host); req.Headers.Add("User-Agent", Options.UserAgent); req.Headers.Add("Accept", Consts.MimeTypes.Html); req.Headers.Add("Sec-WebSocket-Version", "13"); req.Headers.Add("Origin", "null"); req.Headers.Add("Sec-WebSocket-Key", requestKey); req.Headers.Add("Connection", "keep-alive, Upgrade"); req.Headers.Add("Pragma", "no-cache"); req.Headers.Add("Cache-Control", "no-cache"); req.Headers.Add("Upgrade", "websocket"); StringWriter tmpWriter = new StringWriter(); tmpWriter.WriteLine($"{req.Method} {req.RequestUri!.PathAndQuery} HTTP/1.1"); tmpWriter.WriteLine(req.Headers.ToString()); await LowerStream.WriteAsync(tmpWriter.ToString()._GetBytes_UTF8(), cancel); Dictionary <string, string> headers = new Dictionary <string, string>(StrComparer.IgnoreCaseComparer); int num = 0; int responseCode = 0; StreamReader tmpReader = new StreamReader(LowerStream); while (true) { string?line = await TaskUtil.DoAsyncWithTimeout((procCancel) => tmpReader.ReadLineAsync(), timeout : Options.TimeoutOpen, cancel : cancel); if (line._IsNullOrZeroLen()) { break; } if (num == 0) { string[] tokens = line.Split(' '); if (tokens[0] != "HTTP/1.1") { throw new ApplicationException($"Cannot establish the WebSocket Protocol. Response: \"{tokens}\""); } responseCode = int.Parse(tokens[1]); } else { string[] tokens = line.Split(':'); string name = tokens[0].Trim(); string value = tokens[1].Trim(); headers[name] = value; } num++; } if (responseCode != 101) { throw new ApplicationException($"Cannot establish the WebSocket Protocol. Perhaps the destination host does not support WebSocket. Wrong response code: \"{responseCode}\""); } if (headers["Upgrade"].Equals("websocket", StringComparison.InvariantCultureIgnoreCase) == false) { throw new ApplicationException($"Wrong Upgrade header: \"{headers["Upgrade"]}\""); } string acceptKey = headers["Sec-WebSocket-Accept"]; string keyCalcStr = requestKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; SHA1 sha1 = SHA1.Create(); string acceptKey2 = Convert.ToBase64String(sha1.ComputeHash(keyCalcStr._GetBytes_Ascii())); if (acceptKey != acceptKey2) { throw new ApplicationException($"Wrong accept_key: \'{acceptKey}\'"); } this.SendTask = SendLoopAsync(); this.RecvTask = RecvLoopAsync(); }