mirror of
https://github.com/langgenius/dify.git
synced 2026-07-15 01:17:04 +08:00
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Blackoutta <hyytez@gmail.com> Co-authored-by: Blackoutta <37723456+Blackoutta@users.noreply.github.com>
73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
import ssl
|
|
from typing import Any, cast
|
|
from urllib.parse import urlparse
|
|
|
|
import socketio # type: ignore[reportMissingTypeStubs]
|
|
|
|
from configs import dify_config
|
|
from extensions.redis_names import serialize_redis_name
|
|
|
|
SOCKETIO_REDIS_CHANNEL = "socketio"
|
|
|
|
|
|
def _get_ssl_cert_reqs() -> ssl.VerifyMode:
|
|
cert_reqs_map = {
|
|
"CERT_NONE": ssl.CERT_NONE,
|
|
"CERT_OPTIONAL": ssl.CERT_OPTIONAL,
|
|
"CERT_REQUIRED": ssl.CERT_REQUIRED,
|
|
}
|
|
return cert_reqs_map.get(dify_config.REDIS_SSL_CERT_REQS, ssl.CERT_NONE)
|
|
|
|
|
|
def _build_redis_options(redis_url: str) -> dict[str, Any]:
|
|
"""Build Redis options for Socket.IO's cross-process pub/sub manager."""
|
|
options: dict[str, Any] = {
|
|
"socket_timeout": dify_config.REDIS_SOCKET_TIMEOUT,
|
|
"socket_connect_timeout": dify_config.REDIS_SOCKET_CONNECT_TIMEOUT,
|
|
"health_check_interval": dify_config.REDIS_HEALTH_CHECK_INTERVAL,
|
|
"protocol": dify_config.REDIS_SERIALIZATION_PROTOCOL,
|
|
}
|
|
|
|
if dify_config.REDIS_MAX_CONNECTIONS:
|
|
options["max_connections"] = dify_config.REDIS_MAX_CONNECTIONS
|
|
|
|
if urlparse(redis_url).scheme == "rediss":
|
|
options.update(
|
|
{
|
|
"ssl_cert_reqs": _get_ssl_cert_reqs(),
|
|
"ssl_ca_certs": dify_config.REDIS_SSL_CA_CERTS,
|
|
"ssl_certfile": dify_config.REDIS_SSL_CERTFILE,
|
|
"ssl_keyfile": dify_config.REDIS_SSL_KEYFILE,
|
|
}
|
|
)
|
|
|
|
return options
|
|
|
|
|
|
def create_socketio_client_manager() -> Any:
|
|
"""
|
|
Create the Socket.IO manager used to fan out room events across API workers.
|
|
|
|
Workflow collaboration relies on room broadcasts and direct emits to a collaborator's sid. The default in-memory
|
|
manager only reaches clients attached to the current process, so horizontal websocket workers must share a Redis
|
|
pub/sub channel. The channel name follows Dify's Redis key prefix to keep independent deployments isolated.
|
|
"""
|
|
redis_url = dify_config.normalized_pubsub_redis_url
|
|
return socketio.RedisManager(
|
|
redis_url,
|
|
channel=serialize_redis_name(SOCKETIO_REDIS_CHANNEL),
|
|
redis_options=_build_redis_options(redis_url),
|
|
)
|
|
|
|
|
|
# TODO: FIXME(chariri) - Casting to any because app_factory attaches the
|
|
# current app as the `app` attribute on this - Bad.
|
|
sio = cast(
|
|
Any,
|
|
socketio.Server(
|
|
async_mode="gevent",
|
|
client_manager=create_socketio_client_manager(),
|
|
cors_allowed_origins=dify_config.CONSOLE_CORS_ALLOW_ORIGINS,
|
|
),
|
|
)
|