diff --git a/application/Espo/Core/Binding/DefaultBinding.php b/application/Espo/Core/Binding/DefaultBinding.php index 026d039518..52504fcb2f 100644 --- a/application/Espo/Core/Binding/DefaultBinding.php +++ b/application/Espo/Core/Binding/DefaultBinding.php @@ -198,16 +198,6 @@ class DefaultBinding implements BindingProcessor 'externalAccountClientManager' ); - $binder->bindImplementation( - 'Espo\\Core\\WebSocket\\Sender', - 'Espo\\Core\\WebSocket\\ZeroMQSender' - ); - - $binder->bindImplementation( - 'Espo\\Core\\WebSocket\\Subscriber', - 'Espo\\Core\\WebSocket\\ZeroMQSubscriber' - ); - $binder->bindImplementation( 'Espo\\Core\\Acl\\Table\\TableFactory', 'Espo\\Core\\Acl\\Table\\DefaultTableFactory' diff --git a/application/Espo/Core/WebSocket/SenderFactory.php b/application/Espo/Core/WebSocket/SenderFactory.php new file mode 100644 index 0000000000..0527903eca --- /dev/null +++ b/application/Espo/Core/WebSocket/SenderFactory.php @@ -0,0 +1,66 @@ +injectableFactory = $injectableFactory; + $this->config = $config; + $this->metadata = $metadata; + } + + public function create(): Sender + { + $messager = $this->config->get('webSocketMessager') ?? self::DEFAULT_MESSAGER; + + $className = $this->metadata->get(['app', 'webSocket', 'messagers', $messager, 'senderClassName']); + + if (!$className) { + throw new Error("No sender for messager '{$messager}'."); + } + + return $this->injectableFactory->create($className); + } +} diff --git a/application/Espo/Core/WebSocket/ServerStarter.php b/application/Espo/Core/WebSocket/ServerStarter.php index 30a4c551da..256ef042e6 100644 --- a/application/Espo/Core/WebSocket/ServerStarter.php +++ b/application/Espo/Core/WebSocket/ServerStarter.php @@ -46,6 +46,9 @@ use Ratchet\Wamp\WampServer; */ class ServerStarter { + /** + * @var Subscriber + */ private $subscriber; private $categoriesData; @@ -62,9 +65,9 @@ class ServerStarter private $metadata; - public function __construct(Subscriber $subscriber, Config $config, Metadata $metadata) + public function __construct(SubscriberFactory $subscriberFactory, Config $config, Metadata $metadata) { - $this->subscriber = $subscriber; + $this->subscriber = $subscriberFactory->create(); $this->config = $config; $this->metadata = $metadata; diff --git a/application/Espo/Core/WebSocket/Submission.php b/application/Espo/Core/WebSocket/Submission.php index 7ee94fbcc6..e1352f7d39 100644 --- a/application/Espo/Core/WebSocket/Submission.php +++ b/application/Espo/Core/WebSocket/Submission.php @@ -35,13 +35,16 @@ use stdClass; class Submission { + /** + * @var Sender + */ private $sender; private $log; - public function __construct(Sender $sender, Log $log) + public function __construct(SenderFactory $senderFactory, Log $log) { - $this->sender = $sender; + $this->sender = $senderFactory->create(); $this->log = $log; } diff --git a/application/Espo/Core/WebSocket/SubscriberFactory.php b/application/Espo/Core/WebSocket/SubscriberFactory.php new file mode 100644 index 0000000000..234ddc49f5 --- /dev/null +++ b/application/Espo/Core/WebSocket/SubscriberFactory.php @@ -0,0 +1,66 @@ +injectableFactory = $injectableFactory; + $this->config = $config; + $this->metadata = $metadata; + } + + public function create(): Subscriber + { + $messager = $this->config->get('webSocketMessager') ?? self::DEFAULT_MESSAGER; + + $className = $this->metadata->get(['app', 'webSocket', 'messagers', $messager, 'subscriberClassName']); + + if (!$className) { + throw new Error("No subscriber for messager '{$messager}'."); + } + + return $this->injectableFactory->create($className); + } +} diff --git a/application/Espo/Resources/defaults/config.php b/application/Espo/Resources/defaults/config.php index a5f3b76c7d..7f078f810c 100644 --- a/application/Espo/Resources/defaults/config.php +++ b/application/Espo/Resources/defaults/config.php @@ -154,6 +154,7 @@ return [ 'noteEditThresholdPeriod' => '7 days', 'emailForceUseExternalClient' => false, 'useWebSocket' => false, + 'webSocketMessager' => 'ZeroMQ', 'auth2FAMethodList' => ['Totp'], 'personNameFormat' => 'firstLast', 'newNotificationCountInTitle' => false, diff --git a/application/Espo/Resources/defaults/systemConfig.php b/application/Espo/Resources/defaults/systemConfig.php index 99919f61cd..fafd54c4f9 100644 --- a/application/Espo/Resources/defaults/systemConfig.php +++ b/application/Espo/Resources/defaults/systemConfig.php @@ -118,6 +118,7 @@ return [ 'webSocketPort', 'webSocketZeroMQSubscriberDsn', 'webSocketZeroMQSubmissionDsn', + 'webSocketMessager', 'actualDatabaseType', 'actualDatabaseVersion', ], diff --git a/application/Espo/Resources/metadata/app/metadata.json b/application/Espo/Resources/metadata/app/metadata.json index 58b98a2d34..b06a421d56 100644 --- a/application/Espo/Resources/metadata/app/metadata.json +++ b/application/Espo/Resources/metadata/app/metadata.json @@ -22,6 +22,7 @@ ["app", "actions", "__ANY__", "implementationClassName"], ["app", "fieldProcessing"], ["app", "scheduledJobs"], + ["app", "webSocket", "messagers"], ["selectDefs"], ["recordDefs"], ["aclDefs"], diff --git a/application/Espo/Resources/metadata/app/webSocket.json b/application/Espo/Resources/metadata/app/webSocket.json index 37c3da4e1e..62c14dae1b 100644 --- a/application/Espo/Resources/metadata/app/webSocket.json +++ b/application/Espo/Resources/metadata/app/webSocket.json @@ -9,5 +9,11 @@ "paramList": ["scope", "id"], "accessCheckCommand": "AclCheck --userId=:userId --scope=:scope --id=:id --action=stream" } + }, + "messagers": { + "ZeroMQ": { + "senderClassName": "Espo\\Core\\WebSocket\\ZeroMQSender", + "subscriberClassName": "Espo\\Core\\WebSocket\\ZeroMQSubscriber" + } } }