目前的项目中(laravel+vue 前后分离)有一个入金充值的功能,用户点击入金按钮 请求第三方接口,第三方将处理结果返回给指定的回调地址
前台要根据处理结果跳转到不同的页面,可以使用轮询 订单状态,然而想通过websocket方式来处理. 前后台通过laravel-echo-server 建立websocket连接.后台利用laravel的广播功能 如果第三方返回结果 那么将结果通知前端,前端根据结果跳转到不同页面
laravel
的广播系统和队列系统类似,需要两个进程协作,一个是 laravel
的 web
后台系统,另一个是 Socket.IO
服务器系统。具体的流程是页面加载时,网页 js
程序 Laravel Echo
与 Socket.IO
服务器建立连接, laravel
发起通过驱动发布广播,Socket.IO
服务器接受广播内容,对连接的客户端网页推送信息,以达到网页实时更新的目的。
npm install -g laravel-echo-server
在项目根目录 输入
laravel-echo-server init
根据提示一步一步操作
完了执行laravel-echo-server start 开始服务
将config/app.php 里面的App\Providers\BroadcastServiceProvider::class 前的注释放开
.env文件设置
npm install --save socket.io-client
npm install --save laravel-echo
import Echo from 'laravel-echo'
import io from 'socket.io-client'
订阅 user.{id} 这个私有的频道 并监听 H2pDepositCallbackEvent 这个事件 命名空间默认为(App\Events)
创建一个事件
php artisan make:event H2pDepositCallbackEvent
class H2pDepositCallbackEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public $user;
public function __construct(UserModel $user)
{
//
$this->user = $user;
//Log::info(json_encode($this->user->user_account));
}
/**该方法应该返回一个事件广播频道或频道数组。这些频道必须是 Channel、PrivateChannel 或 PresenceChannel 的实例,Channel 频道表示任意用户都可以订阅的公共频道,而 PrivateChannels 或 PresenceChannels 则代表需要进行频道授权的私有频道:
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
//创建一个私有频道
return new PrivateChannel('user.' . $this->user->user_account);
}
//这个方法是 要传递的数据
public function broadcastWith()
{
return ['depositeStatus' => 1];
}
}
然后,你只需要正常触发这个事件即可。一旦事件被触发,队列任务会自动通过指定广播驱动广播该事件(本文用redis作为队列驱动)
在入金控制器里 当收到了第三方返回的数据是 触发改事件 通过这个私有频道推送一个状态depositeStatus
$user = UserModel::where('user_account', intval($request->input('Customer')))->first();
broadcast(new \App\Events\H2pDepositCallbackEvent($user));
前端那边 就能接受到数据了
以为是私有频道 所以 laravel-echo 默认会向服务端 api /broadcasting/auth
发送一条 post 请求进行身份验证
BroadcastServiceProvider.php文件代码
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//Broadcast::routes();
// 将认证路由改为 /api/broadcasting/auth 从而避免 csrf 验证
// 添加中间件 auth:api (jwt 使用 refresh.token) 进行身份验证,避免访问 session ,并使 Auth::user() 生效。
Broadcast::routes(["prefix" => "api","middleware" => "refresh.token"]);
require base_path('routes/channels.php');
}
}
修改laravel-echo-server.json文件