@@ -1972,46 +1972,140 @@ void LaunchWebGL(Project proj)
1972
1972
var webExe = Path . Combine ( webglToolsPath , "SimpleWebServer.exe" ) ;
1973
1973
if ( File . Exists ( webExe ) == false ) return ;
1974
1974
1975
- // pick random port for server
1976
- Random rnd = new Random ( ) ;
1977
- int port = rnd . Next ( 50000 , 61000 ) ;
1975
+ // pick initial number for server, TODO make this default start port as setting field (later if needed..)
1976
+ int port = 50000 ;
1978
1977
1979
- // check if port is available https://stackoverflow.com/a/2793289
1980
- //bool isAvailable = true;
1981
- //IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
1982
- //IPEndPoint[] objEndPoints = ipGlobalProperties.GetActiveTcpListeners( );
1978
+ // check if this project already has server running and process is not closed
1979
+ if ( webglServerProcesses . ContainsKey ( port ) && webglServerProcesses [ port ] . HasExited == false )
1980
+ {
1981
+ Console . WriteLine ( "Port found in cache: " + port + " process=" + webglServerProcesses [ port ] ) ;
1983
1982
1984
- //// compare with existing ports, if available
1985
- //foreach (IPEndPoint tcpi in objEndPoints)
1986
- //{
1987
- // if (tcpi.Port == port)
1988
- // {
1989
- // isAvailable = false;
1990
- // break;
1991
- // }
1992
- //}
1983
+ // check if project matches
1984
+ if ( webglServerProcesses [ port ] . StartInfo . Arguments . IndexOf ( "\" " + buildPath + "\" " ) > - 1 )
1985
+ {
1986
+ Console . WriteLine ( "this project already has webgl server running.. lets open browser url only" ) ;
1987
+ // then open browser url only
1988
+ Tools . OpenURL ( "http://localhost:" + port ) ;
1989
+ return ;
1993
1990
1994
- bool serverLaunched = false ;
1991
+ }
1992
+ else
1993
+ {
1994
+ Console . WriteLine ( "Port in use, but its different project: " + port ) ;
1995
+ Console . WriteLine ( webglServerProcesses [ port ] . StartInfo . Arguments + " == " + "\" " + buildPath + "\" " ) ;
1996
+
1997
+ // then open new port and process
1998
+ // -----------------------------------------------------------
1999
+ // check if port is available https://stackoverflow.com/a/2793289
2000
+ bool isAvailable = true ;
2001
+ IPGlobalProperties ipGlobalProperties = IPGlobalProperties . GetIPGlobalProperties ( ) ;
2002
+ IPEndPoint [ ] objEndPoints = ipGlobalProperties . GetActiveTcpListeners ( ) ;
2003
+
2004
+ // NOTE instead of iterating all ports, just try to open port, if fails, open next one
2005
+ // compare with existing ports, if available
2006
+ for ( int i = 0 ; i < objEndPoints . Length ; i ++ )
2007
+ {
2008
+ if ( objEndPoints [ i ] . Port == port )
2009
+ {
2010
+ port ++ ;
2011
+ if ( port > 65535 )
2012
+ {
2013
+ Console . WriteLine ( "Failed to find open port.." ) ;
2014
+ return ;
2015
+ }
2016
+ }
2017
+ }
1995
2018
1996
- //if (isAvailable == false)
1997
- //{
1998
- // Console.WriteLine("failed to open port " + port + " (should be open already, or something else is using it?)");
1999
- //}
2000
- //else
2001
- //{
2002
- // take process id from unity, if have it (then webserver closes automatically when unity is closed)
2003
- var proc = ProcessHandler . Get ( proj . Path ) ;
2004
- int pid = proc == null ? - 1 : proc . Id ;
2005
- var param = "\" " + webExe + "\" \" " + buildPath + "\" " + port + ( pid == - 1 ? "" : " " + pid ) ; // server exe path, build folder and port
2006
- // TODO take process reference, so can check if its already running
2007
- serverLaunched = Tools . LaunchExe ( monoExe , param ) ;
2008
- //}
2019
+ Console . WriteLine ( "Found available port: " + port ) ;
2020
+
2021
+ if ( isAvailable == false )
2022
+ {
2023
+ Console . WriteLine ( "failed to open port " + port + " (should be open already, or something else is using it?)" ) ;
2024
+ }
2025
+ else
2026
+ {
2027
+ // take process id from unity, if have it (then webserver closes automatically when unity is closed)
2028
+ var proc = ProcessHandler . Get ( proj . Path ) ;
2029
+ int pid = proc == null ? - 1 : proc . Id ;
2030
+ var param = "\" " + webExe + "\" \" " + buildPath + "\" " + port + ( pid == - 1 ? "" : " " + pid ) ; // server exe path, build folder and port
2031
+
2032
+ var webglServerProcess = Tools . LaunchExe ( monoExe , param ) ;
2033
+
2034
+ if ( webglServerProcesses . ContainsKey ( port ) )
2035
+ {
2036
+ Console . WriteLine ( "Error> Should not happen - this port is already in dictionary! port: " + port ) ;
2037
+ }
2038
+ else // keep reference to this process on this port
2039
+ {
2040
+ // TODO how to remove process once its closed? (or unlikely to have many processes in total? can also remove during check, if process already null)
2041
+ webglServerProcesses . Add ( port , webglServerProcess ) ;
2042
+ Console . WriteLine ( "Added port " + port ) ;
2043
+ }
2044
+
2045
+ Tools . OpenURL ( "http://localhost:" + port ) ;
2046
+ }
2047
+ // -----------------------------------------------------------
2009
2048
2010
- if ( serverLaunched == true )
2049
+ }
2050
+ }
2051
+ else
2011
2052
{
2012
- Tools . OpenURL ( "http://localhost:" + port ) ;
2053
+ Console . WriteLine ( "Port not running in cache or process already closed, remove it from cache: " + port ) ;
2054
+ if ( webglServerProcesses . ContainsKey ( port ) ) webglServerProcesses . Remove ( port ) ;
2055
+
2056
+ // TODO remove duplicate code
2057
+ // then open new process
2058
+ // -----------------------------------------------------------
2059
+ // check if port is available https://stackoverflow.com/a/2793289
2060
+ bool isAvailable = true ;
2061
+ IPGlobalProperties ipGlobalProperties = IPGlobalProperties . GetIPGlobalProperties ( ) ;
2062
+ IPEndPoint [ ] objEndPoints = ipGlobalProperties . GetActiveTcpListeners ( ) ;
2063
+
2064
+ // compare with existing ports, if available
2065
+ for ( int i = 0 ; i < objEndPoints . Length ; i ++ )
2066
+ {
2067
+ if ( objEndPoints [ i ] . Port == port )
2068
+ {
2069
+ // TODO doesnt stop at max port number 65535
2070
+ port ++ ;
2071
+ }
2072
+ }
2073
+
2074
+ Console . WriteLine ( "Found available port: " + port ) ;
2075
+
2076
+ if ( isAvailable == false )
2077
+ {
2078
+ Console . WriteLine ( "failed to open port " + port + " (should be open already, or something else is using it?)" ) ;
2079
+ }
2080
+ else
2081
+ {
2082
+ // take process id from unity, if have it(then webserver closes automatically when unity is closed)
2083
+ var proc = ProcessHandler . Get ( proj . Path ) ;
2084
+ int pid = proc == null ? - 1 : proc . Id ;
2085
+ var param = "\" " + webExe + "\" \" " + buildPath + "\" " + port + ( pid == - 1 ? "" : " " + pid ) ; // server exe path, build folder and port
2086
+
2087
+ var webglServerProcess = Tools . LaunchExe ( monoExe , param ) ;
2088
+
2089
+ if ( webglServerProcesses . ContainsKey ( port ) )
2090
+ {
2091
+ Console . WriteLine ( "Error> Should not happen - this port is already in dictionary! port: " + port ) ;
2092
+ }
2093
+ else // keep reference to this process on this port
2094
+ {
2095
+ // TODO how to remove process once its closed? (or unlikely to have many processes in total? can also remove during check, if process already null)
2096
+ webglServerProcesses . Add ( port , webglServerProcess ) ;
2097
+ Console . WriteLine ( "Added port " + port ) ;
2098
+ }
2099
+
2100
+ Tools . OpenURL ( "http://localhost:" + port ) ;
2101
+ }
2102
+ // -----------------------------------------------------------
2103
+
2013
2104
}
2014
- }
2105
+ } // LaunchWebGL()
2106
+
2107
+ // reference to already running webgl server processes and ports
2108
+ Dictionary < int , Process > webglServerProcesses = new Dictionary < int , Process > ( ) ;
2015
2109
2016
2110
private void TxtWebglRelativePath_TextChanged ( object sender , TextChangedEventArgs e )
2017
2111
{
0 commit comments