laravel广播
大约 3 分钟
后端
安装依赖
创建一个路由触发事件
Route::post("seed",[\App\Http\Controllers\Api\Openai\Index::class,"seed"]);
public function seed()
{
$message = (string)\request("message");
AssertUtils::isEmpty($message,"请输入内容");
$data =ChatMessage::create([
"uid" => \request()->user()->id,
"content" => $message,
"type" => 1
]);
// 触发事件
event(new OpenaiMessage($data));
return $this->success("success",$data);
}
公共消息-channel
php artisan make:event ChatMessage
app/Events/ChatMessage.php
私有消息-
php artisan make:event FriendEvent
频道消息-
php artisan make:event GroupEvent
频道授权方式
1、session 方式授权 (默认方式)
这种方式需要在网页端登录后的用户监听私有频道的时候,私有私有频道才能进行认证。
2、sanctum 方式授权
此方式使用了jwt的方式进行的认证,当我们使用次方式进行认证的时候,我们判断用户是否登录,需要用户在header头中写道token,在路由中设置 auth:sanctum
的中间件,从而获取到用户的的登录于是,在laravel的中我们也需要使用这个方式的认证,找到:app/Providers/BroadcastServiceProvider.php
文件,设置认证方式
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes([
"middleware" => ["auth:sanctum"]
]);
require base_path('routes/channels.php');
}
}
授权
// $user: 当登录的用户信息,$id:路由传递的参数
Broadcast::channel('user.{uid}', function ($user, $uid) {
return true; // 我们可以在这里做一些判断,最后返回是 true|false 就可以
});
前端
安装依赖
本地开启 laravel-echo
安装依赖
npm i -g laravel-echo-server
配置连接:resources/js/bootstrap.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001', //本地使用这个方式
// host: 'http://home.com:6001', // laravel-echo 是一个独立运行的使用这个方式
//可选
auth: {
headers: {
Authorization: "Bearer " + LocalStorage.get(EnumData.tokenLabel) // 登录后获得的token值,主要看怎么进行权限认证的
}
}
});
在入口html中添加
<meta name="csrf-token" content="{{ csrf_token() }}">
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
// 也可以下载之后直接引入
<script src="//home.com:6001/socket.io/socket.io.js"></script>
<script src="/js/socket.io.js"></script>
示例
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ env("APP_NAME") }}</title>
<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
@vite(["resources/css/app.css",'resources/js/app.js'])
</head>
<body class="antialiased">
<div id="app">
<router-view />
</div>
</body>
</html>
docker开启laravel-echo
创建一个 docker-compose.yml
文件
version: "3.5"
services:
echo:
image: oanhnn/laravel-echo-server
restart: always
ports:
- 6001:6001
volumes:
- ./data:/app
environment:
- LARAVEL_ECHO_SERVER_GENERATE_CONFIG=true
network_mode: host
运行:
docker-compose up -d
运行后会在当前目录的data下生成一个配置文件,如果启动失败,可以查看redis的配置是否正确。
{
"apiOriginAllow": {},
"authEndpoint": "/broadcasting/auth", // 注意这里的授权路劲
"authHost": "http://localhost:6002", // 注意这里的授权地址
"clients": [],
"database": "redis",
"databaseConfig": {
"redis": {
"host": "127.0.0.1", // 主机的ip地址:192.168.1.2
"port": "6379",
"password" : "redis666",
"keyPrefix": "",
"options": {
"db": "0"
}
},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
},
"publishPresence": true
},
"devMode": true,
"host": null,
"port": 6001,
"protocol": "http",
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"socketio": {},
"subscribers": {"http": true, "redis": true}
}
授权地址说明:
如果是将程序,redis,laravel-echo-server 分开部署的话,直接填写对应的域名即可。
如果是单服务器部署,以宝塔为例,如果我们绑定 :chat.cc
这样一个域名,我们在添加一个绑定,这个主要是端口的绑定这个服务,本地项目可以通过不同的端口访问不同的服务。