Я пытаюсь подключить Nexmo к веб-сокету при входящем звонке (пользователь звонит по номеру, купленному с помощью nexmo, и ссылается на приложение).
На данный моментЯ просто пробую этот Пример кода (который просто повторяет то, что говорит вызывающий) и подключается к этой веб-розетке через Nexmo, следуя "документации" Здесь .
Я успешно отправил действие «подключиться» к nexmo.При вызове номера, купленного с помощью Nexmo, он правильно перенаправляет на конечную точку (api/nexmo/socket
), как показано при использовании точек останова, но затем зависает при достижении webSocket.ReceiveAsync в методе Echo.
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 CancellationToken, булева throwOnPrematureClosure) в System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate [TWebSocketReceiveResultGetter, TWebSocketReceiveResult](* 1 026 * payloadBuffer, CancellationToken CancellationToken, TWebSocketReceiveResultGetter resultGetter) при System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate [TWebSocketReceiveResultGetter, TWebSocketReceiveResult] (* * payloadBuffer тысячу двадцать-семь, CancellationToken CancellationToken, TWebSocketReceiveResultGetter resultGetter) на .... Controllers.NexmoController.Echo (Контекст HttpContext, WebSocket webSocket) в C :... \ Controllers \ NexmoController.cs: строка 97 в .... Controllers.NexmoController.GetAudio () в C: ... \ Controllers \ NexmoController.cs: строка 68 в lambda_method (Closure, Object) в Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult () в Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableResultExecutor.Execute (преобразователь IActionResultTypeMapper, ObjectMethodExecutor. Object.Exject.Exjects.Text.Teas.Text.Teas.Text.Teas.Text.Teas.Text.Tas.Text.Teas.Text.Tas.Text.Text.Text. Объекты.Text.Text.Text. Объекты.высший объект. Объектный объект. Объектный метод. Объектный объект.() в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync () в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync () в Microsoft.AspNetCore.ContInCate.ContectionActionInternal.Mvc.Internal.ControllerActionInvoker.Next (Состояние и следующее, Область и область действия, Объект и состояние, Логическое значение и isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow (контекст ResourceExecutedContext) в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker & След., Boolean & isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync ()
в Microsoft.AspNetCore.RvoidTextIntextMicrosoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke (HttpContext httpContext) в Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke (контекст HttpContext) в Microsoft.AspNetCore.Diagnostics * *evelopExceptionPoneTkeTide 10TextЕсть идеи, что пошло вниз?Или как я мог это исправить?Я не очень понимаю, в чем здесь проблема.
Я также попытался проверить WebSocketState Websocket, и он установлен на «Открыть».Для информации я сам протестировал пример кода (веб-сокет, повторяющий вводимые пользователем данные), и он работает.