React(惯性)中的广播给出了意想不到的结果

问题描述 投票:0回答:1

我正在尝试为我的网络应用程序编写一个简单的实时应用程序。我尝试用简单的 php/blade 对其进行编码(使用 Pusher Cdn),程序给出了预期的结果:提交表单时,广播一个新事件,另一个客户端接收消息。当我突然在 Inertia 中尝试它(使用 Laravel-Echo)时,它开始做一些奇怪的事情,例如只需单击一下即可渲染(多次)接收器部分。

Pusher Cdn 和 PHP/Blade:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title inertia>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
  <script src="https://js.pusher.com/8.2.0/pusher.min.js"></script>
        <!-- Scripts -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    </head>
    <body class="font-sans antialiased">
                    <div className="grid place-items-center">
                <h1 className="text-slate-800 text-center p-8 text-7xl font-bold uppercase">
                    Test Page
                </h1>
                <p className="text-slate-500 px-8 text-center mt-3 text-2xl font-bold">
                    This page is dedicated to test a Real Time Chat in React,
                    using Laravel Echo and Pusher. Request will be done using
                    Jquery
                </p>
                <form>
                <button
                    id='btn'
                    className="mt-8 text-center border border-slate-800 bg-slate-800 text-white font-bold text-2xl p-3 rounded"
                >
                    Broadcast
                </button>
                </form>
            </div>
            <div className="mt-48 grid place-items-center">
                <span id="placeholder"></span>
            </div>
    </body>
    <script>

    // Enable pusher logging - don't include this in production
    Pusher.logToConsole = true;
    const pusher = new Pusher("{{ config('broadcasting.connections.pusher.key') }}", {cluster: "eu"});
    const channel = pusher.subscribe('public');
    channel.bind('chat', function(data){
        $.post('/receive', {
            _token: '{{csrf_token()}}',
            message: "Hello, From JS",

        }).done(res => $("#placeholder").last().after(res));
        });

    $("form").submit(function(e){
        e.preventDefault();
        $.ajax({
            url: '/broadcast',
            method:"POST",
            headers: {
                "X-Socket-Id": pusher.connection.socket_id
            },
            data: {
                _token: "{{ csrf_token() }}",
                message: "Hello,From JS"
            }
        }).done(res => $("#placeholder").last().after(res));
    })
    </script>
</html>

Inertia(React)和 Laravel-Echo:

import React from "react";
import $ from "jquery";
import Echo from "laravel-echo";
import Pusher from "pusher-js";
import { CSRF_TOKEN } from "@/Utils/forms";

function Test() {
    window.Pusher = Pusher;
    window.Pusher.logToConsole = true;

    window.Echo = new Echo({
        broadcaster: "pusher",
        key: "c804af4b0e3beefe4880",
        cluster: "eu",
    });
    window.Echo.channel("public").listen(".chat", function (data) {
        $.post("/receive", {
            _token: `${CSRF_TOKEN}`,
            message: "Hello, From JS",
        }).done((res) => $("#placeholder").last().after(res));
    });

    const handleSubmit = (e) => {
        e.preventDefault();
        $.ajax({
            url: "/broadcast",
            method: "POST",
            headers: {
                "X-Socket-Id": window.Echo.socketId(),
            },
            data: {
                _token: CSRF_TOKEN,
                message: "Hello, From JS",
            },
        }).done((res) => $("#placeholder").last().after(res));
    };

    return (
        <>
            <div className="grid place-items-center">
                <h1 className="text-slate-500 text-center p-8 text-7xl font-bold uppercase">
                    Test Page
                </h1>
                <p className="text-slate-300 px-8 text-center mt-3 text-2xl font-bold">
                    This page is dedicated to test a Real Time Chat in React,
                    using Laravel Echo and Pusher. Request will be done using
                    Jquery
                </p>
                <form onSubmit={handleSubmit}>
                    <button
                        type="submit"
                        className="mt-8 text-center border border-slate-800 bg-slate-800 text-white font-bold text-2xl p-3 rounded"
                    >
                        Broadcast
                    </button>
                </form>
            </div>
            <div className="mt-48 grid place-items-center">
                <span id="placeholder"></span>
            </div>
        </>
    );
}

export default Test;

请原谅我乱七八糟的代码。正如我上面所说,该问题仅在使用 Laravel-Echo 时出现

Expected results: 
    Client 1: Hello,From JS broadcast 
    Client 2: Hello, From JS receiver
Actual Results:
    Client 1:  Hello, From JS receiver; Hello,From JS broadcast
    Client 2:  Hello, From JS receiver; Hello, From JS receiver
laravel broadcast pusher inertiajs laravel-echo
1个回答
0
投票

好吧,我正在发布为我解决的问题,以防其他开发人员遇到同样的问题。

    useEffect(() => {
        window.Pusher = Pusher;
        window.Pusher.logToConsole = true;

        window.Echo = new Echo({
            broadcaster: "pusher",
            key: "c804af4b0e3beefe4880",
            cluster: "eu",
        });

        const channel = window.Echo.channel("public");

        channel.listen(".chat", function (data) {
            $.post("/receive", {
                _token: `${CSRF_TOKEN}`,
                message: "Hello, From JS",
            }).done((res) => $("#placeholder").last().after(res));
        });

        return () => {
            // Cleanup when the component unmounts
            channel.unbind(".chat");
        };
    }, []);

    const handleSubmit = (e) => {
        e.preventDefault();
        $.ajax({
            url: "/broadcast",
            method: "POST",
            headers: {
                "X-Socket-Id": window.Echo.socketId(),
            },
            data: {
                _token: CSRF_TOKEN,
                message: "Hello, From JS",
            },
        }).done((res) => $("#placeholder").last().after(res));
    };

我本质上所做的是将负责设置推送器并侦听 useEffect 函数中事件的代码放在一个空数组中。我使用 useEffect 挂钩来确保我们在组件加载时仅设置事件侦听器一次。为了保持整洁,我在 return 语句中添加了一个清理函数

© www.soinside.com 2019 - 2024. All rights reserved.