Igosuki / signalr-rs

Actix Websocket based implementation of Signalr
MIT License
19 stars 6 forks source link

Can't get a basic client to communicate with a SignalR server #6

Closed iantr closed 2 years ago

iantr commented 2 years ago

I created a basic SignalR server following Microsoft's walkthrough here: https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr

It was trivial to create a C# console client to talk to it. I'm trying to do the same with signalr-rs. I'm having issues getting the Rust signalr-rs code to connect.

I would be happy to contribute working code (server and client) if you like, once I can get the Rust client working.

This is the working C# for the console client:

public class SignalRConnection
{
    public async void Start()
    {
        var url = "https://localhost:5001/chathub"; 

        var hubConnection = new HubConnectionBuilder()
            .WithUrl(url)
            .WithAutomaticReconnect()
            .Build();

        // Avoid certificate errors for now
        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

        // receive a message from the hub
        hubConnection.On<string, string>("ReceiveMessage", (user, message) => OnReceiveMessage(user, message));

        var task = hubConnection.StartAsync();

        task.Wait();

        // send a message to the hub
        await hubConnection.InvokeAsync("SendMessage", "ConsoleApp", "Message from the console app");
    }

    private void OnReceiveMessage(string user, string message)
    {
        Console.WriteLine($"{user}: {message}");
    }
}

This is my in-progress but not working Rust "equivalent":

[actix_rt::main]

async fn main() -> io::Result<()> { env_logger::init();

println!("SignalR Console Rust Client");

let url = Url::parse("https://localhost:5001/");

let hub = "chathub";
let handler = Box::new(ChatHubHandler { hub: hub.to_string() });

// Set up the SSL connector so verification can be turned off for now
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
builder.set_verify(openssl::ssl::SslVerifyMode::NONE); // avoid certificate errors for now
let connector = builder.build();

let client = HubClientBuilder::with_hub_and_url(hub, url.unwrap())
    .ssl_connector(connector)
    .start_supervised(handler)
    .await;

println!("Client started");

match client {
    Ok(addr) => {
        addr.do_send(HubQuery::new(
            hub.to_string(),
            "SendMessage".to_string(),
            vec!["Rust Console App"],
            "Message from the Rust console app".to_string(),
        ));
    }
    Err(e) => {
        println!("Hub client error : {:?}", e);
        System::current().stop();
    }
}

actix_rt::signal::ctrl_c().await

}

I get this output:

SignalR Console Rust Client Client started Hub client error : ParseError(Error("expected value", line: 1, column: 1))

I'd be happy to upload the server code in a PR. It's just the code from Microsoft's SignalR example.

Igosuki commented 2 years ago

Sure, put it in an example so I can review it

On Wed, Nov 10, 2021 at 11:31 PM Ian Treleaven @.***> wrote:

I created a basic SignalR server following Microsoft's walkthrough here: https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr

It was trivial to create a C# console client to talk to it. I'm trying to do the same with signalr-rs. I'm having issues getting the Rust signalr-rs code to connect.

I would be happy to contribute working code (server and client) if you like, once I can get the Rust client working.

This is the working C# for the console client:

public class SignalRConnection { public async void Start() { var url = "https://localhost:5001/chathub";

    var hubConnection = new HubConnectionBuilder()
        .WithUrl(url)
        .WithAutomaticReconnect()
        .Build();

    // Avoid certificate errors for now
    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

    // receive a message from the hub
    hubConnection.On<string, string>("ReceiveMessage", (user, message) => OnReceiveMessage(user, message));

    var task = hubConnection.StartAsync();

    task.Wait();

    // send a message to the hub
    await hubConnection.InvokeAsync("SendMessage", "ConsoleApp", "Message from the console app");
}

private void OnReceiveMessage(string user, string message)
{
    Console.WriteLine($"{user}: {message}");
}

}

This is my in-progress but not working Rust "equivalent":

[actix_rt::main]

