zyanfx / Zyan

:gem: Zyan Communication Framework
http://zyan.com.de
MIT License
88 stars 38 forks source link

.NET 5 support #88

Open theRainbird opened 3 years ago

theRainbird commented 3 years ago

Zyan has currently no support for .NET 5, because .NET Remoting is not available in .NET 5 anymore. .NET 5 support would be a great.

theRainbird commented 3 years ago

I recently created a library to migrate large classic .NET Remoting projects to .NET 5 based on websocket-sharp, named CoreRemoting. Some parts of the code may be also useful for Zyan to create a transport layer that runs well on .NET 5.

yallie commented 3 years ago

Hello Hagen, great to hear from you again! :)

The project looks very interesting! Is it a prototype or you already use it in production?

Some parts of the code may be also useful for Zyan to create a transport layer that runs well on .NET 5.

I've always felt annoyed that such a good library is doomed because of the deprecation of Remoting. Zyan is used in many projects and still gets quite a lot of bugfixes based on a real world use cases. Your new library provides a great opportunity to spin off a future-proof fork of Zyan.

Any chances you could sketch up a new transport layer for Zyan based on CoreRemoting? I remember in the past you once made a working proof-of-concept WCF-based transport for Zyan.

theRainbird commented 3 years ago

Is it a prototype or you already use it in production?

It will soon be ready for production, after the following features are completed:

There are also some more unit tests needed to ensure good quality. I'm working on a .NET Remoting based projecs for many years which has more than 1.1 millon lines of code, why it is almost impossible to rewrite using WebAPI or gRPC, so I created CoreRemoting to have a migration path to .NET 5.

Any chances you could sketch up a new transport layer for Zyan based on CoreRemoting?

Yes. I would like to do the following:

I'll try to make as few compatibility breaks as possible. .NET Standard 2.0 will make migrations to the new branch more soft, because users of Zyan can migrate while still compile against .NET Framework 4.7x+.

I remember in the past you once made a working proof-of-concept WCF-based transport for Zyan.

WCF is also deprecated, so this is a dead end.

Websocket-sharp based CoreRemoting is a good replacement for the TcpDuplexChannel, because it also supports duplex communication over one single connection (makes callbacks/push through firewalls possible). I've tried several Websocket libraries and choosed Websocket-sharp at the end, because it gave the most reliable results. My first approach for CoreRemoting was gRPC. It worked quite nice too, but I ran into issues, when I tried to use it with Blazor clients, because gRPC relies on native C++ DLLs (there is managed code only new variant of gRPC, but this one doesn't run on .NET Framework 4.x). TLS / SSL is difficult when it comes to Linux, so I decided to implement message based encryption similar to Zyan TcpDuplexChanel.

When it comes to serialization I ended in using classic BinaryFormatter (with applying your extensions to make it more safe :) and DataContractSerializer (which was used in WCF as default). The latter was required to support Blazor clients, because Microsoft blocks BinaryFormatter usage in Blazor. I've tried almost other serialization libraies (Protobuf, MessagePack, JSON.NET, ...) I could find on nuget, but they all have some restrictions that they are not usable for a .NET Remoting replacement library.

To leave to door to other transport and serialization technologies open, I've made them pluggable in CoreRemoting.

yallie commented 3 years ago

It will soon be ready for production, after the following features are completed

Sounds exciting! :) You're going to build message integrity right into the transport protocol?

I'm working on a .NET Remoting based projecs for many years which has more than 1.1 millon lines of code

Did you ever use Zyan in your company's projects?

I'll try to make as few compatibility breaks as possible.

Perhaps we could get rid of too many constructor overloads in Zyan classes :) I believe they were written before C# supported default parameter values. I kept them to ensure 100% backwards compatibility, but now it's going to be a major breaking change anyway.

WCF is also deprecated, so this is a dead end.

Sure, WCF is a dead end. I mentioned it because I believe that fork had some different approach to plugging transport channels. But I don't remember much details about it.

To leave to door to other transport and serialization technologies open, I've made them pluggable in CoreRemoting.

That's great! It would be awesome to make them pluggable in Zyan itself. If we don't serialize anything really weird like delegates, it should be possible.

theRainbird commented 3 years ago

You're going to build message integrity right into the transport protocol?

