.Net framework Owin Test Server no funciona con WebSocket
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
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