3

i'm student and beginner, sorry in advance if i don't understand. I try to use Symfony 5 with mercure but i have some difficulty to send an update to the hub. i check the document to Symfony Mercure doc and think to make a good part about that but not all.

i have installed docker on my windows 10 and i install Mercure directly by the Symfony cli like is write on the doc. my parameter is the parameter by default that the cli install. .env

        ###> symfony/mercure-bundle ###
    # See https://symfony.com/doc/current/mercure.html#configuration
    # The URL of the Mercure hub, used by the app to publish updates (can be a local URL)
    MERCURE_URL=https://127.0.0.1:8000/.well-known/mercure
    # The public URL of the Mercure hub, used by the browser to connect
    MERCURE_PUBLIC_URL=https://127.0.0.1:8000/.well-known/mercure
    # The secret used to sign the JWTs
    MERCURE_JWT_SECRET="secret"
###< symfony/mercure-bundle ###

i use a true JWT secret is just for exemple([JWT.io])2.

{
  "mercure": {
    "publish": [
      "*"
    ]
  }
}

with my secret password.

i create an js file with the eventSource.

const eventSource = new EventSource('http://127.0.0.1:8000/.well-known/mercure?topic=' + encodeURIComponent('http://127.0.0.1:8000/commande/recapitulatif'),
    );
eventSource.onmessage = event => {
    // Will be called every time an update is published by the server
    alert("Commande");
    console.log(JSON.parse(event.data));
}

and i would like a notification to be send when somebody access to the recap order : http://127.0.0.1:8000/commande/recapitulatif. In my controller when the address http://127.0.0.1:8000/commande/recapitulatif is call i add:

 $update = new Update(
            'http://127.0.0.1:8000/commande/recapitulatif',
            json_encode(['status' => 'Commande'])
        );

        $hub->publish($update);

on the page where i need to have the notification and add the js code, if i check the connection with mercure in network of the app dev of chrome i can see this:

Request URL: http://127.0.0.1:8000/.well-known/mercure?topic=http%3A%2F%2F127.0.0.1%3A8000%2Fcommande%2Frecapitulatif
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8000
Referrer Policy: strict-origin-when-cross-origin

but when i try to go to the url http://127.0.0.1:8000/commande/recapitulatif i have an error (Failed to send an update) and (SSL connect error for "https://127.0.0.1:8000/.well-known/mercure".)

Update: i change

MERCURE_URL=https://127.0.0.1:8000/.well-known/mercure

MERCURE_PUBLIC_URL=https://127.0.0.1:8000/.well-known/mercure

to

MERCURE_URL=http://127.0.0.1:8000/.well-known/mercure

MERCURE_PUBLIC_URL=http://127.0.0.1:8000/.well-known/mercure

and now with the error (failed to send an update) i have (HTTP/1.1 401 Unauthorized returned for "http://127.0.0.1:8000/.well-known/mercure".)

probably i need to put my app to https for have a ssl connection with mercure ?

An other try. i replace hhttp where i change https to http to my .env and js file. After that i change the code in my controller like this:

 $discovery->addLink($request);

    $response = new JsonResponse([
        '@id' => 'http://127.0.0.1:8000/commande/recapitulatif',
        'status' => 'Order',
    ]);

    $response->headers->setCookie(
        $authorization->createCookie($request, ['http://127.0.0.1:8000/commande/recapitulatif'])
    );

Now i don't have error but nothing is notified to my brower.

my log for the page i want notification:

[Application] Jun 26 17:33:45 |DEBUG  | SECURI Stored the security token in the session. key="_security_main"
[Web Server ] Jun 26 19:33:45 |INFO   | SERVER GET  (200) /favicon.ico ip="127.0.0.1"
[Application] Jun 26 17:33:46 |INFO   | REQUES Matched route "_wdt". method="GET" request_uri="http://127.0.0.1:8000/_wdt/8f2711" route="_wdt" route_parameters={"_controller":"web_profiler.controller.profiler::toolbarAction","_route
":"_wdt","token":"8f2711"}
[Web Server ] Jun 26 19:33:47 |INFO   | SERVER GET  (200) /_wdt/8f2711 ip="127.0.0.1"

and the log where i need to send the notificaton:

[Application] Jun 26 17:36:06 |DEBUG  | SECURI Stored the security token in the session. key="_security_main"
[Web Server ] Jun 26 19:36:06 |INFO   | SERVER POST (200) /commande/recapitulatif host="127.0.0.1:8004" ip="127.0.0.1" scheme="https"
[Application] Jun 26 17:36:07 |INFO   | REQUES Matched route "_wdt". method="GET" request_uri="http://127.0.0.1:8000/_wdt/d13a0f" route="_wdt" route_parameters={"_controller":"web_profiler.controller.profiler::toolbarAction","_route
":"_wdt","token":"d13a0f"}
[Web Server ] Jun 26 19:36:08 |INFO   | SERVER GET  (200) /_wdt/d13a0f ip="127.0.0.1"

but if i add the update like this:

 $update = new Update(
                'http://127.0.0.1:8000/commande/recapitulatif',
                json_encode(['status' => 'Commande']), true
            );

            $hub->publish($update);

my log are like this:

[Application] Jun 26 18:02:39 |INFO   | HTTP_C Request: "POST http://127.0.0.1:8000/.well-known/mercure"
[Application] Jun 26 18:02:39 |INFO   | HTTP_C Response: "401 http://127.0.0.1:8000/.well-known/mercure"
[Application] Jun 26 18:02:39 |CRITICA| REQUES Uncaught PHP Exception Symfony\Component\Mercure\Exception\RuntimeException: "Failed to send an update." at C:\laragon\www\Projet\Restaurant\RelaisDesVoutes\vendor\symfony\mercure\src\H
ub.php line 104
[Web Server ] Jun 26 20:02:39 |INFO   | MERCUR Topic selectors not matched, not provided or authorization error
[Web Server ] Jun 26 20:02:39 |WARN   | SERVER POST (401) /.well-known/mercure host="127.0.0.1:8004" ip="127.0.0.1" scheme="https"
[Application] Jun 26 18:02:39 |DEBUG  | SECURI Stored the security token in the session. key="_security_main"
[Web Server ] Jun 26 20:02:39 |ERROR  | SERVER POST (500) /commande/recapitulatif host="127.0.0.1:8004" ip="127.0.0.1" scheme="https"

If somebody can help me to understand where is my problem, thank you verry much.

devstudent
  • 31
  • 5

1 Answers1

0

I assume you've got the separate Mercure binary running & installed. You can't have both the Mercure binary and Symfony running on port 8000 together. Depending on your version (I am running Mercure v0.9.0 because of a tutorial I followed) you might be able to get away with making a Makefile like this

mercure_server:
    JWT_KEY=my_key ADDR=localhost:3000 ALLOW_ANONYMOUS=1 CORS_ALLOWED_ORIGINS=http://localhost:8000 ./bin/mercure

Then running make mercure_server

This assumes you have the mercure binary in the bin directory of your project. This command will not work with the latest version of Mercure because it's not how the environment variables are set.

The newer version of the Mercure binary runs a modified version of the Caddy Web server and the compatibility with Symfony is not super well documented from what I had read thus far. I would consider downgrading to v0.9.0 if you're in a pinch because there are more resources available surrounding that.

Ervin Šabić
  • 115
  • 3
  • 14