首先我不得吐槽一下,网上写教程真是坑满满,全在教程里面爬坑!!!度娘更不靠谱?
教程基于5.8 顺便提醒一下低版本的问题
环境:
首先我们需要全局安装 laravel-echo-server ,终端输入下面的命令
npm install -g laravel-echo-server
安装完成后,打开你的 Laravel 应用,或新启一个测试项目
$ composer create-project --prefer-dist laravel/laravel echo-test
$ composer require predis/predis
$ laravel-echo-server init
执行这条命令后,会询问你一些关于 Socket 服务的配置信息,这段摘得……将就一下
// 是否在开发模式下运行此服务器(y/n) 输入y
? Do you want to run this server in development mode? (y/N)
// 设置服务器的端口 默认 6001 输入 6001就可以了 或者你想要的
? Which port would you like to serve from? (6001)
// 想用的数据库 选择 redis
? Which database would you like to use to store presence channel members? (Use arrow keys)
❯ redis
sqlite
// 这里输入 你的laravel 项目的访问域名
? Enter the host of your Laravel authentication server. (http://localhost)
// 选择 网络协议 http
? Will you be serving on http or https? (Use arrow keys)
❯ http
https
// 您想为HTTP API生成客户端ID/密钥吗 N
? Do you want to generate a client ID/Key for HTTP API? (y/N)
// 要设置对API的跨域访问吗?(y/n)N
Configuration file saved. Run laravel-echo-server start to run server.
{
"authHost": "http://laravel6:7888", // 自己的laravel服务端
"authEndpoint": "/broadcasting/auth", // 权限认证接口,如果是前后端分离地址是:/api/broadcasting/auth
"clients": [],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true, // 调试打印
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
"http": true,
"redis": true
},
"apiOriginAllow": {
"allowCors": false,
"allowOrigin": "",
"allowMethods": "",
"allowHeaders": ""
}
}
laravel-echo-server start 启动
laravel-echo-server stop 停止
四个全部打勾就代表启动OK了。但是应该有90%的会出现第四个报错!!!!也是很多教程没讲清楚的地方,
出现报错,先去启动你的redis 确认启动无误后开始配置 .env
BROADCAST_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
按照上面的进行配置,如果redis有其他设定自行修改,如果不是5.8,骚年你应该看不到QUEUE_CONNECTION,请修改QUEUE_DRIVER=redis
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
// 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), // 这个是前缀后面有解释
],
以上设置完毕 恭喜骚年第一个坑过去了!!!
npm install --save socket.io-client
npm install --save laravel-echo
import Echo from 'laravel-echo'
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
npm run dev
// 头部加入
// 引入app.js
// 监听并输出
php artisan make:event ExampleEvent
这时在 App/Events
目录下面会创建一个叫做 ExampleEvent.php
的事件类
事件类继承于 ShouldBroadcast
接口
class ExampleEvent implements ShouldBroadcast
找到 broadcastOn
函数,在对应的频道上进行广播
// user1就是频道
public function broadcastOn()
{
return new Channel('user1');
//return new PrivateChannel('channel-name');
}
// 处罚事件时返回的数据
public function broadcastWith()
{
return [
'data' => '老雷啊 坑满满'
];
}
现在添加一条路由用来测试,这里也可以通过控制器去发送,相关看事件文档
Route::get('user1', function(){
broadcast(new \App\Events\ExampleEvent);
});
现在启动监听事件列队
php artisan queue:listen --tries=1
现在我们可以开始测试,先打开首页,如果你定义了其他路由自行打开,我就默认的欢迎页面?!
如果看到下面页面 恭喜骚年你已经和服务器连接上了
服务端
现在我们打开事件路由广播一条消息,打开另一个页面访问 /user1,如果你设定了控制器访问对应的路由就是了,访问以后是空白不必紧张,我们先在终端看看队列,如果什么都没有输出,自行检查redis相关配置,以及查看redis库内是否有数据。正确会看到下面图,刷新一次页面会出现一条
然后我们可以看看第一个页面收到消息没!
如果正常就可以略过这一步了,基本都是5.8版本的问题,其他也没测试,我们先看看服务端显示什么
骚年有没有发现 Channel: laravel_database_user1,频道怎么变了!!!?,是的自动加了前缀!!!
找到config/database.php配置文件
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
// 删掉这一行或是注释掉
'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
],
然后我们再次重新启动服务和队列,刷新两个页面
就可以正常接收消息了
拓展点小知识!为什么会自动发送 2,3
0 open
在打开新传输时从服务器发送(重新检查)
1 close
请求关闭此传输,但不关闭连接本身。
2 ping
由客户端发送。服务器应该用包含相同数据的乓包应答
示例1.客户端发送:2probe 2.服务器发送:3probe
3 pong
由服务器发送以响应ping数据包。
4 message
实际消息,客户端和服务器应该使用数据调用它们的回调。
实施例1
服务器发送:4HelloWorld客户端接收并调用回调socket.on('message',function(data){console.log(data);});
实施例2
客户端发送:4HelloWorld服务器接收并调用回调socket.on('message',function(data){console.log(data);});
5 upgrade
在engine.io切换传输之前,它测试,如果服务器和客户端可以通过这个传输进行通信。如果此测试成功,客户端发送升级数据包,请求服务器刷新其在旧传输上的缓存并切换到新传输。
6 noop
noop数据包。主要用于在接收到传入WebSocket连接时强制轮询周期。