<TargetFramework>netcoreapp2.2</TargetFramework>
...
โ electron-v5 git:(master) โ node -v
v8.15.1
โ electron-v5 git:(master) โ npm -v
6.4.1
Steps to Reproduce:
electronize startโ electron-v5 git:(master) โ electronize start
Start Electron Desktop Application...
Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 49.16 ms for /Users/rosenbek/Desktop/csharp/electron-v5/electron-v5.csproj.
electron-v5 -> /Users/rosenbek/Desktop/csharp/electron-v5/bin/Debug/netcoreapp2.2/osx-x64/electron-v5.dll
electron-v5 -> /Users/rosenbek/Desktop/csharp/electron-v5/bin/Debug/netcoreapp2.2/osx-x64/electron-v5.Views.dll
electron-v5 -> /Users/rosenbek/Desktop/csharp/electron-v5/obj/Host/bin/
node_modules missing in: /Users/rosenbek/Desktop/csharp/electron-v5/obj/Host/node_modules
Start npm install...
up to date in 10.931s
ElectronHostHook handling started...
Invoke electron - in dir: /Users/rosenbek/Desktop/csharp/electron-v5/obj/Host/node_modules/.bin
Electron Socket IO Port: 8000
Electron Socket started on port 8000 at 127.0.0.1
ASP.NET Core Port: 8000
stdout: Use Electron Port: 8000
ASP.NET Core Application connected... global.electronsocket EKbRPQpPh_WrAD8AAAAA 2019-05-29T13:21:26.705Z
stdout: crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.IO.IOException: Failed to bind to address http://127.0.0.1:8000: address already in use. ---> Microsoft.AspNetCore.Connections.AddressInUseException: Address already in use ---> System.Net.Sockets.SocketException: Address already in use
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
After receiving the error, I can inspect the process and see that the only thing running on port 8000 is the Electron.NET app itself:
โ electron-v5 git:(master) โ lsof -t -i :8000
4474
โ electron-v5 git:(master) โ ps -p 4474
PID TTY TIME CMD
4474 ttys001 0:00.38 /Users/rosenbek/Desktop/csharp/electron-v5/obj/Host/node_modu
So it appears that somehow the app is detecting 8000 is open, and then another part of the process looks to use 8000 even though it isn't open?
The only variable in this that makes me think it is potentially something nefarious is that I am on a work VPN. It appears that as long as I am connected to work VPN, Electron.NET misdiagnoses open ports.
Is there anything in the source obvious to you which might fail to detect open port properly? It seems to me like maybe Socket IO chooses to use 8000, and then ASP.NET tries to use it right after:
Electron Socket IO Port: 8000
Electron Socket started on port 8000 at 127.0.0.1
ASP.NET Core Port: 8000
stdout: Use Electron Port: 8000
We use in the Electron.Host (Backend) the Node.js Module portscanner.
https://www.npmjs.com/package/portscanner
https://github.com/baalexander/node-portscanner
Normally we have very good experiences with it. Unfortunately, I can not adjust the problem. It must be a bug of portscanner.
There is no way to specify via configuration which port socketio should use and which port ASP.NET should use? (Ideally, I think it would be a port range rather than an individual port) I checked the documentation for this sort of thing but didn't find any
FWIW, get-port seems to be a more popular alternative to portscanner, and a bit more well-maintained. I wonder if replacement would be simple enough?
A change could also be risky. We need the info / tests if more Mac computers have the same problem.
The next version of Electron.NET should also be able to set its own fixed ports in the electron.manifest.json file.
I don't think this is likely to be a bug with portscanner, but more likely an asynchronicity issue.
What I believe is happening based on the source is that app.on('ready'... is firing, starting the process for socket.io on port 8000, but then startAspCoreBackend is happening before the socket.io process 'listening' is fired (therefore the port is still "open" for a brief moment)
I believe startAspCoreBackend should be called inside of the on('listening... function instead.
I think it would also be wise to not use the same port in both calls to portscanner.findAPortNotInUse.
What are your thoughts?
You can test it.
Go to your project under the folder /obj/Host
Here you can find the main.js
change the code and start the app with the command "electron ." (from obj/Host path) -
Possibly you have to install Electron globally with "sudo npm i electron-g"
I'm curious what comes out of you.
Thanks - I was trying this, but electronize start kept rebuilding obj/ dir :p
Making this change solves the issue
โ Host git:(master) โ electron .
Electron Socket IO Port: 8000
Electron Socket started on port 8000 at 127.0.0.1
ASP.NET Core Port: 8001
stdout: Use Electron Port: 8000
stdout: Hosting environment: Production
Content root path: /Users/rosenbek/Desktop/csharp/electron-v5/obj/Host/bin/
stdout: Now listening on: http://localhost:8001
Application started. Press Ctrl+C to shut down.
ASP.NET Core Application connected... global.electronsocket iDr8rgYT3RRryEk6AAAA 2019-05-29T14:38:17.353Z
stdout: BridgeConnector connected!
stdout: warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
PR here: https://github.com/ElectronNET/Electron.NET/pull/262
If you have any recommendations as to how I would be able to use my local changes as a PackageReference, I would be very greatful ๐ it's so easy with nodejs/javascript, but with dotnet, it seems like a nightmare
I say again and again :) But .NET developers unfortunately do not want to give node.js / javascript a chance.
@robertmuehsig can help a lot better here.
To your PR. Normally, a connection is established with connected only when the ASP.NET Core application has been started. For me it is just illogical how could this work for you?
Is certainly no further instance somewhere in the background?
To your PR. Normally, a connection is established with connected only when the ASP.NET Core application has been started. For me it is just illogical how could this work for you?
Per the current codebase, you have the order of operations that socket.io begins listening before ASP.NET core server starts. It could be changed, but actually, I think current order of operations is correct.
The important thing is really just that they happen "synchronously" (sort of) so that one is finished listening before the other port search occurs.
I have confirmed there are no other electron processes or instances running in the background.
Okay, thank you ... I'll test that again and if everything works out, your PR comes out with the next update. Thank you for your commitment! :)
By the way, there are still plenty of native Electron features that are only for Mac. We have not implemented it yet because we do not have a Mac. If you want to tap into the missing APIs, the Electron.NET would greatly enrich. :)
https://electronjs.org/docs/api (see the "for native macOS applications" parts in the description)
FWIW I have confirmed that by adding project reference to my local (with the fix), I have seen both programs fixed (no port in use error) and working as expected. Commented out PackageReference and instead used ProjectReference to my fork:
<!-- <PackageReference Include="ElectronNET.API" Version="5.22.12" /> -->
<ItemGroup>
<ProjectReference Include="..\Electron.NET\ElectronNET.API\ElectronNET.API.csproj" />
</ItemGroup>
BTW, I <3 this package a ton. I have high hopes for a bright future for this project - #NeverAgain for any WinForms, etc :)
Thank you for the flowers!
We are always happy for a star if someone likes it! Also a donation helps us more intensively to deal with the project :)
@robertmuehsig Do you have any advice for how I could use this locally, in the meantime? I was able to add a project reference, but the Host folder keeps showing up as the one from NuGet package manager. I am trying to make it so that I can use ElectronNET.Host as my local one :/ struggling hardcore with this despite much research
<ItemGroup>
<ProjectReference Include="..\Electron.NET\ElectronNET.API\ElectronNET.API.csproj" />
</ItemGroup>
with Electron.NET living one level above. Same solution, multi-project - one is my fork of Electron.NET and then my app.
I'm trying not to have to use a local nuget repository or local-feeds (https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds) but something tells me I will have no choice.
Well - the easiest option would be to use the same method we use for development:
Our CI system uses this approach, e.g. have a look at the build file.
@robertmuehsig Thanks for getting back to me! I have been trying just what you recommended for a few hours now :) I looked at the buildReleaseNuGetPackages.cmd file and ran all of those commands to make sure artifacts/ folder is up to date with most recent packages.
Then, I added this NuGet config to my local project:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="LocalDev" value="../Electron.NET/artifacts" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
You can see, this project lives alongside the Electron.NET fork in the same solution.
However, whenever I run electronize start (after dotnet clean, dotnet restore, dotnet build etc), the obj/Host folder does not have the changes that are in my Electron.NET fork.
So it seems no matter what, for some reason obj/Host is always missing the changes from my fork. Still trying to grind at this to see if I can get it operational
Mh - You could check your local nuget cache folder and delete the package or bump up the version number from your local build. Maybe NuGet will try to use the "cached" version.
@robertmuehsig Thank you sir. I will proceed to slap myself for not thinking of this :)
Fixed with the current version 5.22.14. Thank you @netpoetica :)
Most helpful comment
Mh - You could check your local nuget cache folder and delete the package or bump up the version number from your local build. Maybe NuGet will try to use the "cached" version.