Skip to content

Fix HTTP transport recovery after domain reload#8

Closed
JOY wants to merge 1 commit into
FunplayAI:mainfrom
JOY:fix/http-listener-reload-recovery
Closed

Fix HTTP transport recovery after domain reload#8
JOY wants to merge 1 commit into
FunplayAI:mainfrom
JOY:fix/http-listener-reload-recovery

Conversation

@JOY
Copy link
Copy Markdown

@JOY JOY commented May 22, 2026

Summary

  • Replace the MCP HTTP transport's HttpListener with a loopback TcpListener that serves the same JSON-RPC-over-HTTP surface on 127.0.0.1.
  • Keep start/stop idempotent and retry short-lived port reuse, but do not report an attached/running state when this service does not own the listener.
  • Keep failed starts and disposed/stopping transports from hanging requests by returning a fast JSON-RPC server-not-ready error.
  • Continue retrying post-domain-reload restart for a bounded window and dispose services in reverse creation order.

Root Cause

Live Unity verification on Second Spawn with v0.3.7 still produced a stopped Funplay UI while the Unity process owned port 8766. CoplayDev MCP console output showed the current failure path:

  • Port 8766 is temporarily in use; retrying for up to 10 seconds.
  • Failed to start HTTP transport: Only one usage of each socket address (protocol/network address/port) is normally permitted.
  • Failed to start transport

At the same time, Windows showed Unity listening on both 127.0.0.1:8766 and [::1]:8766, but direct HTTP probes to http://127.0.0.1:8766/ were actively refused. That means the remaining failure is not a healthy duplicate Funplay server that can be attached to; it is a stale HttpListener/HTTP.sys binding inside the Unity process after script compilation/domain reload. The previous attach-probe approach cannot recover this state because there is no live handler behind the occupied port.

The conservative fix is to stop depending on HttpListener for the Unity editor transport. The package already advertises and configures http://127.0.0.1:<port>/, so a process-owned loopback TCP listener is enough and avoids the dual localhost HTTP.sys prefix behavior seen in the repro.

Verification

  • git diff --check: passed. Windows reported only expected CRLF normalization warnings.
  • dotnet run --project D:\Projects\funplay-unity-mcp-transport-harness\FunplayTransportHarness.csproj: passed.
    • Duplicate start failed without disturbing the owning listener.
    • Request without a subscriber failed fast with the server-not-ready JSON-RPC error.
  • dotnet run --project D:\Projects\funplay-unity-mcp-lifecycle-harness\FunplayLifecycleHarness.csproj: passed.
    • Lifecycle disposal and async queue cancellation checks passed.
  • CoplayDev MCP live log read in D:\Projects\Second-Spawn\Unity confirmed the active v0.3.7 failure before this change: Unity idle, no compilation in progress, Funplay stopped, port still owned by Unity, and Funplay retrying/failing on address-in-use.

Notes

Formal Unity EditMode batch tests were still not runnable in this local setup because package tests are not exposed through the current project Test Runner configuration, and previous disposable-project attempts failed during UPM resolution before test import. The included editor tests document the intended behavior for maintainers/CI.

@JOY JOY force-pushed the fix/http-listener-reload-recovery branch from bcc9846 to 53b9ac7 Compare May 22, 2026 09:57
@JOY
Copy link
Copy Markdown
Author

JOY commented May 23, 2026

Additional live verification from the Second Spawn Unity project:

  • Environment: Unity 6000.5.0b9 on Windows, package loaded from this PR's patched Funplay build during local verification.
  • Result: Funplay MCP remained connected from the evening of 2026-05-22 through 2026-05-23.
  • The editor went through multiple script compilation/domain reload cycles during that window without the MCP server dropping back to the stopped state.

This is the same project that previously reproduced the v0.3.7 failure with Port 8766 is temporarily in use followed by Only one usage of each socket address ... is normally permitted.

@Winlifes
Copy link
Copy Markdown
Member

Thanks for the fix and the extra Windows/Unity 6000.5 beta validation. I incorporated the TCP-listener based recovery approach into main, added a couple of lifecycle hardening tweaks/tests on top, and released it in v0.3.8.

Local validation before release included:

  • Unity 2022.3.62f2c1 script recompile/domain reload recovery through the running MCP server.
  • initialize reporting version 0.3.8 after reload.
  • tools/list returning the expected 29 core tools.
  • occupied-port startup returning false without stalling the editor.
  • unitypackage path validation before upload.

Closing this PR as shipped. Thank you again for the patch and for confirming the original Windows failure case stayed connected overnight.

@Winlifes Winlifes closed this May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants