我一直在努力,因为WebApi端点通过分块传输获得了响应。我正在使用协定库从麦克风获取帧(捕获的语音,字节数组),这些数组是我通过ASP.NET核心中实现的RestApi发布到服务器的。这些数据进一步通过TCP客户端发送到扬声器,当流传输失败时(扬声器无法访问,其他人正在讲话...),扬声器将返回异常。我需要实现一键通的行为,所以有必要使用分块传输。
客户至上
var playUri = "http://localhost:9100/speakers/play";
var request = WebRequest.Create(playUri);
var authorizationHeader = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "admin", "12345"));
request.Headers.Add("Authorization", $"Basic {Convert.ToBase64String(authorizationHeader)}");
request.Method = "POST";
request.ContentType = "audio/basic";
var webRequest = request as HttpWebRequest;
webRequest.SendChunked = true;
var stream = await webRequest.GetRequestStreamAsync();
var rnd = new Random();
//Generating random byte arrays (simulating frames from microphone)
var rnd = new Random();
for (int i = 0; i < 2000; i++)
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
var b = new Byte[1000];
rnd.NextBytes(b);
stream.Write(b, 0, b.Length);
}
stream.Close();
stream.Dispose();
服务器端模拟
[HttpPost("play")]
public async Task<IActionResult> Play( [FromHeader(Name = "Content-Type")] string contentType)
{
var client = new MyTcpClient(login,password);
(bool success, string response, int? statusCode) result = (false, string.Empty, null);
try
{
result = await client.PlayAudio(address, Request.Body);
}
catch (SocketException ex)
{
result.success = false;
if (ex.SocketErrorCode == SocketError.TimedOut)
{
result.statusCode = (int)HttpStatusCode.GatewayTimeout;
}
else
{
result.statusCode = (int)HttpStatusCode.InternalServerError;
}
}
catch (Exception ex)
{
result.success = false;
result.statusCode = (int)HttpStatusCode.InternalServerError;
}
if (result.success || (string.IsNullOrEmpty(result.response) && result.statusCode == null))
{
return Ok();
}
else
{
return StatusCode(result.statusCode.HasValue ? result.statusCode.Value : (int)HttpStatusCode.InternalServerError, result.response);
}
}
如果扬声器可以访问,并且在通过TcpClient向扬声器流式传输过程中没有异常,则一切正常。但是我不知道如何在写流之前完成从请求中获取响应,以便能够通知用户服务器端的问题。有可能吗?