.Net Framework Owin Test Server funktioniert nicht mit WebSocket
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
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