Не удается подключить Nexmo к веб-сокету (удаленная сторона закрыла веб-сокет) в .Net Core - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь подключить 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, и он установлен на «Открыть».Для информации я сам протестировал пример кода (веб-сокет, повторяющий вводимые пользователем данные), и он работает.

1 Ответ

0 голосов
/ 26 февраля 2019

Мы нашли решение:

  • ngrock не работает с веб-сокетами (не без комиссии), поэтому мы опубликовали наше приложение на Azure.
  • Нам нужно было создать экземпляр сетевой розетки в StartUp , а не в нашем контроллере (как пример кода , указанный в исходном сообщении ).Мы поместили метод «Эхо» в другой класс (более того, чтобы сохранить хорошую структуру) и установили, что он статический.

Теперь все работает:)

Уточнение: ngrock не работает с защищенными веб-сокетами (wss)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...