async fn main() -> io::Result<()> { env_logger::init();

println!("SignalR Console Rust Client");

let url = Url::parse("https://localhost:5001/");

let hub = "chathub"; let handler = Box::new(ChatHubHandler { hub: hub.to_string() });

// Set up the SSL connector so verification can be turned off for now let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); builder.set_verify(openssl::ssl::SslVerifyMode::NONE); // avoid certificate errors for now let connector = builder.build();

let client = HubClientBuilder::with_hub_and_url(hub, url.unwrap()) .ssl_connector(connector) .start_supervised(handler) .await;

println!("Client started");

match client { Ok(addr) => { addr.do_send(HubQuery::new( hub.to_string(), "SendMessage".to_string(), vec!["Rust Console App"], "Message from the Rust console app".to_string(), )); } Err(e) => { println!("Hub client error : {:?}", e); System::current().stop(); } }

actix_rt::signal::ctrl_c().await

}

I get this output:

SignalR Console Rust Client Client started Hub client error : ParseError(Error("expected value", line: 1, column: 1))

I'd be happy to upload the server code in a PR. It's just the code from Microsoft's SignalR example.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Igosuki/signalr-rs/issues/6, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADDFBTGVH4NUH4IBXR7Z7LULLXDNANCNFSM5HZBSBOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

iantr commented 2 years ago

Thanks for taking a look! I hope this example helps your project once the issues in my Rust client are worked out. You can see my example added to my fork of the project (I was not able to push to your project and so I let the tooling create a fork). You can see the sample here: https://github.com/iantr/signalr-rs/tree/iantr/C%23_Example/examples/BlazorWebAssemblySignalRApp

Igosuki commented 2 years ago

Hello Ian, sorry it took me so long to find the time... Took me some time to install C# on Linux but after that the sample you provided worked out the box so props to that.

I improved the logging a little in the crate to give better context on errors

Igosuki commented 2 years ago

So after spending about an hour getting familiar with C# and your example, it seems the blazor server doesn't accept the same kind of connection handling as the SignalR configured on Bittrex servers for which the example still works out of the box.

Igosuki commented 2 years ago

