Как отправить сообщение от клиента на сервер через WebSocket в Laravel с помощью Laravel WebSockets?

WebSocket обеспечивает двустороннюю связь: сервер может отправлять сообщения браузеру, а браузер - клиент - может отвечать через то же соединение.

Я реализую приложение чата в Laravel 6, используя:

Я уже понял, что сервер запускает события, а клиент прослушивает эти события следующим образом.

  1. Установите пакет Laravel WebSockets.

composer require beyondcode/laravel-websockets

  1. Настроить config/broadcasting.php.
        'pusher' => [
            'driver' => 'pusher',
            'key' => xxx,
            'secret' => xxx,
            'app_id' => xxx,
            'options' => [
                'cluster' => xxx,
                'encrypted' => true,
                'useTLS' => true, 
                'host' => '127.0.0.1',
                'port' => 6001,
                'scheme' => 'https',
            ],
        ],
    ]
  1. Настроить config/websockets.php
'apps' => [
        [
            'id' => xxx,
            'name' => xxx,
            'key' => xxx,
            'secret' => xxx,
            'enable_client_messages' => true,
            'enable_statistics' => true,
        ],
    ],
  1. Установить Pusher сервер.

composer require pusher/pusher-php-server "~3.0"

  1. Установите драйвер вещания для использования pusher в .env файл.

BROADCAST_DRIVER=pusher

  1. Использовать laravel-echo а также pusher-js на моей клиентской стороне.
import Echo from "laravel-echo"

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    wsHost: window.location.hostname,
    wsPort: 6001,
    disableStats: true,
});
  1. Запустите сервер WebSockets.

php artisan websockets:serve

  1. На стороне сервера запускайте события с помощью класса событий, который реализует ShouldBroadcastNow учебный класс.

event(new MyEventClass((object)$message));

Все нормально работает. На шаге 8 я инициирую события на стороне сервера.

Обратите внимание, что я не использую официальный сервер Pusher, я просто использую реализации API Pusher и pusher-js но укажите Laravel Echo JavaScript package к местным Laravel WebSockets server, настроенный на шаге 6.

Прошу не путать Laravel Echo JavaScript package с laravel-echo-server из Socket.IO Server. Я не используюSocket.IO Server.

Теперь вместо запуска событий на стороне сервера, как показано на шаге 8, я хочу отслеживать события на стороне клиента, поскольку WebSocket допускает двустороннюю связь. Как я могу сделать это вLaravel с Laravel Echo JavaScript Package, Laravel WebSockets PHP package?

4 ответа

См. Эту документацию: https://pusher.com/docs/channels/using_channels/events#triggering-client-events

Согласно документации pusher, инициализируйте свой интерфейс, используя этот

       this.echo = new Pusher('mykey', {
    wsHost: 'localhost',
    wsPort: 6001,
    forceTLS: false,
    disableStats: true,
    enabledTransports: ['ws', 'wss']
  });

используйте это, чтобы вызвать ваше событие

      var channel = this.echo.subscribe("private-channel");
channel.bind("pusher:subscription_succeeded", () => {
var triggered = channel.trigger("client-someEventName", {
   your: "data",
 });
});

Для всех, кто может столкнуться с этой проблемой.

Вам не нужно эхо, и вы должны создавать экземпляр напрямую из Pusher

const my_pusher = new Pusher("APP_KEY", {
        cluster: 'mt1',
        wsHost: window.location.hostname,
        wsPort: 6001,
        forceTLS: false,
        disableStats: true,
    });

И чтобы отправить сообщение на сервер:

my_pusher.send_event('EVENT_NAME',{'ANYTHING':'YOU_WANT'})

После инициализации Echo вам нужно прослушивать определенный канал в вашем интерфейсе. Я покажу код Vue, но внесу соответствующие изменения:

Файл Vue

export default {
    methods: {
        sendCommand(command) {
            axios.post('/api/command', { 'command': command })
            .then((res) => {
                //
            })
        }
    },
    mounted() {
        Echo.channel('xxx')
        .listen('.weight-change', (e) => {
            this.weight = e.weight
        })
    }
}

Здесь вы можете видеть, что все входящие сообщения захватываются в части кода для прослушивания, а отправка нового сообщения выполняется с помощью маршрута api на бэкэнде, который отправляет их в канал Echo.

Пожалуйста, дайте мне знать, если вам нужны пояснения.

Возможно, я ошибаюсь, но я не верю, что вы можете подтолкнуть Pusher с их pusher-jsупаковка. Вот что pusher-php-server composer пакет предназначен для.

Для этого может быть пакет узлов, но зачем вы пытаетесь изобретать велосипед? Просто используйте axios или действие Vuex для публикации на одном из ваших маршрутов, чтобы запустить ваше событие, а затем позвольте Echo получить ответ.

Вам даже не нужно создавать контроллер, просто используйте закрытие маршрута и запустите свое событие. Axios или Vuex будут возвращать Promise, поэтому вы можете дождаться ответа в своем компоненте или в своем действии Vuex.

Я мог бы понять, пытались ли вы реализовать другой тип драйвера для Broadcast, например RabbitMQ или Rachet или что-то в этом роде, но он спроектирован как своего рода круговой цикл, ударил вашу конечную точку из js, запустил событие из PHP, пусть Pusher/ или веб-сокеты, получайте свою трансляцию обратно в js.

Другие вопросы по тегам