Observateur à distance

Si le projet dépassait le cadre de la machine locale, vous devrez probablement vous intégrer à certains systèmes tiers.


Je veux considérer le cas où le système externe mentionné souhaite recevoir des notifications de tout changement dans notre système. Par exemple, mettre à jour un catalogue de produits.


Tâche


Il existe une plateforme de trading qui donne accès à sa base de produits via des services WEB. Les partenaires du site souhaitent connaître au plus vite les modifications de la base de données.


Option de solution


Nous connaissons tous nos partenaires, nous pouvons demander la documentation de leur logiciel.


Vous pouvez implémenter le travail avec l'API de nos partenaires, et lors de la modification du catalogue produit, informez-les directement.


Avec cette approche, chaque nouveau client devra être connecté individuellement. Si le partenaire a modifié quelque chose dans le logiciel, des ressources seront nécessaires pour restaurer la fonctionnalité. En général, des frais supplémentaires et une zone de responsabilité supplémentaire.


Je ne veux vraiment pas établir des liens aussi étroits. Par conséquent, nous ferons ce qui suit.


Prenons le modèle «observateur» comme base. Laissez nos collègues s'abonner aux événements et recevoir les notifications dont ils ont besoin.


la mise en oeuvre


Les enregistrements d'abonnement doivent être conservés quelque part. Le type de stockage restera dans la conscience du développeur. Considérez ce qui doit être stocké.


  • Un événement. Il peut y avoir beaucoup de types d'événements et pour ne pas envoyer d'alertes à tout le monde, vous devez savoir qui s'est abonné à quoi.
  • URL. . HTTP- URL. , .
  • . , ( , , ). , . - . .

, PHP.


, POST- URL. , b2b.api.my-soft.ru/event-subscription. URL event( ).


( Laravel):


public function subscribe()
{
    $request = $this->getRequest();
    $eventName = $request->input('event');
    $url = $request->input('callback');

    $validator = \Validator::make([
        'url' => $url,
        'event' => $eventName
    ], [
        'url' => 'url|required',
        'event' => 'required'
    ]);

    if ($validator->fails()) {
        throw new BadRequestHttpException($validator->errors()->first());
    }

    $repository = $this->getRepository();
    if (!$repository->eventAvailable($eventName)) {
        throw new BadRequestHttpException(trans('api.error.eventSubscription.wrongEvent'));
    }

    if (!$repository->canAddEvent($eventName)) {
        throw new BadRequestHttpException(trans('api.error.eventSubscription.maxCallbacks'));
    }

    $model = $repository->createModel([
        'client_id' => $request->attributes->get('client')->id,
        'event' => $eventName,
        'url' => $url
    ]);
    if ($repository->save($model)) {
        return $this->response($model);
    }
    throw new \Exception();
}

:


  • ,
  • ,
  • ( canAddEvent)
  • ,

.


. , . , .. . .


, , .


.


, , . , , .


, . .


$subscribersRepository->with(['event' => $event->getEventName()])->getActive()->each(function ($model) use ($event) {
    $this->dispatch(new \Commands\RemoteCallback(
        $model->id,
        $model->url,
        $event->getData()->toArray()
    ));
});

.


RemoteCallback :


public function handle(EventSubscriptionRepository $subscriptionRepository)
{
    $client = new \Guzzle\Http\Client();
    $res = $client->post($this->url, [], $this->data, ['connect_timeout' => 3, 'timeout' => 3]);
    try {
        if ($res->send()->getStatusCode() !== 200) {
            throw new \Exception();
        }
        $subscriptionRepository->dropErrors($this->subscriptionId);
    } catch (\Exception $e) {
        $subscriptionRepository->incrementError($this->subscriptionId);
    }
}

. POST- URL. , , .


. . HTTP != 200, . , 3 3 . , .


Lors du traitement d'une demande d'abonnement, la possibilité de celle-ci est vérifiée (méthode canAddEvent). Cela peut être n'importe quoi, mais dans mon cas, la limite du nombre d'auditeurs est vérifiée. Pas plus de 3 pour chaque type d'événement.


De plus, bien sûr, une autorisation est requise pour travailler avec de telles méthodes API.


C'est essentiellement ça. L'option la plus simple est décrite. Si nécessaire, vous pouvez ajouter la prise en charge des connexions SOAP ou socket ou quelque chose comme ça. Et vous devez renvoyer le message si la réponse n'a pas réussi.


All Articles