Fix local HTTP server UI check (#556)

* Fix local HTTP server UI check

* Fix connection section cleanup
main
dsarno 2026-01-14 19:57:17 -08:00 committed by GitHub
parent b611b268ef
commit 3f08ac0e43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 80 additions and 5 deletions

View File

@ -35,6 +35,12 @@ namespace MCPForUnity.Editor.Services
/// </summary> /// </summary>
bool IsLocalHttpServerRunning(); bool IsLocalHttpServerRunning();
/// <summary>
/// Fast reachability check: returns true if a local TCP listener is accepting connections
/// for the configured local URL/port (used for UI state without process inspection).
/// </summary>
bool IsLocalHttpServerReachable();
/// <summary> /// <summary>
/// Attempts to get the command that will be executed when starting the local HTTP server /// Attempts to get the command that will be executed when starting the local HTTP server
/// </summary> /// </summary>

View File

@ -3,6 +3,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Net.Sockets;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using MCPForUnity.Editor.Constants; using MCPForUnity.Editor.Constants;
@ -600,6 +601,75 @@ namespace MCPForUnity.Editor.Services
} }
} }
public bool IsLocalHttpServerReachable()
{
try
{
string httpUrl = HttpEndpointUtility.GetBaseUrl();
if (!IsLocalUrl(httpUrl))
{
return false;
}
if (!Uri.TryCreate(httpUrl, UriKind.Absolute, out var uri) || uri.Port <= 0)
{
return false;
}
return TryConnectToLocalPort(uri.Host, uri.Port, timeoutMs: 50);
}
catch
{
return false;
}
}
private static bool TryConnectToLocalPort(string host, int port, int timeoutMs)
{
try
{
if (string.IsNullOrEmpty(host))
{
host = "127.0.0.1";
}
var hosts = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { host };
if (host == "localhost" || host == "0.0.0.0")
{
hosts.Add("127.0.0.1");
}
if (host == "::" || host == "0:0:0:0:0:0:0:0")
{
hosts.Add("::1");
}
foreach (var target in hosts)
{
try
{
using (var client = new TcpClient())
{
var connectTask = client.ConnectAsync(target, port);
if (connectTask.Wait(timeoutMs) && client.Connected)
{
return true;
}
}
}
catch
{
// Ignore per-host failures.
}
}
}
catch
{
// Ignore probe failures and treat as unreachable.
}
return false;
}
private bool StopLocalHttpServerInternal(bool quiet, int? portOverride = null, bool allowNonLocalUrl = false) private bool StopLocalHttpServerInternal(bool quiet, int? portOverride = null, bool allowNonLocalUrl = false)
{ {
string httpUrl = HttpEndpointUtility.GetBaseUrl(); string httpUrl = HttpEndpointUtility.GetBaseUrl();

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using MCPForUnity.Editor.Constants; using MCPForUnity.Editor.Constants;
using MCPForUnity.Editor.Helpers; using MCPForUnity.Editor.Helpers;
@ -482,14 +481,14 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
bool canStartLocalServer = httpLocalSelected && MCPServiceLocator.Server.IsLocalUrl(); bool canStartLocalServer = httpLocalSelected && MCPServiceLocator.Server.IsLocalUrl();
bool localServerRunning = false; bool localServerRunning = false;
// Avoid running expensive port/PID checks every UI tick. // Avoid running expensive port/PID checks every UI tick; use a fast socket probe for UI state.
if (httpLocalSelected) if (httpLocalSelected)
{ {
double now = EditorApplication.timeSinceStartup; double now = EditorApplication.timeSinceStartup;
if ((now - lastLocalServerRunningPollTime) > 0.75f || httpServerToggleInProgress) if ((now - lastLocalServerRunningPollTime) > 0.75f || httpServerToggleInProgress)
{ {
lastLocalServerRunningPollTime = now; lastLocalServerRunningPollTime = now;
lastLocalServerRunning = MCPServiceLocator.Server.IsLocalHttpServerRunning(); lastLocalServerRunning = MCPServiceLocator.Server.IsLocalHttpServerReachable();
} }
localServerRunning = lastLocalServerRunning; localServerRunning = lastLocalServerRunning;
} }
@ -531,7 +530,7 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
try try
{ {
// Check if a local server is running. // Check if a local server is running.
bool serverRunning = IsHttpLocalSelected() && MCPServiceLocator.Server.IsLocalHttpServerRunning(); bool serverRunning = IsHttpLocalSelected() && MCPServiceLocator.Server.IsLocalHttpServerReachable();
if (serverRunning) if (serverRunning)
{ {
@ -591,7 +590,7 @@ namespace MCPForUnity.Editor.Windows.Components.Connection
var delay = attempt < 6 ? shortDelay : longDelay; var delay = attempt < 6 ? shortDelay : longDelay;
// Check if server is actually accepting connections // Check if server is actually accepting connections
bool serverDetected = MCPServiceLocator.Server.IsLocalHttpServerRunning(); bool serverDetected = MCPServiceLocator.Server.IsLocalHttpServerReachable();
if (serverDetected) if (serverDetected)
{ {