4

I have build a WebSocket web application in .net core by following this and this or this tutorials. Now I am trying to write some integration tests on this by using Microsoft.AspNetCore.TestHost

The way I create the WebSocket

public static WebSocketClient StartWebSocketServer(string url)
{
    var baseAddress = $"http://{url}";
    var builder =
        WebHost.CreateDefaultBuilder(new string[]{})
            .UseEnvironment("Development")
            .ConfigureLogging((ctx, logging) => logging.AddConsole())
            .UseUrls(baseAddress)
            .UseStartup<SocketsTestStartup>();

    var server = new TestServer(builder);
    return server.CreateWebSocketClient();
}

And websocket client creation is done in the code below

ClientWebSocket testAppClient = new ClientWebSocket();
await
    testAppClient 
    .ConnectAsync(
        new Uri("ws://loclahost:52015/local"),
        CancellationToken.None);

local is the path name on the websocket server

Startup.cs

app.MapWebSocketManager(
    "/local",
    serviceProvider.GetService<LocalServiceSocketHandler>());

Anyway, the connection produce the following error

System.Net.WebSockets.WebSocketException : Unable to connect to the remote server

My question is how can I ask ClientWebSocket to connect to TestHost.WebSocketClient?

arose
  • 138
  • 1
  • 8
MJK
  • 3,434
  • 3
  • 32
  • 55
  • I doubt you're still stuck here, but thought I should point out the typo in your url "loclahost". – Ken Lyon Oct 15 '18 at 23:29
  • Haha :), thanks @KenLyon for pointing that – MJK Oct 16 '18 at 09:47
  • No problem. I was about to delete it actually when I realized you had solved the problem yourself. I just know I've been there before and it feels pretty bad when it turns out to be something simple. For example, I was trying for AGES to get the ws: protocol to work before finally realizing that I had to use wss: because my site was https. I had thought it was some obscure MVC problem. – Ken Lyon Oct 16 '18 at 15:50

3 Answers3

4

Using the TestServer the following works on my end and just in case it may help someone else, here's the code:

var builder = WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseEnvironment("Development");

var server = new TestServer(builder);
var wsClient = server.CreateWebSocketClient();

var wsUri = new UriBuilder(server.BaseAddress) 
{
    Scheme = "ws"
}.Uri;

await wsClient.ConnectAsync(wsUri, CancellationToken.None);

But since the original question is using the path /local one would just need to specify the Path property:

var wsUri = new UriBuilder(server.BaseAddress) 
{
    Scheme = "ws",

    Path = "local"
}.Uri;
Jay
  • 3,373
  • 6
  • 38
  • 55
3

Instead of TestServer, I used the following code to run the WebSocket web app

public static IWebHost CreateServer(int port)
{
    var configBuilder = new ConfigurationBuilder();
    configBuilder.AddInMemoryCollection();
    var config = configBuilder.Build();
    config["server.urls"] = $"http://localhost:{port}";

    var host = new WebHostBuilder()
        .ConfigureLogging((ctx, logging) => logging.AddDebug())
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<SocketsTestStartup>()
        .Build();

    host.Start();

    return host;
}

Basically, I have found the solution from aspnet/WebSockets tests

MJK
  • 3,434
  • 3
  • 32
  • 55
  • 1
    I usually tend to check the repos first to see how they test and use them as an example like you did. More often than not you would find a test that suits your needs. – Nkosi Nov 21 '17 at 10:48
0

This code worked for me in the enterprise grade app we developed (see all code here: https://github.com/saturn72/Programmer)

//Create test server    
var server = new TestServer(builder);

//create websocket client, connect it and to server 
var wsc = server.CreateWebSocketClient();
var uri = new Uri(BaseUri, "ws");
var webSocket = wsc.ConnectAsync(uri, CancellationToken.None).Result;
var buffer = WebSocket.CreateClientBuffer(1024, 1024);

//Start receive data
Task.Run(()=> WebSocket.ReceiveAsync(_buffer, CancellationToken.None));

Bare in mind it is async and you need do set some delay in your test

Roi Shabtai
  • 2,981
  • 2
  • 31
  • 47