如何在 Vue 项目中实现 laravel-echo 客户端

axs*_*sor 5 php events broadcast laravel vue.js

我正在开发一个使用Vuetify (Vue.js) 作为前端的应用程序,它与 api 通信到Laravel后端服务器。

我正在尝试使用laravel-echo-serversocket.io制作一个通知系统。并在客户端中使用 laravel-echo。

我用于客户端组件以测试连接是否有效的代码是:

// Needed by laravel-echo
window.io = require('socket.io-client')

let token = this.$store.getters.token

let echo = new Echo({
  broadcaster: 'socket.io',
  host: 'http://localhost:6001',
  auth: {
    headers: {
      authorization: 'Bearer ' + token,
      'X-CSRF-TOKEN': 'too_long_csrf_token_hardcoded'
    }
  }
})

echo.private('Prova').listen('Prova', () => {
  console.log('IT WORKS!')
})
Run Code Online (Sandbox Code Playgroud)

这是代码 laravel-echo-server.json

{
    "authHost": "http://gac-backend.test",
    "authEndpoint": "/broadcasting/auth",
    "clients": [],
    "database": "redis",
    "databaseConfig": {
        "redis": {},
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": null,
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "apiOriginAllow": {
        "allowCors": false,
        "allowOrigin": "",
        "allowMethods": "",
        "allowHeaders": ""
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图修改apiOriginsAllow没有成功。事件被调度,我可以在laravel-echo-server日志中看到它:

Channel: Prova
Event: App\Events\Prova
Run Code Online (Sandbox Code Playgroud)

但在那之后,当我访问包含连接代码的客户端组件时,我可以在 laravel-echo-server 日志中看到长错误跟踪和下一个错误:

The client cannot be authenticated, got HTTP status 419
Run Code Online (Sandbox Code Playgroud)

如您所见,我在 laravel echo 客户端的标头中指定了 csrf 令牌和授权令牌。但它不起作用。

这是代码routes/channels.php

Broadcast::channel('Prova', function ($user) {
    return true;
});
Run Code Online (Sandbox Code Playgroud)

我只想听一个事件,它是私有的还是公共的并不重要,因为当它起作用时,我想将它放入 service worker。然后,我想如果它是公开的,那就更好了。

  • 如何在 laravel 项目之外使用 laravel echo 客户端?
  • 如果我制作私人事件并尝试将其监听到 service worker 会出现问题吗?

axs*_*sor 1

为了启动客户端侦听器,我使用了 Vuex。然后,当我的应用程序启动时,我调度该操作INIT_CHANNEL_LISTENERS来启动侦听器。

\n\n

通道 MODULE vuex 的index.js

\n\n
import actions from \'./actions\'\nimport Echo from \'laravel-echo\'\nimport getters from \'./getters\'\nimport mutations from \'./mutations\'\n\nwindow.io = require(\'socket.io-client\')\n\nexport default {\n  state: {\n    channel_listening: false,\n    echo: new Echo({\n      broadcaster: \'socket.io\',\n      // host: \'http://localhost:6001\'\n      host: process.env.CHANNEL_URL\n    }),\n    notifiable_public_channels: [\n      {\n        channel: \'Notificacio\',\n        event: \'Notificacio\'\n      },\n      {\n        channel: \'EstatRepetidor\',\n        event: \'BroadcastEstatRepetidor\'\n      }\n    ]\n  },\n  actions,\n  getters,\n  mutations\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

通道 MODULE vuex 的 actions.js

\n\n
import * as actions from \'../action-types\'\nimport { notifyMe } from \'../../helpers\'\n// import { notifyMe } from \'../../helpers\'\n\nexport default {\n  /*\n  * S\'entent com a notifiable un event que t\xc3\xa9 "t\xc3\xadtol" i "message" (Per introduir-los a la notificaci\xc3\xb3)\n  * */\n  /**\n   * Inicialitza tots els listeners per als canals. Creat de forma que es pugui ampliar.\n   * En cas de voler afegir m\xc3\xa9s canals "Notifiables" s\'ha de afegir un registre al state del index.js d\'aquest modul.\n   * @param context\n   */\n  [ actions.INIT_CHANNEL_LISTENERS ] (context) {\n    console.log(\'Initializing channel listeners...\')\n    context.commit(\'SET_CHANNEL_LISTENING\', true)\n\n    context.getters.notifiable_public_channels.forEach(listener => {\n      context.dispatch(actions.INIT_PUBLIC_NOTIFIABLE_CHANNEL_LISTENER, listener)\n    })\n    // }\n  },\n\n  /**\n   * Inicialitza un event notificable a trav\xc3\xa9s d\'un canal.\n   * Per anar b\xc3\xa9 hauria de tenir un titol i un missatge.\n   * @param context\n   * @param listener\n   */\n  [ actions.INIT_PUBLIC_NOTIFIABLE_CHANNEL_LISTENER ] (context, listener) {\n    context.getters.echo.channel(listener.channel).listen(listener.event, payload => {\n      notifyMe(payload.message, payload.title)\n    })\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

助手中的notifyMe函数\n该函数在浏览器上发送通知

\n\n
export function notifyMe (message, titol = \'TITLE\', icon = icon) {\n  if (!(\'Notification\' in window)) {\n    console.error(\'This browser does not support desktop notification\')\n  } else if (Notification.permission === \'granted\') {\n    let notification = new Notification(titol, {\n      icon: icon,\n      body: message,\n      vibrate: [100, 50, 100],\n      data: {\n        dateOfArrival: Date.now(),\n        primaryKey: 1\n      }\n    })\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后后端像问题一样使用 laravel-echo-server 。使用redis对事件和supervisor进行队列在服务器启动时启动 laravel-echo-server。

\n