在React应用中触发一个事件到私有频道

18

我想触发一个事件到Pusher私有频道,我的服务器端语言是Laravel。我查阅了很多资源,但我没有找到一个全面的方法来覆盖服务端和前端。最后我找到了这个解决方案。 第一步:

 export const SendChat = () => {
    try {
        var pusher = new Pusher('YOUR_APP_KEY', {
            cluster: 'ap2',
            forceTLS: true,
            authTransport: 'jsonp',
            authEndpoint: `${baseUrl}pusher/auth`,
        });
        var channel = pusher.subscribe('private-channel');
        channel.bind('pusher:subscription_succeeded', function() {
            var triggered = channel.trigger('client-EVENT_NAME', { 'message': 'Hi ....' });
            console.log(triggered)
        });

    } catch (error) {
        console.error(error);
    }
}

并在某处调用它

<Button onClick={this.props.SendChat}  waves='light' >Send</Button>

您必须在Pusher帐户设置中启用客户端事件

login to your pusher account -> select the channel ->App Settings -> select Enable client events -> update

在此之后添加您的应用程序密钥、频道名称和事件名称,然后我们需要在服务器端进行授权。这是示例 Laravel 代码,首先在 web.php 中添加此路由。

添加您的应用程序密钥、频道名称和事件名称,然后我们需要在服务器端进行授权。这是示例 Laravel 代码,首先在 web.php 中添加此路由。

Route::get('pusher/auth', 'PusherController@pusherAuth');

将 PusherController.php 修改为以下内容:

public function pusherAuth()
{
    $user = auth()->user();

    if ($user) {
        $pusher = new Pusher('auth_key', 'secret', 'app_id');
        $auth= $pusher->socket_auth(Input::get('channel_name'), Input::get('socket_id'));
        $callback = str_replace('\\', '', $_GET['callback']);
        header('Content-Type: application/javascript');
        echo($callback . '(' . $auth . ');');
        return;
    }else {
        header('', true, 403);
        echo "Forbidden";
        return;
    }
}

测试一下,你应该能看到像这样的东西

 Pusher : State changed : connecting -> connected with new socket ID 3953.****556
Pusher : Event sent : {"event":"pusher:subscribe","data":{"auth":"83045ed1350e63c912f5:328fb78165d01f7d6ef3bb6d4a30e07c9c0ad0283751fc2c34d484d4fd744be2","channel":"private-chat"}}
Pusher : Event sent : {"event":"client-MessageSent","data":{"message":"Hi ...."},"channel":"private-chat"}
true

1
谢谢。我想知道这段代码是否也适用于React-Native? - Moein Hosseini
1
你能否编辑你的问题,提供你所面临的问题的信息,包括错误。 - doydoy
我们可以使用 authTransport: 'json' 替代 authTransport: 'jsonp' 吗? - Moein Hosseini
好的,谢谢您的回复。 - Moein Hosseini
你好,祝你好运。 - Bakhtiar
显示剩余2条评论
2个回答

1

无论您使用哪种客户端语言,都没有太大关系。Angular、Vue和React都是JS框架和库。您可以考虑使用通用的JS代码,将其放置在所有3个应用程序中。

让我尽力给出我所知道的详细答案。

为了开始,您应该首先尝试在没有Pusher的情况下完成聊天场景。即:用户应该能够通过API从前端发送消息,并将其存储在数据库中。

完成此操作后,非常容易将Pusher包含在流程中。(简单地说,您需要广播一个事件,这将通知Socket Server向通道上的所有/其他用户广播消息)

对于Pusher身份验证,您不需要显式创建路由和方法。一旦您在config/app.php中取消注释BroadcastServiceProvider,您就可以运行:

php artisan route:list

同时,您会看到一个广播路由broadcasting/auth

您可以使用此路由进行身份验证。不过,您可以进行一些更改并在其前面添加/api

进入BroadcastServiceProvider.php文件,并将boot方法替换为:

public function boot()
    {
        Broadcast::routes(
            [
                'prefix' => 'api',
                'as' => 'api.broadcasting.auth',
                'middleware' => ['auth:sanctum'],
            ]
        );

        require base_path('routes/channels.php');
    }

我假设您正在使用Laravel Sanctum进行身份验证。如果没有,请将身份验证中间件更改为您的提供程序。
完成后,您可以使用此auth路由从前端进行身份验证。所以,我在ReactJS中创建了一个服务,并在构造函数中创建了一个Pusher实例:
this.pusher = new Pusher(PUSHER_APP_KEY, {
        authEndpoint: 'http:localhost:8000/api/broadcasting/auth',
        cluster: PUSHER_CLUSTER,
        useTLS: true,
        auth: {
            headers: {
                Authorization: 'Bearer ' + authHeader
            }
        }
    });

您只需要实例化一次Pusher并在整个应用程序中使用此实例。因此,我为Pusher创建了一个服务类。

如果您希望现在事情变得简单,您需要在使用pusher的页面上执行此代码。页面加载后,您需要调用此代码。所以,您将执行以下操作:

let pusher = null;

useEffect(() => {
  pusher = new Pusher(PUSHER_APP_KEY, {
            authEndpoint: 'http:localhost:8000/api/broadcasting/auth',
            cluster: PUSHER_CLUSTER,
            useTLS: true,
            auth: {
                headers: {
                    Authorization: 'Bearer ' + authHeader
                }
            }
        });
}, []);

因此,我们在我们的函数组件或页面中拥有了Pusher的实例。

现在,我们需要订阅频道。

使用这个Pusher实例,我们可以订阅频道。如果您已经按照同一页上的useEffect方法进行操作,那么在获取实例后,您可以使用以下代码订阅频道并绑定事件:

const channel = pusher.subscribe('private-chat.' + channelName)

同时,您可以执行以下操作来绑定事件:

channel.bind('event.name', function(data) {
  console.log(data);
});

请确保将“channelName”和“event.name”分别替换为您的频道和事件名称。
现在,一旦从后端广播您的事件,您就可以收听它了。
因此,您将从后端执行以下操作。 您将拥有一个方法,该方法将消息存储在数据库中,因此,假设该代码如下:
public function sendMessage (Request $request){
  //.... Rest of the logic

  $user = $request->user();

  // Store the message
  $chatMessage = $chat->messages()->create([
      'message' => $message,
      'sender_id' => $user->id
  ]);
  
  broadcast(new NewMessage($user, $chatMessage))->toOthers();
  
  //... Rest of the logic
}

这条广播消息会发送到聊天中的其他用户。

我希望这个答案能给你一个好的思路和方向。


这个在React Native中能用吗? - NAZIR HUSSAIN
我还没有测试过React-Native,但它是后端更改,我相信它对于任何JS框架都能正常工作。 - Hesan Naveed

-1

如果要在Laravel上使用Pusher进行WebSocket工作,我建议在React部分使用Laravel Echo包。在后端方面,在config/broadcasting.php中设置Pusher的配置。 有关如何在后端和前端使用Pusher的官方文档,请参见Laravel的更多详细信息。 https://laravel.com/docs/8.x/broadcasting#pusher-channels


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接