.Net Framework Owin Test Server funktioniert nicht mit WebSocket

Aug 26 2020

Mein Projekt ist Owin selbst gehostet und bietet Web-API-Endpunkte und Web-Socket-Endpunkte. Hier ist der relevante Konfigurationscode in der Startklasse des Projekts. Owin WebSocket wird hier verwendet

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);
    }

Funktioniert reibungslos, wenn die App gestartet wird, kann ich die Web-API über "http: // {host} / api / v1 / test" verwenden und die Websockets verwenden von: "ws: // {host} / api / v1 / socket /Prüfung"

Dann habe ich beschlossen, einige Integrationstests hinzuzufügen. Ich benutze hier Owin Test Server . In TestServer.Createder Konfiguration ist identisch:

        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);

Testmethode für api

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

Funktioniert gut. Funktioniert aber nicht für 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();

Warum No connection could be madehier? Es scheint, dass der Testserver nur reguläre http-Anfragen unterstützen kann, nicht Websocket. Dies ist jedoch in der Haupt-App nicht der Fall, in der die gleiche Einstellung und das gleiche Framework verwendet werden. Was fehlt mir hier? Ich habe stundenlang vergeblich damit herumgespielt ...

Antworten

Frostless Aug 26 2020 at 11:24

Habe die Antwort gefunden. Die TestServer.Create<Startup>()einzige startet nur die In-Memory-Instanz, in der die URL nicht verfügbar ist. Der Web-Socket-Client ist jedoch auf die URL angewiesen, um zu funktionieren. Die Lösung besteht also darin, die Überlastung zu verwenden WebApp.Start<Startup>(Settings.WebApiUrl)(eine Web-App wird über die von Ihnen angegebene URL gestartet).

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

Ref