I have to add only a Signature property to the WireMessage class. OK, someone may say, that message integrity is a separate concern and should be implemented separately. But I want to keep the code as easy and lean as possible. SoC is important, but keep the complexity low is important too.

Did you ever use Zyan in your company's projects?

Unfortunately not :sob:. The main project is a large ERP application. It's development was started in the early 90s. So it's difficult to migrate the infrastructure to a new framework. There was never budget for that. We currently use classic .NET Remoting. Since last year we're switched from standard TcpChannel to GenuineChannels (gtcp). This one is a masterpiece. But it is still .NET Remoting which is deprecated. So CoreRemoting will open a migration path even for that old grown large application to .NET 5 (I believe, that .NET 6 will be out, before the migration really begins).

Perhaps we could get rid of too many constructor overloads in Zyan classes :)

Of course, the Zyan source code should be polished. Currently I develop almost everything on Linux and using JetBrains RiderIDE. It has excellent code inspection and makes refactoring much more easy compared the Visual Studio (only my subjective opinion).

If we don't serialize anything really weird like delegates, it should be possible.

No, only parameters to call delegates are serialized. The problems I had with most serializers are to serialize DataSets / DataTables. And not only current snapshots of them, but rather complete DiffGrams (to bring RowStates and original values over the wire).

yallie commented 3 years ago

Unfortunately not 😭. The main project is a large ERP application. It's development was started in the early 90s. So it's difficult to migrate the infrastructure to a new framework. There was never budget for that.

Sounds familiar... Although we started many new projects with Zyan, we never migrated our legacy Remoting apps to Zyan.

zaksnet commented 3 years ago

Hey Guys! Any estimates and projections of when and if this is going to happen?

theRainbird commented 3 years ago

Precise estimates are difficult :crystal_ball:, because I'm doing this only in my free time :cocktail:. Before I start to migrate Zyan from classic .NET Remoting to CoreRemoting, development of CoreRemoting must be completed. There are only few tasks left. You can track the progress on the Project Kanban board. When that tasks are done, CoreRemoting is feature complete. Then I'll start to migrate Zyan. I start with it as soon as possible, because everyone using .NET Remoting or Zyan is already searching for a replacement. If it take to long, most users will have found other solutions.

theRainbird commented 3 years ago

First migration steps towards .NET 5 are done. Basic Zyan RPC features are now running on .NET 5 with CoreRemoting under the hood. Many things like events, delegates, InterLinq are not working yet.

This is the commit: https://github.com/zyanfx/Zyan/commit/0aca4ad1f3739935434fe8cdc6fc44747b506793 You can find the CoreRemoting migration version at the following branch: https://github.com/zyanfx/Zyan/tree/with_coreremoting

yallie commented 3 years ago

That's great! 🎉

InterLinq probably just needs a new adaptor/query executor for the CoreRemoting. I think that events and delegates will be the most tricky part... As far as I remember, the current implementation relies on a special treatment for MarshalByRefObjects.

theRainbird commented 3 years ago

CoreRemoting currently does support delegates and events, but not MarshalByRefObj. So I have implement this first in CoreRemoting. MarshalByRefObj behavior is tricky to achieve on .NET Core / .NET 5, because there is no RealProxy implementation. So I'll using Castle.DynamicProxy. This one is great, but it can only proxy interfaces without limitations. When proxy a class, only virtual members could be intercepted. Interface proxies should be enough to get Zyan event and delegate support running, but not enough to easily migrate classic .NET Remoting applications to CoreRemoting. Generating a wrapper with IL on runtime could be possible fallback solution.

My next steps will be:

yallie commented 3 years ago

CoreRemoting currently does support delegates and events, but not MarshalByRefObj. So I have implement this first in CoreRemoting.

Do we really need MarshalByRefObj support? It looks to me as an implementation details in Zyan, not a feature. One of key points of Zyan is to avoid using MarshalByRefObjs and other .NET Remoting APIs.

This one is great, but it can only proxy interfaces without limitations. When proxy a class, only virtual members could be intercepted.

Zyan only supports proxies for interfaces, does it?

theRainbird commented 3 years ago

But Zyan is using MarshalByRefObjects internally to provider delegate and event support. So I have two options to get Zyan delegate and event support running on .NET 5: