CoreWCF / CoreWCF

Main repository for the Core WCF project
MIT License
1.65k stars 292 forks source link

[Bug]: Not able to launch more than one corewcf service (Different process) using named pipe on same port #1311

Open pranith-BH opened 9 months ago

pranith-BH commented 9 months ago

Duplicate ?

Product version

1.5

Describe expected behavior

I have 2 Self Hosted WCF services working with Net48. They use only net named pipe for communication. When converting them to CoreWCf and using net named pipes it should work

Describe actual behavior

The first starts correctly and says listening on Net Pipe , as soon as the second service tries to start it says port is already in use. To reproduce the issue run the CoreWCFDemoFirst then second. CoreWCFDemosSecond.zip

CoreWCFDemoFirst.zip

Which binding

NetNamedPipe

security

None

Which .NET version

.NET 6

Which os platform

Windows

Code snippet used to reproduce the issue

No response

Stacktrace if any

No response

pranith-BH commented 9 months ago

@mconnew Help please

mconnew commented 9 months ago

I'm not going to be able to take a look until next week. What error do you get when starting the second one? My suspicion is you are using the same base address on each. The base address needs to be unique between processes as that's what's used as the path behind the named pipe. You can specify the base address as an option to UseNetNamedPipe.

mconnew commented 9 months ago

Also if you can post the code into either a temporary github repo or a gist (gist can do multiple files now) then I can look at the code on my phone.

obiwan007 commented 9 months ago

The problem is that Kestrel ist starting up with the default endpoint. Why kestrel is even starting (if not call UseKestrel) is a bit strange.

Microsoft.AspNetCore.DataProtection.Internal.DataProtectionHostedService[65] Key ring with default key {94932533-09e7-4f45-ac06-b255f487cb48} was loaded during application startup. dbug: Microsoft.AspNetCore.Server.Kestrel[0] No listening endpoints were configured. Binding to http://localhost:5000 by default. dbug: CoreWCF.Channels.Framing.NetMessageFramingConnectionHandler[0] Registering URI net.pipe://localhost/HostedWebControlCallback/0_00000000-0000-0000-0000-000000000000 with NetMessageFramingConnectionHandler dbug: Microsoft.AspNetCore.Hosting.Diagnostics[4] Hosting started

mconnew commented 8 months ago

We need to add a second set of extension methods to IHostBuilder as well as IWebHostBuilder so that you don't need to use a WebApplication to host your service. That way you can use Host.CreateDefaultBuilder to create an app host which doesn't require you to have an Http endpoint. For now you can work around this by explicitly configuring Kestrel to listen on localhost with port number 0. This will cause it to pick an unused port and bind to that. By using localhost you prevent other hosts from connecting.
We'll get this fixed, but as there's a workaround, it's not going to be done urgently.

Modify the CreateWebHostBuilder method in the sample you posted to look like this:

        public IWebHostBuilder CreateWebHostBuilder<TStartup>([CallerMemberName] string basePath = "", [CallerMemberName] string callerMethodName = "") where TStartup : class =>
            WebHost.CreateDefaultBuilder(Array.Empty<string>())
                .UseNetNamedPipe(options =>
                {
                    options.Listen(new Uri("net.pipe://localhost/" + basePath + "/"));
                })
                .UseKestrel(options =>
                {
                    options.ListenLocalhost(0);
                })
                .UseStartup<TStartup>();

This way you don't have clashing listening port numbers.

pranith-BH commented 8 months ago

@mconnew : I tried something similar to what you mentioned , able to get to to launch.

Our Application is deployed In networks where its not possible for us to keep multiple ports open. We have about 20 plus self hosted wcf services. Do you think when we get the TCP Port Sharing Service added for CoreWCF We will still be able to achieve the way it used to work with WCF of keeping a single port open or do you think the way Kestral is starting up it will not allow us to achieve our intended target. If TCP Port sharing will solve it can you share any timeline for it ? Would be possible for us to setup a short teams call. We used Named Pipes for internal communications and NetTCP for external communications.

mconnew commented 8 months ago

With Port Sharing, we will control the creation of the port, and that will actually happen in the port sharing service which then duplicates the socket handle and sends the handle number to the service which then creates a socket based on that handle. We'll then hand off that socket to Kestrel. Kestrel just won't own the listening socket.

pranith-BH commented 8 months ago

@mconnew : Thanks for the quick reply. Would it be possible for us to a short microsoft teams call . I do have a case created with MS support as well for this.

mconnew commented 8 months ago

Talk to MS support about scheduling a call

mconnew commented 8 months ago

@pranith-BH, alternatively we have a monthly teams meeting you could join, details in the main readme page, but we recently had it so it's a few weeks out until the next one.

mconnew commented 7 months ago

I found another issue which is related to this. Issue #1340 will need to be fixed at the same time as this.