Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import typing
|
|
from concurrent.futures import Future
|
|
|
|
if typing.TYPE_CHECKING:
|
|
import asyncio
|
|
|
|
from ._async._ws import ASGIWebSocketExtension
|
|
|
|
|
|
class ThreadASGIWebSocketExtension:
|
|
"""Synchronous WebSocket extension wrapping an async ASGIWebSocketExtension.
|
|
|
|
Delegates all operations to the async extension on a background event loop,
|
|
blocking the calling thread via concurrent.futures.Future.
|
|
"""
|
|
|
|
def __init__(self, async_ext: ASGIWebSocketExtension, loop: asyncio.AbstractEventLoop) -> None:
|
|
self._async_ext = async_ext
|
|
self._loop = loop
|
|
|
|
@property
|
|
def closed(self) -> bool:
|
|
return self._async_ext.closed
|
|
|
|
def next_payload(self) -> str | bytes | None:
|
|
"""Block until the next message arrives from the ASGI WebSocket app."""
|
|
future: Future[str | bytes | None] = Future()
|
|
|
|
async def _do() -> None:
|
|
try:
|
|
result = await self._async_ext.next_payload()
|
|
future.set_result(result)
|
|
except Exception as e:
|
|
future.set_exception(e)
|
|
|
|
self._loop.call_soon_threadsafe(lambda: self._loop.create_task(_do()))
|
|
return future.result()
|
|
|
|
def send_payload(self, buf: str | bytes) -> None:
|
|
"""Send a message to the ASGI WebSocket app."""
|
|
future: Future[None] = Future()
|
|
|
|
async def _do() -> None:
|
|
try:
|
|
await self._async_ext.send_payload(buf)
|
|
future.set_result(None)
|
|
except Exception as e:
|
|
future.set_exception(e)
|
|
|
|
self._loop.call_soon_threadsafe(lambda: self._loop.create_task(_do()))
|
|
future.result()
|
|
|
|
def close(self) -> None:
|
|
"""Close the WebSocket and clean up."""
|
|
future: Future[None] = Future()
|
|
|
|
async def _do() -> None:
|
|
try:
|
|
await self._async_ext.close()
|
|
future.set_result(None)
|
|
except Exception as e:
|
|
future.set_exception(e)
|
|
|
|
self._loop.call_soon_threadsafe(lambda: self._loop.create_task(_do()))
|
|
future.result()
|