Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET/C# Binding #237

Closed
StinkySteak opened this issue Nov 9, 2024 · 22 comments
Closed

.NET/C# Binding #237

StinkySteak opened this issue Nov 9, 2024 · 22 comments
Labels
question Further information is requested

Comments

@StinkySteak
Copy link

Hi, I want to create a WebTransport support for Unity, I've tried quiche, but it seems they dont have built-in for WT Yet. I've across this, and wanted to create the bindings for .NET first. Sadly I dont understand elixir so much, so it will take some time to learn too. Also, My env is windows.

My questions are:

  • do I need the quinn or the WebTransport native files?
  • Can you explain me, what are the things I need to do (in high level)
@BiagioFesta
Copy link
Owner

Hi! Thanks for your interest in adding WebTransport support for Unity and exploring the project. I’m not a Windows or C# expert myself, so I don’t have detailed guidance on setting everything up in that environment. However, I can share some key insights and potential steps:

  1. Creating Bindings: You might want to check out csbindgen, a Rust project that helps generate C# bindings from Rust code. You could use it to generate C# bindings for the wtransport library. However, note that you’ll need to compile the Rust code as a dynamic library (DLL) rather than a static Rust library. The Rust documentation on linkage has details on how to do this.

  2. Async Runtime Challenge: One of the more complex parts of this integration will be dealing with async runtimes. The wtransport library requires an async Rust runtime, specifically tokio. Directly calling Rust async functions from C# through FFI won’t work out-of-the-box because there won’t be a tokio runtime available in the C# context, which will cause panics.

    To handle this, you’ll need to create an additional layer in your bindings. This layer should start a tokio runtime and coordinate with the C# async environment (like managing tasks and callbacks). This approach will require some understanding of both Rust async runtimes and C# async handling.

  3. Next Steps: Given the complexities, I’d suggest starting by experimenting with calling a simple async Rust function (running on tokio) from C#. This will help you get familiar with bridging between Rust’s and C#'s async models. Once you have that foundation, you can gradually work towards integrating wtransport.

This is definitely a challenging task, but it’s achievable with some groundwork on async integration. Good luck, and feel free to reach out if you have further questions along the way!

@StinkySteak
Copy link
Author

I still have questions, when I compile the webTransport as native library, will it automatically include quinn?

@BiagioFesta
Copy link
Owner

Yes, in general, when you compile wtransport it will bring quinn code inside for the QUIC stack implementation

@StinkySteak
Copy link
Author

Ok got it, in addition there is this https://github.com/quinn-rs/quinn-ffi, what do you think?

@BiagioFesta
Copy link
Owner

I was not aware about that, but it is probably a good start point and try to achieve the same with wtransport

@BiagioFesta BiagioFesta added the question Further information is requested label Nov 27, 2024
@wegylexy
Copy link

Check FlyByWirelss.WebTransport out. It is for server, but you may get some ideas on how to build a WebTransport client with System.Net.Quic in .NET 6.

@StinkySteak
Copy link
Author

I will take a look at it, thanks, give me time

@StinkySteak
Copy link
Author

Check FlyByWirelss.WebTransport out. It is for server, but you may get some ideas on how to build a WebTransport client with System.Net.Quic in .NET 6.

@wegylexy Unity doesn't support Latest .NET API right, how problematic if they are separate instance do you think?

@wegylexy
Copy link

@StinkySteak If it's a Windows desktop game, you could implement the WebTransport client in a separate background service and use named pipe(s) (e.g. 1 named pipe client per WT bi-directional stream with 1 named pipe server per WT session) between the local background service and the game. Then you wouldn't be limited to the Unity API.

@StinkySteak
Copy link
Author

I only intend to use the WebTransport server in dedicated server (linux), then the client can connect through javascript

@wegylexy
Copy link

In this case, you don't have to use a Unity server, thus no need for .NET binding or get limited to .NET Standard 2.1 only. What do you really want to achieve, regardless of the technology behind the scenes?

@StinkySteak
Copy link
Author

What we're limited is the Unity Mono API, where we don't have access to QUIC API. If the unity can execute a background process, I guess it can be fine, if the control is easy

@wegylexy
Copy link

the client can connect through javascript

If you use JavaScript, you don't use Mono API, just use JavaScript WebTransport in your web client.

@StinkySteak
Copy link
Author

The issue I'm unable to solve, is the server (unity instance) need to have the ability of to accept a webTransport connection

@wegylexy
Copy link

I mean, if you want to take advantage of WebTransport or any custom networking, don't use Unity Multiplay Hosting.

@StinkySteak
Copy link
Author

I'm getting a little lost here, I'm not talking about Unity Multiplay Hosting anywhere. Lets say we have a Unity multiplayer game, using mirror, and we want to utilize QUIC for webBrowser which is webTransport. However Unity is a mono and do not have an access to your API you developed for .NET 6.
The root issue is: Unity cannot take advantage for .NET 6 API, is it clear?

@wegylexy
Copy link

You need to pick one way for networking, either use Unity server (Mirror or otherwise) or something custom (WebTransport or anything).

@StinkySteak
Copy link
Author

Let's clear things up, Mirror, or Fishnet, or Netick, or you name it, has the options for us to choose the transport e.g UDP, TCP, WebSocket, even WebTransport. However, running WebTransport server in unity is not feasible. the rest are feasible, even webRTC, but WebTransport is the most effective for WebGL

@wegylexy
Copy link

I understand that Mirror does not support WebTransport in Unity WebGL client, but you don't have to use Mirror as your server. Are you saying you want to implement a custom transport for Mirror on the server side then? Otherwise, build your own networking outside Unity, just use Unity WebGL client for rendering but no Unity on server, fully custom network transport.

@StinkySteak
Copy link
Author

I have to use it inside Unity, making the same code for client & server, now you get the ideas, do you think It's possible to make it run inside Unity? or a plugin you shared make it possible for unity to interact with a background process

@wegylexy
Copy link

Server and clients are not supposed to run the same code, other than sharing data structures, because they have different responsibilities. The server runs some game logic and route packets from one client to others. The client sends commands and receives updates. You don't have to restrict yourself to those frameworks or plugins although they may be attractive at first. If there is some shared logic, you could use node.js for JavaScript or ASP.NET Core for C# on the server and Unity WebGL client in JavaScript or Unity Windows client in C# to share more code.

@StinkySteak
Copy link
Author

Sharing same code is critical when you are doing client side prediction, and more advanced tech. I think this conversation is not going anywhere, unless you can share the solution.

I can close it and re-open in the future if I go back take a look at rust wtransport.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants