如何使用 React 连接到 Laravel Websocket?

How to connect to Laravel Websocket with React?

我正在构建一个订购应用程序,我用 Laravel 做后端,用 ReactJSReact Native

做前端

我希望在客户发布订单和订单更新时实时更新。

目前,我设法获得了使用推送器的 WebSocket 运行 API using devmarketer 他的教程。

我在控制台中成功回应了命令,但现在我想使用我的 react 应用

访问 channel

而这一步是我遇到困难的地方。

因为我不确定如何创建我的应用程序都可以访问的 route 以及如何通过此路由访问频道。

官方 laravel 文档提供了一个示例,说明如何访问推送器,但没有说明如何使用外部连接(例如:我的本机反应应用程序)连接到它

window.Echo = new Echo({
  broadcaster: 'pusher',
  key: 'rapio1',
  host: 'http://backend.rapio',
  authEndpoint: 'http://backend.rapio/broadcasting/auth',
  auth: {
    headers: {
      // Authorization: `Bearer ${token}`,
      Accept: 'application/json',
    },
  }
  // encrypted: true
});
window.Echo.channel('rapio.1').listen('OrderPushed', (e) =>{
    console.log(e.order)
})

所以我的问题是如何在我的 React 应用程序上访问广播频道?

添加了后端事件


class OrderPushed implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $neworder;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Order $neworder)
    {
        $this->neworder = $neworder;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        //return new Channel('Rapio.'.$this->neworder->id);
       return new Channel('Rapio');

    }
    public function broadcastWith()
    {
        return [
            'status' => $this->neworder->status,
            'user' => $this->neworder->user->id,
        ];
    }
}

如果您只需 console.log 到控制台就可以访问前端的数据,那么您应该已经完成​​大部分工作了。

将数据实际导入 React 组件的方式取决于您使用的是状态管理库(例如 redux)还是纯粹的 React。

基本上,您会在前端维护数据的本地副本,然后使用 Echo 事件更新该数据。例如,你可以在 redux、你的一个反应组件或其他地方有一个订单列表,你可以根据创建、更新和删除事件追加和修改它。

我个人会在后端创建一个 OrderCreatedOrderUpdatedOrderDeleted 事件,其中包含给定的订单模型。

class OrdersList extends React.Component {
    componentDidMount() {
        this.fetchInitialDataUsingHttp();

        //Set up listeners when the component is being mounted
        window.Echo.channel('rapio.1').listen('OrderCreated', (e) =>{
            this.addNewOrder(e.order);
        }).listen('OrderUpdated', (e) =>{
            this.updateOrder(e.order);
        }).listen('OrderDeleted', (e) =>{
            this.removeOrder(e.order);
        });
    }

    componentWillUnmount() {
        //@TODO: Disconnect echo
    }
}

您是否在后端使用 broadcastAs() 方法?

为了正确回答您的问题,了解这一点很重要,因为如果您是,Laravel 回显客户端假定名称空间是 App\OrderPushed。

当使用 broadcastAs() 时,你需要在它前面加上一个点,告诉 echo 不要使用命名空间,所以在你的例子中,它将是:

.listen('.OrderPushed')

另外,您不需要在后端做任何额外的设置,以便每个客户端应用程序连接到套接字服务器,除非您想要一个 multi-tenancy 设置,不同的后端应用程序将使用 WebSockets 服务器。

我还使用 wsHostwsPort 而不仅仅是主机和端口,但不确定这是否有所不同