.Net framework Owin Test Server não funciona com WebSocket

Aug 26 2020

Meu projeto é auto-hospedado pelo Owin, ele fornece endpoints de API da Web e endpoints de soquete da Web. Aqui está o código de configuração relevante na classe de inicialização do projeto Owin WebSocket é usado aqui

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 sem problemas, quando o aplicativo é iniciado, posso consumir a API da Web por meio de "http: // {host} / api / v1 / test" e usar os soquetes da Web por: "ws: // {host} / api / v1 / socket /teste"

Então decidi adicionar alguns testes de integração. Eu uso o Owin Test Server aqui. Na TestServer.Createconfiguração é 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 teste para API

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

Funciona bem. Mas não 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 que No connection could be madeaqui? Parece que o servidor de teste só pode suportar solicitações http regulares, não websocket. Mas este não é o caso no aplicativo principal, onde a configuração e estrutura idênticas são usadas. O que estou perdendo aqui? Estou mexendo nisso há horas, sem sucesso ...

Respostas

Frostless Aug 26 2020 at 11:24

Encontrei a resposta. O TestServer.Create<Startup>()único começa apenas a instância na memória em que o url não está disponível. O cliente de soquete da web, entretanto, depende da url para funcionar. Portanto, a solução é usar a sobrecarga WebApp.Start<Startup>(Settings.WebApiUrl)(ela inicia um aplicativo da web no url fornecido)

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

Ref