protected WebSocketWrapper(string uri) { _ws = new System.Net.WebSockets.Managed.ClientWebSocket(); _ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(20); _uri = new Uri(uri); _cancellationToken = _cancellationTokenSource.Token; }
static async Task TestConnection(string server) { using (var ws = new System.Net.WebSockets.Managed.ClientWebSocket()) { await ws.ConnectAsync(new Uri(server), CancellationToken.None); var buffer = new ArraySegment <byte>(new byte[1024]); var readTask = ws.ReceiveAsync(buffer, CancellationToken.None); const string msg = "hello"; var testMsg = new ArraySegment <byte>(Encoding.UTF8.GetBytes(msg)); await ws.SendAsync(testMsg, WebSocketMessageType.Text, true, CancellationToken.None); var read = await readTask; var reply = Encoding.UTF8.GetString(buffer.Array, 0, read.Count); if (reply != msg) { throw new Exception($"Expected to read back '{msg}' but got '{reply}' for server {server}"); } Console.WriteLine("Success connecting to server " + server); } }
public async Task <ResultModel <byte[]> > Convert(string data) { try { Status = ServiceStatus.Running; //BuildAuthUrl string host = ApiAuthorization.BuildAuthUrl(_settings); //Base64 convert string if (string.IsNullOrEmpty(data)) { throw new Exception("Convert data is null."); } string base64Text = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(data)); if (base64Text.Length > 8000) { throw new Exception("Convert string too long. No more than 2000 chinese characters."); } using (var ws = new ClientWebSocket()) { await ws.ConnectAsync(new Uri(host), CancellationToken.None); //接收数据 StartReceiving(ws); //Send data _data.text = base64Text; TTSFrameData frame = new TTSFrameData() { common = _common, business = _business, data = _data }; //string send = JsonHelper.SerializeObject(frame); await ws.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(frame))), WebSocketMessageType.Text, true, CancellationToken.None); while (Status == ServiceStatus.Running) { await Task.Delay(10); } //await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "NormalClosure", CancellationToken.None); //在Winform中会提示:调用 WebSocket.CloseAsync 后收到的消息类型“Text”无效。只有在不需要从远程终结点得到更多数据时,才应使用 WebSocket.CloseAsync。请改用“WebSocket.CloseOutputAsync”保持能够接收数据,但关闭输出通道。 await ws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "NormalClosure", CancellationToken.None); } return(new ResultModel <byte[]>() { Code = ResultCode.Success, Data = _result == null ? null : _result.ToArray(), }); } catch (Exception ex) { //服务器主动断开连接 if (ex.InnerException != null && ex.InnerException is SocketException && ((SocketException)ex.InnerException).SocketErrorCode == SocketError.ConnectionReset) { return(new ResultModel <byte[]>() { Code = ResultCode.Error, Message = "服务器主动断开连接,可能是整个会话是否已经超过了60s、读取数据超时等原因引起的。", }); } else { return(new ResultModel <byte[]>() { Code = ResultCode.Error, Message = ex.Message, }); } } }
private async void StartReceiving(ClientWebSocket client) { if (_result != null) { _result.Clear(); } //单次完整数据 string msg = ""; while (true) { try { if (client.CloseStatus == WebSocketCloseStatus.EndpointUnavailable || client.CloseStatus == WebSocketCloseStatus.InternalServerError || client.CloseStatus == WebSocketCloseStatus.EndpointUnavailable) { Status = ServiceStatus.Stopped; return; } //唔,足够大的缓冲区 var array = new byte[100000]; var receive = await client.ReceiveAsync(new ArraySegment <byte>(array), CancellationToken.None); if (receive.MessageType == WebSocketMessageType.Text) { if (receive.Count <= 0) { continue; } //string msg = Encoding.UTF8.GetString(array, 0, receive.Count); //在Winform中无法把json一次完整接收,需要判断EndOfMessage的状态。 //临时不完整数据 string tempMsg = Encoding.UTF8.GetString(array, 0, receive.Count); msg += tempMsg; if (receive.EndOfMessage == false) { continue; } TTSResult result = JsonSerializer.Deserialize <TTSResult>(msg, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); //清空数据 msg = ""; if (result.Code != 0) { throw new Exception($"Result error: {result.Message}"); } if (result.Data == null) { //空帧,不用管 continue; } byte[] audiaBuffer = System.Convert.FromBase64String(result.Data.Audio); _result.AddRange(audiaBuffer); OnMessage?.Invoke(this, result.Data.Audio); if (result.Data.Status == 2) { Status = ServiceStatus.Stopped; } } } catch (WebSocketException) { Status = ServiceStatus.Stopped; return; } catch (Exception ex) { Status = ServiceStatus.Stopped; if (!ex.Message.ToLower().Contains("unable to read data from the transport connection")) { OnError?.Invoke(this, new ErrorEventArgs() { Code = ResultCode.Error, Message = ex.Message, Exception = ex, }); } } } }