Fernbeobachter

Wenn das Projekt den Rahmen des lokalen Computers sprengt, müssen Sie höchstwahrscheinlich in einige Systeme von Drittanbietern integrieren.


Ich möchte den Fall betrachten, in dem das erwähnte externe System Benachrichtigungen über Änderungen in unserem System erhalten möchte. Zum Beispiel das Aktualisieren eines Produktkatalogs.


Aufgabe


Es gibt eine Handelsplattform, die über WEB-Dienste Zugriff auf ihre Produktbasis bietet. Die Partner der Site möchten so schnell wie möglich über Änderungen in der Datenbank informiert werden.


Lösungsoption


Wir kennen alle unsere Partner, wir können Dokumentation für ihre Software anfordern.


Sie können die Arbeit mit der API unserer Partner implementieren und diese beim Ändern des Produktkatalogs direkt benachrichtigen.


Bei diesem Ansatz muss jeder neue Client einzeln verbunden werden. Wenn der Partner etwas an der Software geändert hat, sind Ressourcen erforderlich, um die Funktionalität wiederherzustellen. Im Allgemeinen zusätzliche Kosten und eine zusätzliche Verantwortungszone.


Ich möchte wirklich keine so engen Beziehungen herstellen. Daher werden wir Folgendes tun.


Nehmen wir das Beobachtermuster als Grundlage. Lassen Sie unsere Kollegen Veranstaltungen abonnieren und erhalten Sie die erforderlichen Benachrichtigungen.


Implementierung


Abonnementaufzeichnungen müssen irgendwo aufbewahrt werden. Die Art der Speicherung bleibt dem Entwickler überlassen. Überlegen Sie, was gespeichert werden muss.


  • Veranstaltung. Es kann viele Arten von Ereignissen geben. Um keine Benachrichtigungen an alle zu senden, müssen Sie wissen, wer was abonniert hat.
  • 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 . , .


Während der Bearbeitung einer Abonnementanfrage wird die Möglichkeit geprüft (canAddEvent-Methode). Es kann alles sein, aber in meinem Fall wird die Begrenzung der Anzahl der Zuhörer überprüft. Nicht mehr als 3 für jeden Ereignistyp.


Außerdem ist natürlich eine Autorisierung erforderlich, um mit solchen API-Methoden arbeiten zu können.


Das ist es im Grunde. Die einfachste Option wird beschrieben. Bei Bedarf können Sie Unterstützung für SOAP- oder Socket-Verbindungen oder ähnliches hinzufügen. Und Sie müssen die Nachricht erneut senden, wenn die Antwort nicht erfolgreich war.


All Articles