So, as you can see the UI client on port 5001 does something quite different than the HubClient does, it does a post request for negotiation and then upgrades the conn to a websocket. While the Hub Client in signalr-rs does a GET request for negotiation, on another endpoint. So I suggest you first find how to parameterize the server properly so that negotiation can be done on GET requests (maybe it's the 5000 port by default ?). I'll be happy to document how to start a C# project compatible with this library once you do.

iantr commented 2 years ago

Thanks very much for your efforts, Guillaume! I'll give things a try - this helps a lot.

Cheers

Ian


From: Guillaume Balaine @.> Sent: Thursday, December 2, 2021 4:28 AM To: Igosuki/signalr-rs @.> Cc: Ian Treleaven @.>; Author @.> Subject: Re: [Igosuki/signalr-rs] Can't get a basic client to communicate with a SignalR server (Issue #6)

So, as you can see the UI client on port 5001 does something quite different than the HubClient does, it does a post request for negotiation and then upgrades the conn to a websocket. While the Hub Client in signalr-rs does a GET request for negotiation, on another endpoint. So I suggest you first find how to parameterize the server properly so that negotiation can be done on GET requests (maybe it's the 5000 port by default ?). I'll be happy to document how to start a C# project compatible with this library once you do.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FIgosuki%2Fsignalr-rs%2Fissues%2F6%23issuecomment-984583347&data=04%7C01%7C%7C574a55f7710443e4587308d9b58f4118%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637740449159394363%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=SpUaMQ%2Br3UPe4beN9XCOsTYDMaoq0usdF4aoRa4B8rg%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FACA7AFH3NGHWEORF6AZY4LLUO5Q67ANCNFSM5HZBSBOQ&data=04%7C01%7C%7C574a55f7710443e4587308d9b58f4118%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637740449159404363%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=eHKe4If2zbQvU%2F%2F61LC5DVcUhpw%2F%2BL2KGj33UQJbFVE%3D&reserved=0. Triage notifications on the go with GitHub Mobile for iOShttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapps.apple.com%2Fapp%2Fapple-store%2Fid1477376905%3Fct%3Dnotification-email%26mt%3D8%26pt%3D524675&data=04%7C01%7C%7C574a55f7710443e4587308d9b58f4118%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637740449159414353%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=Kyogg3ukBN7%2F2kZ1fF54KrM92%2BclE0gv5aVYcGfko%2Fo%3D&reserved=0 or Androidhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.github.android%26referrer%3Dutm_campaign%253Dnotification-email%2526utm_medium%253Demail%2526utm_source%253Dgithub&data=04%7C01%7C%7C574a55f7710443e4587308d9b58f4118%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637740449159414353%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=oivqTtmh5j1RxUp1Kkh7mxXhD9pAvGwFgzRNeHpH6tw%3D&reserved=0.

Igosuki commented 2 years ago

@iantr Have you been able to figure it out ?

iantr commented 2 years ago

Thanks for getting back to me, Guillaume. I've moved to Socket.IO for WebSocket stuff since I needed a protocol that was more open. I found a Rust library for that which I've been able to get working. I'm a total Microsoft guy I have to admit but in searching around it seemed like there was less industry support for SignalR. Socket.IO does some nice things such as start with HTTP long polling and then transitioning to WebSockets if possible. That's a durable approach that is important for my needs. I can't tell what Microsoft is doing under the covers - I'm not sure what the spec is. I also know the company I work for (Absolute Software) wouldn't be that keen on adopting a Microsoft-only protocol.

Thanks very much for getting back to me.

Cheers!

Ian


From: Guillaume Balaine @.> Sent: Wednesday, December 15, 2021 1:42 AM To: Igosuki/signalr-rs @.> Cc: Ian Treleaven @.>; Mention @.> Subject: Re: [Igosuki/signalr-rs] Can't get a basic client to communicate with a SignalR server (Issue #6)

@iantrhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fiantr&data=04%7C01%7C%7Cb75eb40f3d6d42df398308d9bfaf2999%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637751581327165523%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=9rXoAzsjG55S9pYGI4AGXKctXdwIP4tVbMX%2BCE1LUMc%3D&reserved=0 Have you been able to figure it out ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FIgosuki%2Fsignalr-rs%2Fissues%2F6%23issuecomment-994580554&data=04%7C01%7C%7Cb75eb40f3d6d42df398308d9bfaf2999%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637751581327175520%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=tEwUWtBWssLnPHUjdmzwtuwoZ3a83MhyJ%2BIkccrYjmY%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FACA7AFCYNNKTSP6LKAADU73URBPG7ANCNFSM5HZBSBOQ&data=04%7C01%7C%7Cb75eb40f3d6d42df398308d9bfaf2999%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637751581327185513%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=ILuhxcbJRFatxOr4gkLT9UeyqX6UX8lApTyoSWbcNm0%3D&reserved=0. Triage notifications on the go with GitHub Mobile for iOShttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapps.apple.com%2Fapp%2Fapple-store%2Fid1477376905%3Fct%3Dnotification-email%26mt%3D8%26pt%3D524675&data=04%7C01%7C%7Cb75eb40f3d6d42df398308d9bfaf2999%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637751581327185513%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=WBqWFuVrzUkrOeSC6k6dGqfxLD6kA0vKo7hOCGZuOO8%3D&reserved=0 or Androidhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.github.android%26referrer%3Dutm_campaign%253Dnotification-email%2526utm_medium%253Demail%2526utm_source%253Dgithub&data=04%7C01%7C%7Cb75eb40f3d6d42df398308d9bfaf2999%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637751581327195507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7Rux56a3ZqRZ%2FkGDFhcqjb445OPn1Jqh5HrnZZVksWc%3D&reserved=0.

Igosuki commented 2 years ago

Well yeah SignalR is just like Socket.IO in that it tries to build a bidirectionnal technology that can work in any environment using both XHRs and WS, Socket was always going to be leaner and closer to what the browser does, SignalR seems to be a bit too integrated with Microsoft's stack.