dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.27k stars 9.96k forks source link

[Epic] SignalR should have a C++ client #5301

Closed BrennanConroy closed 7 months ago

BrennanConroy commented 6 years ago
muratg commented 6 years ago

cc @anurse

BrennanConroy commented 6 years ago

List of possible work items, issues can be created from these once we decide which ones we will be implementing and importance:

analogrelay commented 6 years ago

Let's do an API review next week. @BrennanConroy can you schedule something?

alexsandro-xpt commented 6 years ago

I missing this ❤️ thanks all!

BrennanConroy commented 6 years ago

That is what the second item on the list is

Add SignalR Service support, mainly add redirect and auth from handshake response

BrennanConroy commented 6 years ago

access_token=<my azure access key> This is gotten by making a negotiate request to your app. I'm guessing you're using the wrong key here.

Manually make a request to your server to the /negotiate endpoint, get the response which should be {"url":"...","accessToken":"token"} and then create your hub connection using that info.

BrennanConroy commented 6 years ago

https://some-random-signalr.service.signalr.net is not your endpoint base. The server that you host that calls AddAzureSignalR is your endpoint. So you need to make a POST to your server at [endpoint]/negotiate which is where you'll get the redirect negotiate response.

analogrelay commented 6 years ago

It's important to note how the SignalR Service works. It's designed to be completely transparent to the client configuration:

  1. The first thing the client does is connect directly to your application. This is so that all your authentication logic can run. So if your app is running on http://mysite.com and the below logic in it's Startup.Configure, then your initial endpoint base is http://mysite.com/myhub
app.UseAzureSignalR(routes =>
{
    routes.MapHub<MyHub>("/myhub");
}
  1. The Azure SignalR SDK (which you must be using on the server) handles this request (this is what app.UseAzureSignalR does in your server app), and gets an special single-use access token from the service. Your app (via the Azure SignalR SDK) sends the URL for the Service endpoint and that access token back as a "redirect response" (that's number 2 in the section on negotiate in the spec)

  2. The client then takes the URL provided in the response (which will be based on https://some-random-signalr.service.signalr.net) and uses that as the new endpoint base. It also uses the access token and puts it in the Authorization HTTP header as a Bearer token. Then it does the normal SignalR negotiate handshake with the new endpoint base.

A brief diagram of these three steps:

image

analogrelay commented 6 years ago

I don't know what might be going wrong there. It's a little strange that you're specifying half the querystring (?url=chat&asrs.op=%2Fchat) in the URL and another half (access_token=[...]) in the querystring. What is the URL that the C++ client actually ends up requesting?

BrennanConroy commented 6 years ago

I started work on making the client work with the service a while ago. If you're comfortable changing the signalr client source code you can copy what I did here: https://github.com/aspnet/SignalR/commit/8b09728f0381fc791bd63957e72ae267727cb1b9

analogrelay commented 6 years ago

I'm afraid we don't have much in the way of resources to work on C++ right now. As @BrennanConroy mentioned we have some prototype code, but we're busy with other stuff right now and not really able to put together a complete example.

If there is a way to monitor outgoing requests from VS that would help.

You can debug through the SignalR client code, right?

bradygaster commented 5 years ago

Not saying we're officially committed to the C++ client story but we are considering it for the 3.0 time frame. As well as other potential new clients.

stukselbax commented 5 years ago

Will this client be compatible with aspnetcore signalr 2.1-2.2 server?

Probably the SignalR/clients/cpp/README.md and docs should be updated to point out your plans about the C++ client.

BrennanConroy commented 5 years ago

Yes this will be compatible with AspNetCore SignalR

wegylexy commented 5 years ago

any idea why get_connection_id() on client doesn't match with Context.ConnectionId on server?

BrennanConroy commented 5 years ago

We are just starting to work on this. I'd suggest giving us a few weeks to make some progress and then start filing issues :)

Glad you're trying it out though!

pps83 commented 5 years ago

A few questions regarding c++ signalr client:

davidfowl commented 5 years ago

how different is the old signalr from asp.net core signalr? Where can I read to understand these differences and why these two are incompatible? https://docs.microsoft.com/en-us/aspnet/core/signalr/version-differences?view=aspnetcore-2.2

signalr uses cpprestsdk, which isn't a tiny lib. In our case we cannot use it because of the binary size. Would that be easy to make a lean version of signalr that does only websockets (without pure http fallback)?

We're open to that.

wegylexy commented 5 years ago

When linked statically, the final binary is small, meaning I'm using only a tiny bit of cpprestsdk. But there were a lot of trials and errors to finally got everything compiled and linked. Preferably there will be a small signalrclient.lib and signalrclient.dll that doesn't require any other DLLs at run-time.

pps83 commented 5 years ago

I'll check size impact of signalr, but we weren't able to ship it due to app store size limits (we are a large 100mb-range app), so I'm looking to avoid cpprest (we use libcurl), and possibly to even use something leaner than websocketpp (I'd be ok to impl websocket/signalr myself if needed).

steji113 commented 5 years ago

Speaking of using cpprestsdk, I had started a conversation last year regarding other library options back on aspnet/signalr#2510. It looks like this issue had some other good tidbits of feedback that might still be valuable, as well.

I am still interested in any potential API discussions too.

steji113 commented 5 years ago

Just following up on this as I see the C++ client is being actively worked on. /cc @anurse since I originally chatted with you. Also, /cc @BrennanConroy as I believe you are the one actively working on it and might have some insight into the design process. Thanks guys!

BrennanConroy commented 5 years ago

Hey @steji113, we're currently working on cleaning up the API to not use any external libraries publicly. The big one right now is pplx::task<T> and we're looking at doing a callback model. For example invoke might look like connection.invoke("MethodName", args, [](some_param) { // process params });

alexsandro-xpt commented 5 years ago

Anybody know what is the roadmap for this library?

BrennanConroy commented 5 years ago

We are planning on shipping alongside the 3.0 release.

analogrelay commented 5 years ago

We need to break this up into smaller issues ASAP, I'll check in with you @BrennanConroy.

alexsandro-xpt commented 5 years ago

@BrennanConroy The ASPNET Core 3.0 release is planned to end of this year but I would like to start test something. Can I use this project https://github.com/aspnet/SignalR-Client-Cpp to test?

BrennanConroy commented 5 years ago

Our priorities have changed and I can't guarantee that this will ship in the 3.0 release.

https://github.com/aspnet/SignalR-Client-Cpp is where we will be doing work on the C++ client. Feel free to test it out and file issues in this repo.

proga7med commented 5 years ago
analogrelay commented 5 years ago

No, the Hub Proxy mechanism is no longer present in the SignalR client. Instead you call .InvokeAsync("NameOfMethod", arg1, arg2) on the HubConnection. By the way, this issue is tracking our work on a C++ client, I'd suggest posting a separate issue if you have a general SignalR question, or asking on Stack Overflow.

ghost commented 4 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.