【发布时间】:2019-07-19 00:52:37
【问题描述】:
我正在尝试在进行入站呼叫时将 Nexmo 连接到网络套接字(用户拨打通过 nexmo 购买的号码并链接到应用程序)。
到目前为止,我只是在尝试这个Sample Code(它只是回应调用者所说的话)并按照“文档”Here 通过 Nexmo 连接到这个 websocket。
我成功地向 nexmo 发送了一个“连接”操作。在调用使用 Nexmo 购买的号码时,它会正确重定向到端点 (api/nexmo/socket),如使用断点时所示,但在到达 Echo 方法中的 webSocket.ReceiveAsync 时会挂断。 p>
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
namespace MyProject.Web.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class NexmoController : ControllerBase
{
private WebSocket _webSocket;
[HttpGet("answer")]
public IActionResult AnswerHandler()
{
const string host = "MY_NGROK_URL";
const string locale = "fr-FR";
var nccos = new JArray();
var nccoConnect = new JObject()
{
{ "action", "connect" },
{ "endpoint", new JArray(new JObject{
{ "type", "websocket" },
{ "uri", $"wss://{host}/api/nexmo/socket"},
{ "content-type", "audio/l16;rate=16000"},
{ "headers", new JObject {
{ "language", locale },
{ "callerID", "MY_NUMBER_HARDCODED_WHILE_TESTING" }
}
}
})
}
};
nccos.Add(nccoConnect);
return Content(nccos.ToString(), "application/json");
}
[HttpPost("event")]
public IActionResult EventHandler()
{
return Ok();
}
[HttpGet("socket")]
public async Task GetAudio()
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
_webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
await Echo(HttpContext, _webSocket);
}
else
{
HttpContext.Response.StatusCode = 400;
}
}
//Copy Paste from the Sample Code
private async Task Echo(HttpContext context, WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
//Breakpoint : ReceiveAsync generates an exception
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
}
}
这里是捕获的异常:
System.Net.WebSockets.WebSocketException (0x80004005):远程 一方在未完成关闭的情况下关闭了 WebSocket 连接 握手。 ---> System.Net.WebSockets.WebSocketException (0x80004005): 远程方未完成就关闭了 WebSocket 连接 亲密的握手。
更多异常:
在 System.Net.WebSockets.ManagedWebSocket.ThrowIfEOFUnexpected(Boolean throwOnPrematureClosure) 在 System.Net.WebSockets.ManagedWebSocket.EnsureBufferContainsAsync(Int32 minimumRequiredBytes, CancellationToken cancelToken, Boolean throwOnPrematureClosure) 在 System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate[TWebSocketReceiveResultGetter,TWebSocketReceiveResult](
Memory`1payloadBuffer、CancellationToken、cancellationToken、 TWebSocketReceiveResultGetter resultGetter) 在 System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate[TWebSocketReceiveResultGetter,TWebSocketReceiveResult](Memory`1payloadBuffer、CancellationToken、cancellationToken、 TWebSocketReceiveResultGetter resultGetter) 在 ....Controllers.NexmoController.Echo(HttpContext 上下文, WebSocket webSocket) 中 C:...\Controllers\NexmoController.cs:行 97 在 ....Controllers.NexmoController.GetAudio() 中 C:...\Controllers\NexmoController.cs:行 68 at lambda_method(Closure, Object) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() 在 Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,Object[] 参数)在 System.Threading.Tasks.ValueTask`1.get_Result() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态& next, Scope& 范围, Object& 状态, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态和下一个, 范围&作用域、对象&状态、布尔& isCompleted)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
在 Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)
有什么想法吗?或者我该如何解决这个问题? 我真的不明白这里有什么问题。
我还尝试检查 Websocket 的 WebSocketState,它设置为“打开”。 有关信息,我自己测试了示例代码(websocket 回显用户的输入)并且它可以工作。
【问题讨论】:
-
你能记录你想要回显的内容吗?可能是您正在回显文本消息而不是音频。见developer.nexmo.com/voice/voice-api/guides/…
-
我只使用音频输入,所以不是这样 :) 但最后我们发现了问题:ngrok(见下面的答案):) 仍然谢谢!
标签: c# asp.net-core websocket phone-call nexmo