如檔案中所述,我使用以下命令安裝了mercure:
composer require mercure
之后,我應該啟動美居服務器,問題是:如何?
Symfony 的檔案沒有說明這一點。
Mercure 的檔案也沒有說明任何內容,尤其是使用/config/packages/mercure.yaml.
我發現我需要下載一個單獨的二進制檔案(對于我的特定平臺),然后我應該使用以下命令從 Powershell 啟動服務器:
.\/bin/mercure run
但是,如果我嘗試通過-envfile ".env",那么它甚至不會嘗試使用內部的任何變數。
最重要的是,它似乎根本沒有使用任何環境變數,即使是我在 cmd.xml 中定義的環境變數。
還有其他一些事情,比如我如何允許 CORS,因為我的組態檔中沒有任何東西可以更改,它不是我可以傳遞給二進制檔案的引數,也不能將其添加為環境變數。
如果我曾經嘗試訂閱該事件(由于之前的問題在 2019 埠上完成),則回傳 404 和 CORS。
這也是我得到的.\/bin/mercure run:

我的.env:

現在我想知道我應該如何使用mercure,我看過幾個symfony 5.4的視頻,它們基本上要么在linux上,而且它以某種方式對他們有用,要么它被標記為配置更改、語法更改的過時原因和別的...
該檔案在這方面也沒有任何幫助,這讓我后悔嘗試使用mercure。
編輯:
I was told to try fiddling with Caddy configs, but it doesn't seem like mercure is trying to use those either, even tried specifying the config with -config.
Result:
- Port not set to 3000
- No allow_cors header
Caddyfile:
# Learn how to configure the Mercure.rocks Hub on https://mercure.rocks/docs/hub/config
{
{$GLOBAL_OPTIONS}
http_port 3000
https_port 3000
}
localhost:3000
route {
encode zstd gzip
@origin header Origin http://localhost:8000
header @origin Access-Control-Allow-Origin "http://localhost:8000"
header @origin Access-Control-Request-Method GET
header Access-Control-Allow-Credentials "true"
mercure {
# Publisher JWT key
publisher_jwt "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.iHLdpAEjX4BqCsHJEegxRmO-Y6sMxXwNATrQyRNt3GY"
subscriber_jwt "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InN1YnNjcmliZSI6WyIqIl19fQ.0J4jgLQSHzPMTZ5jiYM8Yv7jmTANRgILG5FKY98LgEU"
publish_origins *
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
respond /healthz 200
respond "Not Found" 404
}
at this point, i feel like i'm using every tricks in the book and it still doesn't work, i'm probably gonna end up moving to periodic fetch instead, reliable and actually work.
Update 1:
- Server Start on port 3000
- CORS is now allowed
- 401 whenever i try to request a topic
Update 2:
No HTTP errors, event is apparently subscribed from what mercure say, but nothing received, something tell me mercure doesn't support semantics
Update 3:
With a topic such as /update/test/{0}, set in the update, the event source and yaml config, no updates are received on the client
Update 4:
i cannot get updates to work at all, either with or without semantics, here is my config and route atm:
mercure.yaml :
mercure:
hubs:
default:
url: '%env(MERCURE_URL)%'
public_url: '%env(MERCURE_PUBLIC_URL)%'
jwt:
secret: '%env(MERCURE_JWT_SECRET)%'
publish: '["/update/test/*"]'
subscribe: '["/update/test/*"]'
My route (DefaultController):
#[Route('/update/test/{id}', name: 'test')]
public function test(HubInterface $hub, ?int $id): Response
{
$update = new Update("localhost:8000/update/test/{$id}",
son_encode(
array(
"result" => "success",
"data" => "User is in Room {$id}"
)
)
);
$hub->publish($update);
return new Response("Success");
}
uj5u.com熱心網友回復:
我會給你一個在不使用 Docker 的情況下在 windows 上運行的 Mercure 示例,對不起我的英語好嗎?!
我將從安裝帶有 SSL 虛擬主機的 symfony 5.4 開始:https://myshop.local和 MercureBundle。
例如,目標是在新產品進入商店庫存時通知所有經過身份驗證的用戶。
第一:mercure hub 和您的站點必須在同一個域或子域上運行,否則無法共享 auth cookie;因此我們的 Mercure 集線器將在https://myshop.local:3000上運行(同一個域,但另一個埠,請檢查您的防火墻)
第二:設定適當的環境變數是必要的,所以在你的.env.local:
###> 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://myshop.local:3000/.well-known/mercure
# The public URL of the Mercure hub, used by the browser to connect
MERCURE_PUBLIC_URL=https://myshop.local:3000/.well-known/mercure
# The secret used to sign the JWTs
MERCURE_JWT_SECRET=m3rcu353cr37pa55pra53DEV
###< symfony/mercure-bundle ###
第三:美居它基于主題概念(喜歡頻道),所以你的mercure.yaml食譜:
mercure:
hubs:
default:
url: '%env(MERCURE_URL)%'
public_url: '%env(MERCURE_PUBLIC_URL)%'
jwt:
secret: '%env(MERCURE_JWT_SECRET)%'
publish: ['notif/out-of-stock'] # the topic or topics where the notifications will be published coming from the mercure hub.
subscribe: ['notif/out-of-stock'] # the topic or topics to which users will subscribe to receive notifications.
第四:您需要下載mercure的Windows二進制檔案,并在Caddy檔案中設定一些配置:
# Learn how to configure the Mercure.rocks Hub on https://mercure.rocks/docs/hub/config
{
{$GLOBAL_OPTIONS}
}
{$SERVER_NAME:myshop.local:3000}
log
tls C:\wamp64\bin\apache\apache2.4.41\conf\ssl\myshop.local.crt C:\wamp64\bin\apache\apache2.4.41\conf\ssl\myshop.local.key
route {
encode zstd gzip
mercure {
# Transport to use (default to Bolt)
transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db}
# Publisher JWT key
publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# Subscriber JWT key
subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
cors_origins https://myshop.local
publish_origins https://myshop.local
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
respond /healthz 200
respond "Not Found" 404
}
這里有三個重要方面:
- $SERVER_NAME
- log指令:您必須設定虛擬主機 SSL 證書的 .crt 和 .key 檔案的路徑。
- cors_origins和publish_origins必須設定您的 webapp 域以避免 CORS 錯誤
第五:您必須從您的電源外殼運行您的美居服務器;從您的 Mercure 二進制目錄中運行:$env:MERCURE_PUBLISHER_JWT_KEY='m3rcu353cr37pa55pra53DEV';$env:MERCURE_SUBSCRIBER_JWT_KEY='m3rcu353cr37pa55pra53DEV';.\mercure.exe run -config .\Caddyfile
重要!!:該鍵與環境變數相同MERCURE_JWT_SECRET
現在從控制器,您必須在主題上發布通知:
public function publishNewProductAction(Symfony\Component\Mercure\HubInterface $mercureHub):Response{
/** insert new product to a database **/
...
$em->persist($newProduct);
$em->flush();
$data=['productName'=>$newProduct->getName(), 'productPrice'=>$newProduct->getPrice()];
$update = new Symfony\Component\Mercure\Update();
$hubUpdate = new Symfony\Component\Mercure\Update(
'notif/new-product', # the topic where you go to publish
\json_encode($data), # the data that you want to publish on the mercure hub
true # indicate that need auth
);
return new Response('A new product has been registered!!'); # its the normal response to user that insert a product (admin user for exmple)
}
重要提示:symfony 創建實時通知系統的真正威力在于將 Messenger 組件和異步佇列與 Mercure 相結合。你可以調查一下。
因此,例如在客戶端:
<script type="text/javascript">
$(document).ready(function () {
const eventSource = new EventSource("{{ mercure('notif/out-of-stock', { subscribe:'notif/out-of-stock'})|escape('js')}}", {withCredentials: true});
eventSource.onopen = function () {
console.log('Socket connection!');
};
eventSource.onmessage = function (e) {
var data = JSON.parse(e.data);
console.log('A new product is enable for you: ' data.productName '. Price: $' data.price);
};
eventSource.onerror = function () {
console.log('Socket error!');
};
});
</script>
uj5u.com熱心網友回復:
你有一些錯誤。首先:在您的 mercure.yaml 中,您必須以這種方式建立主題:
publish: ["update/test/{id}"] # your topic must complie with this format
subscribe: ["update/test/{id}"]
在您的環境變數中,您設定MERCURE_JWT_SECRETsymfony-mercure-bundle 以及在 mercure.yaml 中宣告的主題和訂閱者,完成傳遞給集線器的 JWT,您不需要將其設定到 de Caddy 檔案中。
并且,在您的功能中:
#[Route('/update/test/{id}', name: 'test')]
public function test(HubInterface $hub, ?int $id): Response
{
$update = new Update(sprintf("update/test/%s", $id)),
json_encode(
array(
"result" => "success",
"data" => sprintf("User is in Room %s", $id)
)
)
);
$hub->publish($update);
return new Response("Success");
}
考慮到作為 Update 的引數傳遞的 URI 段,不包含字符“{}”
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/454065.html
