public void WsConnect() { if (Ws_Button == "connect") { WebSocketHelper1 = new WebSocketHelper(Ws_URL, (BwsTransportType)(TransportCode)) { DoLog = false, OnStateChange = WsOnStateChange, OnMessage = WsOnMessage, OnError = WsOnError }; IsDisabled = false; log = new List <BwsMessage>(); Ws_Button = "disconnect"; } else { WebSocketHelper1.Close(); IsDisabled = true; Ws_Button = "connect"; log = new List <BwsMessage>(); } }
public async Task Run(WebSocket socket, CancellationToken ct) { _socket = socket; while (await WebSocketHelper.ReadFrame(socket, ct) is Frame frame) { if (_processors.TryGetValue(frame.Scope, out var processor)) { if (this.Log().IsEnabled(LogLevel.Trace)) { this.Log().LogTrace($"Received Frame [{frame.Scope} / {frame.Name}]"); } await processor.ProcessFrame(frame); } else { if (this.Log().IsEnabled(LogLevel.Trace)) { this.Log().LogTrace($"Unknown Frame [{frame.Scope} / {frame.Name}]"); } } } }
public override async Task OnMessageReceiced(WebSocketHelper webSocketHandler, ReceivedMessage receivedMessage, string originalData) { if (receivedMessage == null || string.IsNullOrEmpty(receivedMessage.Message)) { return; } var message = receivedMessage.Message; await webSocketHandler.SendMessage("originalData:" + originalData, webSocketHandler.WebSocket.Clients.Caller); await webSocketHandler.SendMessage("您发送了文字:" + message, webSocketHandler.WebSocket.Clients.Caller); await webSocketHandler.SendMessage("正在处理中(反转文字)...", webSocketHandler.WebSocket.Clients.Caller); await Task.Delay(1000); //处理文字 var result = string.Concat(message.Reverse()); await webSocketHandler.SendMessage(result, webSocketHandler.WebSocket.Clients.Caller); var appId = Config.SenparcWeixinSetting.WxOpenAppId;//与微信小程序账号后台的AppId设置保持一致,区分大小写。 try { var sessionBag = SessionContainer.GetSession(receivedMessage.SessionId ?? "-"); //临时演示使用固定openId var openId = sessionBag != null ? sessionBag.OpenId : receivedMessage.SessionId;// "用户未正确登陆小程序,或是在网页上发起"; openId = openId ?? "[未登录用户]"; //await webSocketHandler.SendMessage("OpenId:" + openId, webSocketHandler.WebSocket.Clients.Caller); //await webSocketHandler.SendMessage("FormId:" + formId); //群发 var shotOpenId = openId.Length > 10 ? $"***{openId.Substring(openId.Length - 10, 10)}" : openId; await webSocketHandler.SendMessage($"[群发消息] [来自 OpenId:{shotOpenId},昵称:{(sessionBag?.DecodedUserInfo?.nickName)??"[未登录]"}]:{message}", webSocketHandler.WebSocket.Clients.All); //发送模板消息 //var data = new WxOpenTemplateMessage_PaySuccessNotice( // "在线购买", SystemTime.Now, "图书众筹", "1234567890", // 100, "400-9939-858", "http://sdk.senparc.weixin.com"); if (sessionBag != null) { var formId = receivedMessage.FormId;//发送模板消息使用,需要在wxml中设置<form report-submit="true"> var data = new { keyword1 = new TemplateDataItem("来自小程序WebSocket的模板消息(测试数据)"), keyword2 = new TemplateDataItem(SystemTime.Now.LocalDateTime.ToString()), keyword3 = new TemplateDataItem($"来自 Senparc.Weixin SDK 小程序 .Net Core WebSocket 触发\r\n您刚才发送了文字:{message}"), keyword4 = new TemplateDataItem(SystemTime.NowTicks.ToString()), keyword5 = new TemplateDataItem(100.ToString("C")), keyword6 = new TemplateDataItem("400-031-8816"), }; var tmResult = Senparc.Weixin.WxOpen.AdvancedAPIs.Template.TemplateApi.SendTemplateMessage(appId, openId, "Ap1S3tRvsB8BXsWkiILLz93nhe7S8IgAipZDfygy9Bg", data, receivedMessage.FormId, "pages/websocket/websocket", "websocket", null); } } catch (Exception ex) { var msg = ex.Message + "\r\n\r\n" + originalData + "\r\n\r\nAPPID:" + appId; await webSocketHandler.SendMessage(msg, webSocketHandler.WebSocket.Clients.Caller); //VS2017以下如果编译不通过,可以注释掉这一行 WeixinTrace.SendCustomLog("WebSocket OnMessageReceiced()过程出错", msg); } }
public static async Task HandlerAsync(HttpContext context) { var url = context.Request.Headers[CustomHttpHeaders.RTVSRequestedURL]; using (var client = new HttpClient()) { if (context.WebSockets.IsWebSocketRequest) { var ub = new UriBuilder(url) { Scheme = "ws" }; var clientWebsocket = new ClientWebSocket(); foreach (var subProtocol in context.WebSockets.WebSocketRequestedProtocols) { clientWebsocket.Options.AddSubProtocol(subProtocol); } clientWebsocket.Options.KeepAliveInterval = TimeSpan.FromMinutes(10); await clientWebsocket.ConnectAsync(ub.Uri, CancellationToken.None); var serverWebSocket = await context.WebSockets.AcceptWebSocketAsync(); await WebSocketHelper.SendReceiveAsync(serverWebSocket, clientWebsocket, CancellationToken.None); } else { var request = new HttpRequestMessage(new HttpMethod(context.Request.Method), url); foreach (var requestHeader in context.Request.Headers) { IEnumerable <string> value = requestHeader.Value; request.Headers.Add(requestHeader.Key, value); } if (context.Request.ContentLength > 0) { using (var reqStream = await request.Content.ReadAsStreamAsync()) { await context.Request.Body.CopyToAsync(reqStream); await reqStream.FlushAsync(); } } using (var response = await client.SendAsync(request)) { context.Response.StatusCode = (int)response.StatusCode; foreach (var responseHeader in context.Response.Headers) { IEnumerable <string> value = responseHeader.Value; response.Headers.Add(responseHeader.Key, value); } using (var respStream = await response.Content.ReadAsStreamAsync()) { await respStream.CopyToAsync(context.Response.Body); await context.Response.Body.FlushAsync(); } } } } }
public MappableDeviceClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper, string apiUrl) : base(messageReader, messageWriter, webSocketHelper) { uri = new Uri(apiUrl + "/ws/mappableDevice"); }
public override Task OnConnecting(WebSocketHelper webSocketHandler) { //TODO:处理连接时的逻辑 return(base.OnConnecting(webSocketHandler)); }
public override async Task OnMessageReceiced(WebSocketHelper webSocketHandler, ReceivedMessage receivedMessage, string originalData) { if (receivedMessage == null || string.IsNullOrEmpty(receivedMessage.Message)) { return; } var message = receivedMessage.Message; await webSocketHandler.SendMessage("originalData:" + originalData); await webSocketHandler.SendMessage("您发送了文字:" + message); await webSocketHandler.SendMessage("正在处理中..."); await Task.Delay(1000); //处理文字 var result = string.Concat(message.Reverse()); await webSocketHandler.SendMessage(result); #if NET45 var appId = Config.SenparcWeixinSetting.WxOpenAppId; //与微信小程序账号后台的AppId设置保持一致,区分大小写。 #else var appId = "WxOpenAppId"; //与微信小程序账号后台的AppId设置保持一致,区分大小写。 #endif try { //发送模板消息 var formId = receivedMessage.FormId;//发送模板消息使用,需要在wxml中设置<form report-submit="true"> var sessionBag = SessionContainer.GetSession(receivedMessage.SessionId); //临时演示使用固定openId var openId = sessionBag != null ? sessionBag.OpenId : "onh7q0DGM1dctSDbdByIHvX4imxA";// "用户未正确登陆"; await webSocketHandler.SendMessage("OpenId:" + openId); //await webSocketHandler.SendMessage("FormId:" + formId); if (sessionBag == null) { openId = "onh7q0DGM1dctSDbdByIHvX4imxA";//临时测试 } //var data = new WxOpenTemplateMessage_PaySuccessNotice( // "在线购买", SystemTime.Now, "图书众筹", "1234567890", // 100, "400-9939-858", "http://sdk.senparc.weixin.com"); var data = new { keyword1 = new TemplateDataItem("来自小程序WebSocket的模板消息"), keyword2 = new TemplateDataItem(SystemTime.Now.LocalDateTime.ToString()), keyword3 = new TemplateDataItem("Name"), keyword4 = new TemplateDataItem("Number"), keyword5 = new TemplateDataItem(100.ToString("C")), keyword6 = new TemplateDataItem("400-031-8816"), }; var tmResult = Senparc.Weixin.WxOpen.AdvancedAPIs.Template.TemplateApi.SendTemplateMessage(appId, openId, "Ap1S3tRvsB8BXsWkiILLz93nhe7S8IgAipZDfygy9Bg", data, receivedMessage.FormId, "pages/websocket/websocket", "websocket", null); } catch (Exception ex) { var msg = ex.Message + "\r\n\r\n" + originalData + "\r\n\r\nAPPID:" + appId; await webSocketHandler.SendMessage(msg); //VS2017以下如果编译不通过,可以注释掉这一行 WeixinTrace.SendCustomLog("WebSocket OnMessageReceiced()过程出错", msg); } }
public static async Task HandlerAsync(HttpContext context) { var url = context.Request.Headers[CustomHttpHeaders.RTVSRequestedURL]; using (var client = new HttpClient()) { if (context.WebSockets.IsWebSocketRequest) { var ub = new UriBuilder(url) { Scheme = "ws" }; var request = new HttpRequestMessage(new HttpMethod(context.Request.Method), ub.Uri); string subProtocols = string.Join(", ", context.WebSockets.WebSocketRequestedProtocols); request.Headers.Add(Constants.Headers.SecWebSocketVersion, Constants.Headers.SupportedVersion); if (!string.IsNullOrWhiteSpace(subProtocols)) { request.Headers.Add(Constants.Headers.SecWebSocketProtocol, subProtocols); } var response = await client.SendAsync(request); HttpStatusCode statusCode = response.StatusCode; if (statusCode != HttpStatusCode.SwitchingProtocols) { response.Dispose(); } else { string respSubProtocol = response.Headers.GetValues(Constants.Headers.SecWebSocketProtocol).FirstOrDefault(); // TODO: match sub protocols. var responseStream = await response.Content.ReadAsStreamAsync(); var clientWebsocket = CommonWebSocket.CreateClientWebSocket(responseStream, respSubProtocol, TimeSpan.FromMinutes(2), receiveBufferSize: 1024 * 16, useZeroMask: false); var serverWebSocket = await context.WebSockets.AcceptWebSocketAsync(); await WebSocketHelper.SendReceiveAsync(serverWebSocket, clientWebsocket, CancellationToken.None); } } else { var request = new HttpRequestMessage(new HttpMethod(context.Request.Method), url); foreach (var requestHeader in context.Request.Headers) { IEnumerable <string> value = requestHeader.Value; request.Headers.Add(requestHeader.Key, value); } if (context.Request.ContentLength > 0) { using (Stream reqStream = await request.Content.ReadAsStreamAsync()) { await context.Request.Body.CopyToAsync(reqStream); await reqStream.FlushAsync(); } } using (var response = await client.SendAsync(request)) { context.Response.StatusCode = (int)response.StatusCode; foreach (var responseHeader in context.Response.Headers) { IEnumerable <string> value = responseHeader.Value; response.Headers.Add(responseHeader.Key, value); } using (var respStream = await response.Content.ReadAsStreamAsync()) { await respStream.CopyToAsync(context.Response.Body); await context.Response.Body.FlushAsync(); } } } } }
public async Task OpenAsync(string uri) { if (Opened) { throw new ApplicationException("WebSocket is already opened."); } Uri u = new Uri(uri); HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, uri); byte[] nonce = new byte[16]; new Random().NextBytes(nonce); string requestKey = Convert.ToBase64String(nonce); req.Headers.Add("Host", u.Host); req.Headers.Add("User-Agent", UserAgent); req.Headers.Add("Accept", "text/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 st.WriteAsyncWithTimeout(tmpWriter.AsciiToByteArray(), timeout : this.TimeoutOpen, cancel : this.Cancel); Dictionary <string, string> headers = new Dictionary <string, string>(); int num = 0; int responseCode = 0; StreamReader tmpReader = new StreamReader(st); while (true) { string line = await WebSocketHelper.DoAsyncWithTimeout((procCancel) => tmpReader.ReadLineAsync(), timeout : this.TimeoutOpen, cancel : this.Cancel); if (line == "") { 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 = new SHA1Managed(); string acceptKey2 = Convert.ToBase64String(sha1.ComputeHash(keyCalcStr.AsciiToByteArray())); if (acceptKey != acceptKey2) { throw new ApplicationException($"Wrong accept_key: \'{acceptKey}\'"); } Opened = true; }
public InputDeviceFeedbackClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper, Uri baseUri) : base(messageReader, messageWriter, webSocketHelper, baseUri) { }
public WebSocketClientFrame() { this.MaskingKey = WebSocketHelper.CreateMaskingKey(); this.IsMasked = true; }
public override async Task OnMessageReceiced(WebSocketHelper webSocketHandler, ReceivedMessage receivedMessage, string originalData) { if (receivedMessage == null || string.IsNullOrEmpty(receivedMessage.Message)) { return; } var message = receivedMessage.Message; await webSocketHandler.SendMessage("originalData:" + originalData); await webSocketHandler.SendMessage("您发送了文字:" + message); await webSocketHandler.SendMessage("正在处理中..."); await Task.Delay(1000); //处理文字 var result = string.Concat(message.Reverse()); await webSocketHandler.SendMessage(result); try { //发送模板消息 var formId = receivedMessage.FormId;//发送模板消息使用,需要在wxml中设置<form report-submit="true"> var sessionBag = SessionContainer.GetSession(receivedMessage.SessionId); //临时演示使用固定openId var openId = sessionBag != null ? sessionBag.OpenId : "onh7q0DGM1dctSDbdByIHvX4imxA";// "用户未正确登陆"; await webSocketHandler.SendMessage("OpenId:" + openId); //await webSocketHandler.SendMessage("FormId:" + formId); if (sessionBag == null) { openId = "onh7q0DGM1dctSDbdByIHvX4imxA";//临时测试 } //var data = new WxOpenTemplateMessage_PaySuccessNotice( // "在线购买", DateTime.Now, "图书众筹", "1234567890", // 100, "400-9939-858", "http://sdk.senparc.weixin.com"); var data = new { keyword1 = new TemplateDataItem("ADD"), keyword2 = new TemplateDataItem(DateTime.Now.ToString()), keyword3 = new TemplateDataItem("Name"), keyword4 = new TemplateDataItem("Number"), keyword5 = new TemplateDataItem(100.ToString("C")), keyword6 = new TemplateDataItem("400-9939-858"), }; var appId = WebConfigurationManager.AppSettings["WxOpenAppId"];//与微信小程序账号后台的AppId设置保持一致,区分大小写。 var tmResult = Senparc.Weixin.WxOpen.AdvancedAPIs.Template.TemplateApi.SendTemplateMessage(appId, openId, "Oc7R_U_23T8DtVgWn3d__-WkIctx_yDWTg8_4Mx8wgY", data, receivedMessage.FormId, null, null); } catch (Exception ex) { webSocketHandler.SendMessage(ex.Message + "\r\n\r\n" + originalData + "\r\n\r\nAPPID:" + WebConfigurationManager.AppSettings["WxOpenAppId"]); } }
private byte[] Synthesis(EdgeTTSSettings settings, string text) { var ws = ObtainConnection(); if (ws == null) { // Cancelled return(null); } lock (ws) { // Send request var requestId = Guid.NewGuid().ToString().Replace("-", ""); var timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffK"); try { ws.SendText( "Path:speech.config\r\n" + $"X-RequestId:{requestId}\r\n" + $"X-Timestamp:{timestamp}\r\n" + "Content-Type:application/json\r\n" + "\r\n" + "{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{\"sentenceBoundaryEnabled\":\"false\",\"wordBoundaryEnabled\":\"false\"},\"outputFormat\":\"audio-24khz-48kbitrate-mono-mp3\"}}}}\r\n", _wsCancellationSource ); ws.SendText( "Path:ssml\r\n" + $"X-RequestId:{requestId}\r\n" + $"X-Timestamp:{timestamp}\r\n" + "Content-Type:application/ssml+xml\r\n" + "\r\n" + "<speak xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"http://www.w3.org/2001/mstts\" xmlns:emo=\"http://www.w3.org/2009/10/emotionml\" version=\"1.0\" xml:lang=\"en-US\">" + $"<voice name=\"{settings.Voice}\">" + $"<prosody rate=\"{settings.Speed - 100}%\" pitch=\"{(settings.Pitch - 100) / 2}%\" volume=\"{settings.Volume.Clamp(1, 100)}\">" + text + "</prosody></voice></speak>\r\n", _wsCancellationSource ); } catch (Exception) { ws.Abort(); ws.Dispose(); throw; } // Start receiving var buffer = new MemoryStream(); var session = new WebSocketHelper.Session(ws); var state = ProtocolState.NotStarted; while (true) { var message = WebSocketHelper.ReceiveNextMessage(session, _wsCancellationSource); Logger.Debug($"Received WS message\n{message}"); if (message.Type == WebSocketMessageType.Text) { if (message.MessageStr.Contains(requestId)) { switch (state) { case ProtocolState.NotStarted: if (message.MessageStr.Contains("Path:turn.start")) { state = ProtocolState.TurnStarted; } break; case ProtocolState.TurnStarted: if (message.MessageStr.Contains("Path:turn.end")) { throw new IOException("Unexpected turn.end"); } else if (message.MessageStr.Contains("Path:turn.start")) { throw new IOException("Turn already started"); } break; case ProtocolState.Streaming: if (message.MessageStr.Contains("Path:turn.end")) { // All done return(buffer.ToArray()); } else { throw new IOException($"Unexpected message during streaming: {message.MessageStr}"); } default: throw new ArgumentOutOfRangeException(); } } else { if (state != ProtocolState.NotStarted) { throw new IOException("Unexpected request id during streaming"); } else { // Ignore } } } else if (message.Type == WebSocketMessageType.Binary) { switch (state) { case ProtocolState.NotStarted: // Do nothing break; case ProtocolState.TurnStarted: case ProtocolState.Streaming: // Parsing message // The first 2 bytes are the header length if (message.MessageBinary.Length < 2) { throw new IOException("Message too short"); } var headerLen = (message.MessageBinary[0] << 8) + message.MessageBinary[1]; if (message.MessageBinary.Length < 2 + headerLen) { throw new IOException("Message too short"); } var header = Encoding.UTF8.GetString(message.MessageBinary, 2, headerLen); if (header.EndsWith("Path:audio\r\n")) { if (!header.Contains(requestId)) { throw new IOException("Unexpected request id during streaming"); } state = ProtocolState.Streaming; buffer.Write(message.MessageBinary, 2 + headerLen, message.MessageBinary.Length - 2 - headerLen); } else { Logger.Warn($"Unexpected message with header {header}"); } break; default: throw new ArgumentOutOfRangeException(); } } else if (message.Type == WebSocketMessageType.Close) { throw new IOException("Unexpected closing of connection"); } else { throw new ArgumentOutOfRangeException(); } } } }
private byte[] Synthesis(XfyunTTSSettings settings, string text) { var apiSecret = settings.ApiSecret; var apiKey = settings.ApiKey; var appId = settings.AppId; if (string.IsNullOrEmpty(apiKey) || string.IsNullOrEmpty(apiSecret) || string.IsNullOrEmpty(appId)) { Logger.Error(strings.msgErrorEmptyApiSecretKey); _settingsControl.NotifyEmptyApiKey(); return(null); } var base64Text = Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); if (base64Text.Length > 8000) { Logger.Error("Convert string too long. No more than 2000 chinese characters."); return(null); } using (var ws = SystemClientWebSocket.CreateClientWebSocket()) { // Connect var date = DateTime.UtcNow.ToString("R"); var sign = $"host: tts-api.xfyun.cn\ndate: {date}\nGET /v2/tts HTTP/1.1"; string sha; using (var hash = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret))) { sha = Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(sign))); hash.Clear(); } var authorization = $"api_key=\"{apiKey}\"," + $" algorithm=\"hmac-sha256\"," + $" headers=\"host date request-line\"," + $" signature=\"{sha}\""; var url = $"wss://tts-api.xfyun.cn/v2/tts?host=tts-api.xfyun.cn" + $"&date={WebUtility.UrlEncode(date).Replace("+", "%20")}" + $"&authorization={Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization))}"; try { ws.ConnectAsync(new Uri(url), _wsCancellationSource.Token).Wait(); } catch (AggregateException e) { var inner = e.InnerExceptions.First().GetBaseException(); if (inner is WebException webException) { var resp = (HttpWebResponse)webException.Response; string body = null; using (var stream = resp.GetResponseStream()) { if (stream != null) { var reader = new StreamReader(stream, string.IsNullOrEmpty(resp.CharacterSet) ? Encoding.UTF8 : Encoding.GetEncoding(resp.CharacterSet)); body = reader.ReadToEnd(); } } Logger.Error($"Unable to connect to server: {body}"); switch (resp.StatusCode) { case HttpStatusCode.Unauthorized: case HttpStatusCode.Forbidden: Logger.Error(strings.msgErrorXfyunAuthFail); return(null); } } throw; } // Send request var request = new TTSRequest { Common = new TTSRequest.CommonParam { AppId = settings.AppId, }, Business = new TTSRequest.BusinessParam { Voice = settings.Voice, Pitch = settings.Pitch * 10, Speed = settings.Speed * 10, Volume = settings.Volume * 10, }, Data = new TTSRequest.DataParam { Status = 2, Text = base64Text, } }; ws.SendText(JsonConvert.SerializeObject(request), _wsCancellationSource); // Start receiving var buffer = new MemoryStream(); var session = new WebSocketHelper.Session(ws); while (true) { var message = WebSocketHelper.ReceiveNextMessage(session, _wsCancellationSource); Logger.Debug($"Received WS message\n{message}"); if (message.Type == WebSocketMessageType.Text) { var resp = JsonConvert.DeserializeObject <TTSResponse>(message.MessageStr); if (resp.Code == 0) { // Success! if (resp.Data != null) { var data = Convert.FromBase64String(resp.Data.Audio); buffer.Write(data, 0, data.Length); if (resp.Data.Status == 2) { // Complete! return(buffer.ToArray()); } } } else { Logger.Error($"Unexpected response code received: {resp.Code}: {resp.Message}"); switch (resp.Code) { case 10005: case 10313: Logger.Error(strings.msgErrorXfyunWrongAppId); break; case 11200: case 11201: Logger.Error(strings.msgErrorXfyunInsufficientApiQuota); break; } return(null); } } else if (message.Type == WebSocketMessageType.Binary) { throw new IOException("Unexpected binary message received"); } else if (message.Type == WebSocketMessageType.Close) { throw new IOException("Unexpected closing of connection"); } else { throw new ArgumentOutOfRangeException(); } } } }
protected WebsocketJsonClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper, ClientWebSocket client) { this.messageReader = messageReader; this.messageWriter = messageWriter; this.webSocketHelper = webSocketHelper; this.client = client; }
protected WebsocketJsonClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper) { this.messageReader = messageReader; this.messageWriter = messageWriter; this.webSocketHelper = webSocketHelper; client = new ClientWebSocket(); }
public static async Task HandlerAsync(HttpContext context) { var url = context.Request.Headers[CustomHttpHeaders.RTVSRequestedURL]; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = context.Request.Method; if (context.WebSockets.IsWebSocketRequest) { UriBuilder ub = new UriBuilder(url) { Scheme = "ws" }; ClientWebSocket clientWebsocket = new ClientWebSocket(); await clientWebsocket.ConnectAsync(ub.Uri, CancellationToken.None); var serverWebSocket = await context.WebSockets.AcceptWebSocketAsync(string.Join(", ", context.WebSockets.WebSocketRequestedProtocols)); await WebSocketHelper.SendReceiveAsync(serverWebSocket, clientWebsocket, CancellationToken.None); } else { SetRequestHeaders(request, context.Request.Headers); if (context.Request.ContentLength > 0) { using (Stream reqStream = await request.GetRequestStreamAsync()) { await context.Request.Body.CopyToAsync(reqStream); await reqStream.FlushAsync(); } } HttpWebResponse response = null; try { response = (HttpWebResponse)await request.GetResponseAsync(); } catch (WebException wex) { if (wex.Status == WebExceptionStatus.ProtocolError) { response = wex.Response as HttpWebResponse; } else { throw wex; } } finally { if (response != null) { context.Response.StatusCode = (int)response.StatusCode; SetResponseHeaders(response, context.Response); using (Stream respStream = response.GetResponseStream()) { await respStream.CopyToAsync(context.Response.Body); await context.Response.Body.FlushAsync(); } response.Close(); } } } }
public async Task GetResponseAsync(HttpListenerContext context, string localBaseUrl, string remoteBaseUrl, CancellationToken ct) { string postUri = null; if (context.Request.IsWebSocketRequest) { UriBuilder ub = new UriBuilder(PostUri) { Scheme = "wss" }; postUri = ub.Uri.ToString(); } else { postUri = PostUri.ToString(); } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUri); request.Method = context.Request.HttpMethod; request.ServerCertificateValidationCallback += ValidateCertificate; if (!context.Request.IsWebSocketRequest) { SetRequestHeaders(request, context.Request.Headers, localBaseUrl, remoteBaseUrl); } // Add RTVS headers var remoteUri = GetRemoteUri(context.Request.Url, remoteBaseUrl); request.Headers.Add(CustomHttpHeaders.RTVSRequestedURL, remoteUri.ToString()); if (context.Request.ContentLength64 > 0) { using (Stream reqStream = await request.GetRequestStreamAsync()) { await context.Request.InputStream.CopyAndFlushAsync(reqStream, null, ct); } } HttpWebResponse response = null; try { response = (HttpWebResponse)await request.GetResponseAsync(); if (response != null) { if (context.Request.IsWebSocketRequest && response.StatusCode == HttpStatusCode.SwitchingProtocols) { Stream respStream = response.GetResponseStream(); string subProtocol = response.Headers[Constants.Headers.SecWebSocketProtocol]; var remoteWebSocket = CommonWebSocket.CreateClientWebSocket(respStream, subProtocol, TimeSpan.FromMinutes(10), receiveBufferSize: 65335, useZeroMask: true); var websocketContext = await context.AcceptWebSocketAsync(subProtocol, receiveBufferSize : 65335, keepAliveInterval : TimeSpan.FromMinutes(10)); await WebSocketHelper.SendReceiveAsync(websocketContext.WebSocket, remoteWebSocket, ct); } else { context.Response.StatusCode = (int)response.StatusCode; SetResponseHeaders(response, context.Response, localBaseUrl, remoteBaseUrl); using (Stream respStream = response.GetResponseStream()) using (Stream outStream = context.Response.OutputStream) { await respStream.CopyAndFlushAsync(outStream, null, ct); } response.Close(); } } } catch (WebException wex) when(wex.Status == WebExceptionStatus.ProtocolError) { response = wex.Response as HttpWebResponse; } catch (OperationCanceledException) { WebServer.Stop(remoteUri.Port); } catch (Exception ex) when(!ex.IsCriticalException()) { _log.WriteLine(LogVerbosity.Normal, MessageCategory.Error, Resources.Error_RemoteWebServerException.FormatInvariant(ex.Message)); _console?.WriteErrorLine(Resources.Error_RemoteWebServerException.FormatInvariant(ex.Message)); WebServer.Stop(remoteUri.Port); } finally { response?.Close(); } }
public async Task ProcessRequest(AspNetWebSocketContext context) { var socket = context.WebSocket; //传入的context中有当前的web socket对象 _sockets.Add(socket); //此处将web socket对象加入一个静态列表中 string connectionId = context.AnonymousID; //string code = context.QueryString["code"]; string strategy_id = context.QueryString["strategy_id"]; string time = context.QueryString["time"]; string user_id = context.QueryString["user_id"]; // backtest item int data_id = 1; var sy = ""; var nsy = ""; var hc = ""; var xp = ""; string report_path = ""; DateTime dt = DateTime.ParseExact(time, "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); string new_time = dt.ToString("yyyyMMddHHmmss"); string origin_time = dt.ToString("yyyy-MM-dd HH:mm:ss"); StringBuilder sb = new StringBuilder(); Convert(origin_time, sb); string new_time_2 = sb.ToString(); string path = common_path + @"\" + user_id; string file = new_time + ".py"; //utils.saveFile(code, path, file); utils.copyFile(path + @"\" + file, common_path + @"\" + file); // 回测 Task t = new Task(() => { string sArguments = common_path + @"\" + file; EngineRunner runner = new EngineRunner(user_id); runner.RunPythonScript(sArguments); }); t.Start(); byte[] bytes; ArraySegment <byte> buffer; var topic = user_id; using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect("tcp://*****:*****@"\" + backtest_id + @".docx"; WordFileOperator.CreateReport(code, time, file_path); //进入一个无限循环,当web socket close时循环结束 while (true) { //var buffer = new ArraySegment<byte>(new byte[1024]); var receivedResult = await socket.ReceiveAsync(buffer, CancellationToken.None);//对web socket进行异步接收数据 if (receivedResult.MessageType == WebSocketMessageType.Close) { await socket.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, CancellationToken.None);//如果client发起close请求,对client进行ack _sockets.Remove(socket); break; } if (socket.State == System.Net.WebSockets.WebSocketState.Open) { string recvMsg = Encoding.UTF8.GetString(buffer.Array, 0, receivedResult.Count); var recvBytes = Encoding.UTF8.GetBytes(recvMsg); var sendBuffer = new ArraySegment <byte>(recvBytes); foreach (var innerSocket in _sockets)//当接收到文本消息时,对当前服务器上所有web socket连接进行广播 { if (innerSocket != socket) { await innerSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None); } } } } } }
public override Task OnDisConnected(WebSocketHelper webSocketHandler) { return(null); }
public async Task GetResponseAsync(HttpListenerContext context, string localBaseUrl, string remoteBaseUrl, CancellationToken ct) { string postUri = null; if (context.Request.IsWebSocketRequest) { UriBuilder ub = new UriBuilder(PostUri) { Scheme = "wss" }; postUri = ub.Uri.ToString(); } else { postUri = PostUri.ToString(); } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUri); request.Method = context.Request.HttpMethod; request.ServerCertificateValidationCallback += ValidateCertificate; if (!context.Request.IsWebSocketRequest) { SetRequestHeaders(request, context.Request.Headers, localBaseUrl, remoteBaseUrl); } // Add RTVS headers request.Headers.Add(CustomHttpHeaders.RTVSRequestedURL, GetRemoteUrl(context.Request.Url, remoteBaseUrl)); if (context.Request.InputStream.CanSeek && context.Request.InputStream.Length > 0) { using (Stream reqStream = await request.GetRequestStreamAsync()) { await context.Request.InputStream.CopyAndFlushAsync(reqStream); } } HttpWebResponse response = null; try { response = (HttpWebResponse)await request.GetResponseAsync(); } catch (WebException wex) { if (wex.Status == WebExceptionStatus.ProtocolError) { response = wex.Response as HttpWebResponse; } else { throw wex; } } finally { if (response != null) { if (context.Request.IsWebSocketRequest && response.StatusCode == HttpStatusCode.SwitchingProtocols) { Stream respStream = response.GetResponseStream(); string subProtocol = response.Headers[Constants.Headers.SecWebSocketProtocol]; var remoteWebSocket = CommonWebSocket.CreateClientWebSocket(respStream, subProtocol, TimeSpan.FromMinutes(10), receiveBufferSize: 65335, useZeroMask: true); var websocketContext = await context.AcceptWebSocketAsync(subProtocol, receiveBufferSize : 65335, keepAliveInterval : TimeSpan.FromMinutes(10)); await WebSocketHelper.SendReceiveAsync(websocketContext.WebSocket, remoteWebSocket, ct); } else { context.Response.StatusCode = (int)response.StatusCode; SetResponseHeaders(response, context.Response, localBaseUrl, remoteBaseUrl); using (Stream respStream = response.GetResponseStream()) using (Stream outStream = context.Response.OutputStream) { await respStream.CopyAndFlushAsync(outStream); } response.Close(); } } } }
public async Task <IActionResult> VaultBridgeConnection(string cryptoCode = null, [ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId = null) { if (!HttpContext.WebSockets.IsWebSocketRequest) { return(NotFound()); } cryptoCode = cryptoCode ?? walletId.CryptoCode; using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10))) { var cancellationToken = cts.Token; var network = Networks.GetNetwork <BTCPayNetwork>(cryptoCode); if (network == null) { return(NotFound()); } var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var hwi = new Hwi.HwiClient(network.NBitcoinNetwork) { Transport = new HwiWebSocketTransport(websocket) }; Hwi.HwiDeviceClient device = null; HwiEnumerateEntry deviceEntry = null; HDFingerprint? fingerprint = null; string password = null; int? pin = null; var websocketHelper = new WebSocketHelper(websocket); async Task <bool> RequireDeviceUnlocking() { if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); return(true); } if (deviceEntry.NeedsPinSent is true && pin is null) { await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken); return(true); } if (deviceEntry.NeedsPassphraseSent is true && password == null) { await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken); return(true); } return(false); } JObject o = null; try { while (true) { var command = await websocketHelper.NextMessageAsync(cancellationToken); switch (command) { case "set-passphrase": device.Password = await websocketHelper.NextMessageAsync(cancellationToken); password = device.Password; break; case "ask-sign": if (await RequireDeviceUnlocking()) { continue; } if (walletId == null) { await websocketHelper.Send("{ \"error\": \"invalid-walletId\"}", cancellationToken); continue; } if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken); o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); var authorization = await _authorizationService.AuthorizeAsync(User, Policies.CanModifyStoreSettings.Key); if (!authorization.Succeeded) { await websocketHelper.Send("{ \"error\": \"not-authorized\"}", cancellationToken); continue; } var psbt = PSBT.Parse(o["psbt"].Value <string>(), network.NBitcoinNetwork); var derivationSettings = GetDerivationSchemeSettings(walletId); derivationSettings.RebaseKeyPaths(psbt); var signing = derivationSettings.GetSigningAccountKeySettings(); if (signing.GetRootedKeyPath()?.MasterFingerprint != fingerprint) { await websocketHelper.Send("{ \"error\": \"wrong-wallet\"}", cancellationToken); continue; } try { psbt = await device.SignPSBTAsync(psbt, cancellationToken); } catch (Hwi.HwiException) { await websocketHelper.Send("{ \"error\": \"user-reject\"}", cancellationToken); continue; } o = new JObject(); o.Add("psbt", psbt.ToBase64()); await websocketHelper.Send(o.ToString(), cancellationToken); break; case "ask-pin": if (device == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); continue; } await device.PromptPinAsync(cancellationToken); await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken); pin = int.Parse(await websocketHelper.NextMessageAsync(cancellationToken), CultureInfo.InvariantCulture); if (await device.SendPinAsync(pin.Value, cancellationToken)) { await websocketHelper.Send("{ \"info\": \"the pin is correct\"}", cancellationToken); } else { await websocketHelper.Send("{ \"error\": \"incorrect-pin\"}", cancellationToken); continue; } break; case "ask-xpubs": if (await RequireDeviceUnlocking()) { continue; } JObject result = new JObject(); var factory = network.NBXplorerNetwork.DerivationStrategyFactory; var keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(0, true); BitcoinExtPubKey xpub = await device.GetXPubAsync(keyPath); if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } result["fingerprint"] = fingerprint.Value.ToString(); var strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.Segwit }); AddDerivationSchemeToJson("segwit", result, keyPath, xpub, strategy); keyPath = new KeyPath("49'").Derive(network.CoinType).Derive(0, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.SegwitP2SH }); AddDerivationSchemeToJson("segwitWrapped", result, keyPath, xpub, strategy); keyPath = new KeyPath("44'").Derive(network.CoinType).Derive(0, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.Legacy }); AddDerivationSchemeToJson("legacy", result, keyPath, xpub, strategy); await websocketHelper.Send(result.ToString(), cancellationToken); break; case "ask-device": password = null; pin = null; deviceEntry = null; device = null; var entries = (await hwi.EnumerateEntriesAsync(cancellationToken)).ToList(); deviceEntry = entries.FirstOrDefault(); if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken); continue; } device = new HwiDeviceClient(hwi, deviceEntry.DeviceSelector, deviceEntry.Model, deviceEntry.Fingerprint); fingerprint = device.Fingerprint; JObject json = new JObject(); json.Add("model", device.Model.ToString()); json.Add("fingerprint", device.Fingerprint?.ToString()); await websocketHelper.Send(json.ToString(), cancellationToken); break; } } } catch (Exception ex) { JObject obj = new JObject(); obj.Add("error", "unknown-error"); obj.Add("details", ex.ToString()); try { await websocketHelper.Send(obj.ToString(), cancellationToken); } catch { } } finally { await websocketHelper.DisposeAsync(cancellationToken); } } return(new EmptyResult()); }
public override Task OnConnecting(WebSocketHelper webSocketHandler) { return(null); }
protected override void OnStartup(StartupEventArgs e) { var isReStart = false; if (e.Args.CanBeCount()) { e.Args.ForEachOfUnNone(arg => { if (arg.StartsWith("restart")) { isReStart = true; } if (arg.StartsWith("kill")) { var opt = arg.Split(':'); int id; if (opt.Length == 2 && int.TryParse(opt[1], out id)) { var processes = Process.GetProcesses(); if (processes.Any(process => process.Id == id)) { Process.GetProcessById(id).Kill(); } } } if (arg.StartsWith("del")) { var opt = arg.Split(':'); if (opt.Length == 2) { DirectoryHelper.DeleteRecursive(opt[1]); } } }); } #region 判断是否重复运行(重启模式不再判断) if (!isReStart) { var currentProcess = Process.GetCurrentProcess(); var location = Assembly.GetExecutingAssembly().Location; foreach (var process in Process.GetProcessesByName(currentProcess.ProcessName)) { if (process.Id != currentProcess.Id && location == currentProcess.MainModule.FileName) { MessageBox.Show("Program is running."); SystemHelper.Exit(); return; } } } #endregion base.OnStartup(e); SystemHelper.InitIcon(this, Calibur.Properties.Resources.calibur); FiddlerHelper.Start(); WebSocketHelper.Start(); CaliburService.InitialEntry(); if (!isReStart) { Utilities.RunExecutable("Chrome", StorageHelper.AchiveValue("pageloading", "http://hellerz.github.io/hellerz/")); } }
public XboxDeviceClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper, Uri baseUri) : base(messageReader, messageWriter, webSocketHelper, baseUri) { }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, Microsoft.Extensions.Hosting.IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseWebSockets(); app.Use(async(context, next) => { if (context.Request.Path == "/ws") { if (context.WebSockets.IsWebSocketRequest) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); Console.WriteLine($"New Connection {context.Connection.RemoteIpAddress}"); var message = WebSocketHelper.GetMessage(webSocket).Result; var connectionmessage = message.Split(":"); switch (connectionmessage[0]) { case "Matlab": { var user = new Models.User(webSocket, Guid.NewGuid()); user._state = "Matlab"; Program.MatlabUser.Add(user); Console.WriteLine($"New Connected MatlabUser {context.Connection.RemoteIpAddress} " + user._guid); await user.Echo(); break; } case "Phone": { switch (connectionmessage[2]) { case "Relative": { var user = new Models.User(webSocket, connectionmessage[0], Guid.NewGuid(), connectionmessage[1], connectionmessage[2], connectionmessage[3]); Console.WriteLine($"New Connected Phone if relative mode {context.Connection.RemoteIpAddress} " + connectionmessage[1] + " " + connectionmessage[3]); Program.Users.Add(user); await user.Echo(); break; } case "StandAlone": { var user = new Models.User(webSocket, connectionmessage[0], Guid.NewGuid(), connectionmessage[1], connectionmessage[2], connectionmessage[3]); Program.Users.Add(user); Console.WriteLine($"New Connected Phone if StandAlone mode {context.Connection.RemoteIpAddress} " + connectionmessage[1] + " " + connectionmessage[3]); await user.Echo(); break; } } break; } } /*var user = new Models.User(webSocket, Guid.NewGuid()); * if (messageMass[0] == "State") * { * if (messageMass[1] == "Matlab") * { * user._state = "Matlab"; * Program.MatlabUser.Add(user); * Console.WriteLine($"New Connected MatlabUser {context.Connection.RemoteIpAddress} " + user._guid); * } * else if(messageMass[1] == "MainMatlabUser") * { * user._state = "Matlab"; * Program.MainMatlabUser = user; * Console.WriteLine($"New Connected MainMatlabUser {context.Connection.RemoteIpAddress} " + user._guid); * } * else if(messageMass[1] == "Phone") * { * user._model = messageMass[2]; * Program.Users.Add(user); * Console.WriteLine($"New Connected Phone {context.Connection.RemoteIpAddress} " + user._guid +" " + messageMass[2]); * //Console.WriteLine($"New Connected Phone {context.Connection.RemoteIpAddress} " + user._guid); * } * await user.Echo(); * } * else * { * await user.Echo(); * }*/ } else { context.Response.StatusCode = 400; } } else { await next(); } }); app.UseMvc(); }
public override Task OnDisConnected(WebSocketHelper webSocketHandler) { //TODO:处理断开连接时的逻辑 return(base.OnDisConnected(webSocketHandler)); }
static void BenchStreamBuffer() { FastStreamBuffer <byte> new_test_buf(int num = 1) { FastStreamBuffer <byte> ret = new FastStreamBuffer <byte>(); for (int i = 0; i < num; i++) { ret.Enqueue(new byte[] { 1, 2, 3, }); ret.Enqueue(new byte[] { 4, 5, 6, 7 }); ret.Enqueue(new byte[] { 8, 9, 10, 11, 12 }); ret.Enqueue(new byte[] { 13, 14, 15, 16, 17, 18 }); } return(ret); } MicroBenchmarkQueue q = new MicroBenchmarkQueue(); int num_test_data = 10000; object[] test_data_array = new object[num_test_data]; for (int i = 0; i < num_test_data; i++) { test_data_array[i] = new object(); } q.Add(new MicroBenchmark <int>("Queue insert test: .NET Queue", 10000, (x, iterations) => { Queue <object> queue = new Queue <object>(); for (int i = 0; i < iterations; i++) { foreach (object o in test_data_array) { queue.Enqueue(o); } } }, () => 0), true, 0); q.Add(new MicroBenchmark <int>("Queue insert test: Fifo<T>", 10000, (x, iterations) => { Fifo <object> fifo = new Fifo <object>(); var span = test_data_array.AsSpan(); for (int i = 0; i < iterations; i++) { fifo.Write(span); } }, () => 0), true, 0); q.Add(new MicroBenchmark <int>("InsertFirst", 1000, (x, iterations) => { List <int> rands = new List <int>(); for (int i = 0; i < 256; i++) { rands.Add(WebSocketHelper.RandSInt31()); } Memory <byte> add_data = new byte[] { 1, 2, 3, 4, 5, }; FastStreamBuffer <byte> buf = new_test_buf(); for (int i = 0; i < iterations; i++) { //buf.Insert(buf.PinHead + 0, add_data); buf.InsertHead(add_data); } }, () => 0), true, 0); q.Add(new MicroBenchmark <int>("InsertAndRemoveRandom", 10000, (x, iterations) => { List <int> rands = new List <int>(); for (int i = 0; i < 256; i++) { rands.Add(WebSocketHelper.RandSInt31()); } Memory <byte> add_data = new byte[] { 1, 2, 3, 4, 5, }; FastStreamBuffer <byte> buf = new_test_buf(); for (int i = 0; i < iterations; i++) { long pin = buf.PinHead + rands[i % rands.Count] % (buf.Length - add_data.Length); buf.Insert(pin, add_data); buf.Remove(pin, add_data.Length); } }, () => 0), true, 0); q.Add(new MicroBenchmark <int>("EnqueueAndDequeue", 10000, (x, iterations) => { List <int> rands = new List <int>(); for (int i = 0; i < 256; i++) { rands.Add(WebSocketHelper.RandSInt31()); } Memory <byte> add_data = new byte[] { 1, 2, 3, 4, 5, }; FastStreamBuffer <byte> buf = new_test_buf(); for (int i = 0; i < iterations; i++) { buf.Enqueue(add_data); var ret = buf.Dequeue(long.MaxValue, out _, false); } }, () => 0), true, 10); FastStreamBuffer <byte> bufx1 = new_test_buf(10000); FastStreamBuffer <byte> bufx2 = new_test_buf(10000); q.Add(new MicroBenchmark <int>("MoveToOtherEmpty", 100000, (x, iterations) => { for (int i = 0; i < iterations; i++) { bufx1.DequeueAllAndEnqueueToOther(bufx2); bufx2.DequeueAllAndEnqueueToOther(bufx1); } }, () => 0), true, 20); System.GC.Collect(); q.Add(new MicroBenchmark <int>("MoveToOtherNonEmpty", 1, (x, iterations) => { FastStreamBuffer <byte> buf1 = new_test_buf(10000); FastStreamBuffer <byte> buf2 = new_test_buf(10000); for (int i = 0; i < iterations; i++) { buf1.DequeueAllAndEnqueueToOther(buf2); } }, () => 0), true, 20); bool call_deque = true; long deque_max = 1; q.Add(new MicroBenchmark <int>("Datagram1_single_add", 10000, (x, iterations) => { FastDatagramBuffer <int> dg = new FastDatagramBuffer <int>(); for (int i = 0; i < iterations; i++) { dg.Enqueue(i); } if (call_deque) { for (int i = 0; i < iterations; i++) { var r = dg.Dequeue(deque_max, out long _); } } }, () => 0), true, 30); q.Add(new MicroBenchmark <int>("Datagram1_bulk_add", 10000, (x, iterations) => { FastDatagramBuffer <int> dg = new FastDatagramBuffer <int>(); int[] tmp = new int[100]; for (int i = 0; i < iterations; i++) { dg.EnqueueAll(tmp); } if (call_deque) { for (int i = 0; i < iterations; i++) { var r = dg.Dequeue(deque_max, out long _); } } }, () => 0), true, 30); q.Run(); }
public async Task <IActionResult> VaultBridgeConnection(string cryptoCode = null, [ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId = null) { if (!HttpContext.WebSockets.IsWebSocketRequest) { return(NotFound()); } cryptoCode = cryptoCode ?? walletId.CryptoCode; using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10))) { var cancellationToken = cts.Token; var network = Networks.GetNetwork <BTCPayNetwork>(cryptoCode); if (network == null) { return(NotFound()); } var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var hwi = new Hwi.HwiClient(network.NBitcoinNetwork) { Transport = new HwiWebSocketTransport(websocket) }; Hwi.HwiDeviceClient device = null; HwiEnumerateEntry deviceEntry = null; HDFingerprint? fingerprint = null; string password = null; bool pinProvided = false; var websocketHelper = new WebSocketHelper(websocket); async Task <bool> RequireDeviceUnlocking() { if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); return(true); } if (deviceEntry.Code is HwiErrorCode.DeviceNotInitialized) { await websocketHelper.Send("{ \"error\": \"need-initialized\"}", cancellationToken); return(true); } if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPinSent is true) && !pinProvided) { if (!IsTrezorT(deviceEntry)) { await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken); return(true); } else { try { // On trezor T this will prompt the password! (https://github.com/bitcoin-core/HWI/issues/283) await device.GetXPubAsync(new KeyPath("44'"), cancellationToken); } catch (HwiException ex) when(ex.ErrorCode == HwiErrorCode.DeviceAlreadyUnlocked) { pinProvided = true; } await websocketHelper.Send("{ \"error\": \"need-passphrase-on-device\"}", cancellationToken); return(true); } } if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPassphraseSent is true) && password == null) { if (IsTrezorT(deviceEntry)) { await websocketHelper.Send("{ \"error\": \"need-passphrase-on-device\"}", cancellationToken); } else { await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken); } return(true); } return(false); } JObject o = null; try { while (true) { var command = await websocketHelper.NextMessageAsync(cancellationToken); switch (command) { case "set-passphrase": device.Password = await websocketHelper.NextMessageAsync(cancellationToken); password = device.Password; break; case "ask-sign": if (await RequireDeviceUnlocking()) { continue; } if (walletId == null) { await websocketHelper.Send("{ \"error\": \"invalid-walletId\"}", cancellationToken); continue; } if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken); o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); var authorization = await _authorizationService.AuthorizeAsync(User, Policies.CanModifyStoreSettings.Key); if (!authorization.Succeeded) { await websocketHelper.Send("{ \"error\": \"not-authorized\"}", cancellationToken); continue; } var psbt = PSBT.Parse(o["psbt"].Value <string>(), network.NBitcoinNetwork); var derivationSettings = GetDerivationSchemeSettings(walletId); derivationSettings.RebaseKeyPaths(psbt); var signing = derivationSettings.GetSigningAccountKeySettings(); if (signing.GetRootedKeyPath()?.MasterFingerprint != fingerprint) { await websocketHelper.Send("{ \"error\": \"wrong-wallet\"}", cancellationToken); continue; } var signableInputs = psbt.Inputs .SelectMany(i => i.HDKeyPaths) .Where(i => i.Value.MasterFingerprint == fingerprint) .ToArray(); if (signableInputs.Length > 0) { var actualPubKey = (await device.GetXPubAsync(signableInputs[0].Value.KeyPath)).GetPublicKey(); if (actualPubKey != signableInputs[0].Key) { await websocketHelper.Send("{ \"error\": \"wrong-keypath\"}", cancellationToken); continue; } } try { psbt = await device.SignPSBTAsync(psbt, cancellationToken); } catch (Hwi.HwiException) { await websocketHelper.Send("{ \"error\": \"user-reject\"}", cancellationToken); continue; } o = new JObject(); o.Add("psbt", psbt.ToBase64()); await websocketHelper.Send(o.ToString(), cancellationToken); break; case "ask-pin": if (device == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); continue; } try { await device.PromptPinAsync(cancellationToken); } catch (HwiException ex) when(ex.ErrorCode == HwiErrorCode.DeviceAlreadyUnlocked) { pinProvided = true; await websocketHelper.Send("{ \"error\": \"device-already-unlocked\"}", cancellationToken); continue; } await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken); var pin = int.Parse(await websocketHelper.NextMessageAsync(cancellationToken), CultureInfo.InvariantCulture); if (await device.SendPinAsync(pin, cancellationToken)) { pinProvided = true; await websocketHelper.Send("{ \"info\": \"the pin is correct\"}", cancellationToken); } else { await websocketHelper.Send("{ \"error\": \"incorrect-pin\"}", cancellationToken); continue; } break; case "ask-xpub": if (await RequireDeviceUnlocking()) { continue; } await websocketHelper.Send("{ \"info\": \"ok\"}", cancellationToken); var askedXpub = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); var addressType = askedXpub["addressType"].Value <string>(); var accountNumber = askedXpub["accountNumber"].Value <int>(); JObject result = new JObject(); var factory = network.NBXplorerNetwork.DerivationStrategyFactory; if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } result["fingerprint"] = fingerprint.Value.ToString(); DerivationStrategyBase strategy = null; KeyPath keyPath = null; BitcoinExtPubKey xpub = null; if (!network.NBitcoinNetwork.Consensus.SupportSegwit && addressType != "legacy") { await websocketHelper.Send("{ \"error\": \"segwit-notsupported\"}", cancellationToken); continue; } if (addressType == "segwit") { keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.Segwit }); } else if (addressType == "segwitWrapped") { keyPath = new KeyPath("49'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.SegwitP2SH }); } else if (addressType == "legacy") { keyPath = new KeyPath("44'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.Legacy }); } else { await websocketHelper.Send("{ \"error\": \"invalid-addresstype\"}", cancellationToken); continue; } result.Add(new JProperty("strategy", strategy.ToString())); result.Add(new JProperty("accountKey", xpub.ToString())); result.Add(new JProperty("keyPath", keyPath.ToString())); await websocketHelper.Send(result.ToString(), cancellationToken); break; case "refresh-device": case "ask-device": DeviceSelector deviceSelector = (command == "refresh-device" && deviceEntry != null ? deviceEntry.DeviceSelector : null); password = null; pinProvided = false; deviceEntry = null; device = null; var entries = (await hwi.EnumerateEntriesAsync(cancellationToken)).ToList(); deviceEntry = entries.Where(h => deviceSelector == null || SameSelector(deviceSelector, h.DeviceSelector)).FirstOrDefault(); if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken); continue; } device = new HwiDeviceClient(hwi, deviceEntry.DeviceSelector, deviceEntry.Model, deviceEntry.Fingerprint); fingerprint = device.Fingerprint; JObject json = new JObject(); json.Add("model", device.Model.ToString()); json.Add("fingerprint", device.Fingerprint?.ToString()); await websocketHelper.Send(json.ToString(), cancellationToken); break; } } } catch (FormatException ex) { JObject obj = new JObject(); obj.Add("error", "invalid-network"); obj.Add("details", ex.ToString()); try { await websocketHelper.Send(obj.ToString(), cancellationToken); } catch { } } catch (Exception ex) { JObject obj = new JObject(); obj.Add("error", "unknown-error"); obj.Add("message", ex.Message); obj.Add("details", ex.ToString()); try { await websocketHelper.Send(obj.ToString(), cancellationToken); } catch { } } finally { await websocketHelper.DisposeAsync(cancellationToken); } } return(new EmptyResult()); }
public WebsocketXboxClient(MessageReader messageReader, MessageWriter messageWriter, WebSocketHelper webSocketHelper) : base(messageReader, messageWriter, webSocketHelper) { }