.Net framework Owin Test Server no funciona con WebSocket

Aug 26 2020

Mi proyecto es autohospedado por Owin, proporciona puntos finales de API web y puntos finales de socket web. Aquí está el código de configuración relevante en la clase de inicio del proyecto Owin WebSocket se usa aquí

using Owin;
using Owin.WebSocket.Extensions;
public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
           name: "api",
           routeTemplate: "api/{version}/{controller}"
       );
        config.EnsureInitialized();
        app.MapWebSocketRoute<WebSocket>("/api/v1/socket/test");
        app.UseWebApi(config);
    }

Funciona sin problemas, cuando se inicia la aplicación, puedo consumir la API web a través de "http: // {host} / api / v1 / test" y usar los websockets mediante: "ws: // {host} / api / v1 / socket /prueba"

Entonces decidí agregar algunas pruebas de integración. Yo uso Owin Test Server aquí. En TestServer.Createla configuración es idéntico:

        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
           name: "api",
           routeTemplate: "api/{version}/{controller}"
       );
        config.EnsureInitialized();
        app.MapWebSocketRoute<WebSocket>("/api/v1/socket/test");
        app.UseWebApi(config);

Método de prueba para api

        var url = new UriBuilder()
        {
            Scheme = "http",
            Path = "/api/v1/test"
        }.Uri;;
        var result = client.GetAsync(url).Result;

Funciona muy bien. Pero no funciona para web socket:

       var wsUri = new UriBuilder()
        {
            Scheme = "ws",
            Path = "/api/v1/socket/test"
        }.Uri;

        //create websocket client, connect it and to server 
        var wsc = new ClientWebSocket();

        Task.Run(async () =>
        {
            await wsc.ConnectAsync(wsUri, CancellationToken.None);
            var a = wsc.State; // Here error thrown: No connection could be made because the target machine actively refused it 127.0.0.1:80
        }).GetAwaiter().GetResult();

¿Por qué No connection could be madeaquí? Parece que el servidor de prueba solo puede admitir solicitudes http regulares, no websocket. Pero este no es el caso en la aplicación principal donde se usa la misma configuración y marco. ¿Que me estoy perdiendo aqui? He estado jugando con esto durante horas sin éxito ...

Respuestas

Frostless Aug 26 2020 at 11:24

Encontré la respuesta. El TestServer.Create<Startup>()único inicia solo la instancia en memoria donde la URL no está disponible. Sin embargo, el cliente de socket web se basa en la URL para funcionar. Entonces, la solución es usar la sobrecarga WebApp.Start<Startup>(Settings.WebApiUrl)(inicia una aplicación web en la URL que proporcionas)

       WebApp.Start(new StartOptions("http://localhost:8989"), startup =>
        {
            startup.MapWebSocketRoute<TestConnection>();
            startup.MapWebSocketRoute<TestConnection>("/ws", sResolver);
            startup.MapWebSocketPattern<TestConnection>("/captures/(?<capture1>.+)/(?<capture2>.+)", sResolver);
        });

Árbitro