leemason / polycast
Laravel Websocket 广播补丁,使用 Ajax 和 MySQL。
Requires
- illuminate/database: 5.1.*|5.2.*
- illuminate/support: 5.1.*|5.2.*
Requires (Dev)
- phpunit/phpunit: ~4.0
This package is not auto-updated.
Last update: 2024-09-14 15:46:52 UTC
README
Laravel Websocket 广播补丁,使用 Ajax 和 MySQL。Laravel 5.1 或更高版本
安装
使用 composer 安装此包
composer require leemason/polycast
更新 composer 后,将 ServiceProvider 添加到 config/app.php 中的 providers 数组
Laravel 5.1
LeeMason\Polycast\PolycastServiceProvider::class,
在你的 config/broadcasting.php 中广播连接数组中添加以下内容
'polycast' => [ 'driver' => 'polycast', 'delete_old' => 2, //this deletes old events after 2 minutes, this can be changed to leave them in the db longer if required. ]
使用发布命令将包资源复制到您的 public 文件夹
php artisan vendor:publish --tag=public --force
迁移包的数据库迁移(创建 polycast_events 表)
php artisan migrate --path=vendor/leemason/polycast/migrations
用法
要可选地将 Polycast 设置为默认广播事件驱动程序,请将 polycast
设置为 config/broadcasting.php 中的默认值或 .env 文件中的 BROADCAST_DRIVER=polycast
。
一旦安装,您可以创建与现在完全相同的广播事件(使用 ShouldBroadcast 特性),但您可以通过浏览器来消费这些事件,而无需安装/购买 nodejs/redis 或外部库。
此包的目标不是与 PRedis/SocketIO/Pusher 等库或解决方案竞争。但它确实为无法安装 nodejs 并运行 websocket 服务器,或 Pusher 等服务成本不可行的场景提供了可行的解决方案。
该包利用纯 JavaScript 超时和 Ajax 请求来“模拟”实时体验。它通过将广播事件保存在数据库中,通过 setTimeout JavaScript Ajax 请求,轮询包的接收器 URL,并通过 JavaScript 回调分发有效载荷来实现这一点。
为了增强实时事件模拟,每个找到的事件都会从请求的时间开始解析,以及事件被触发的时间。然后使用秒数差异来延迟特定事件的回调触发。
这样做是为了防止在 Ajax 请求完成后将每个事件回调都直接输出到 dom,而是按顺序触发,就像它正在实时加载一样。
对于用户来说,与 websocket 的唯一真正区别是他们可能要落后几秒钟(取决于提供的轮询选项,“默认 5 秒”)。
我尽量使 JavaScript API 与当前的 socket 解决方案相似,以降低学习曲线。
以下是一个示例
<script src="<?php echo url('vendor/polycast/polycast.min.js');?>"></script> <script> (function() { //create the connection var poly = new Polycast('http://localhost/polycast', { token: '<?php echo csrf_token();?>' }); //register callbacks for connection events poly.on('connect', function(obj){ console.log('connect event fired!'); console.log(obj); }); poly.on('disconnect', function(obj){ console.log('disconnect event fired!'); console.log(obj); }); //subscribe to channel(s) var channel1 = poly.subscribe('channel1'); var channel2 = poly.subscribe('channel2'); //fire when event on channel 1 is received channel1.on('Event1WasFired', function(data){ console.log(data); }); //fire when event on channel 2 is received, optionally accessing the event object channel2.on('Event2WasFired', function(data, event){ /* event.id = mysql id event.channels = array of channels event.event = event name event.payload = object containing event data (same as the first data argument) event.created_at = timestamp from mysql event.requested_at = when the ajax request was performed event.delay = the delay in seconds from when the request was made and when the event happened (used internally to delay callbacks) */ var body = document.getElementById('body'); body.innerHTML = body.innerHTML + JSON.stringify(data); }); //at any point you can disconnect poly.disconnect(); //and when you disconnect, you can again at any point reconnect poly.reconnect(); }()); </script>
分析示例,您可以看到我们包含了库
<script src="<?php echo url('vendor/polycast/polycast.min.js');?>"></script>
在自执行函数中创建 Polycast 对象(这可以通过几种方式完成,并且有几个选项)
<script> (function() { //default options defaults = { url: null, token: null, polling: 5 //this is how often in seconds the ajax request is made, make sure its less than the (delete_old * 60) connection config value or events may get deleted before consumed. }; //create the connection var poly = new Polycast('http://localhost/polycast', { token: '<?php echo csrf_token();?>' }); //or like this var poly = new Polycast({ url: 'http://localhost/polycast', token: '<?php echo csrf_token();?>' }); //or like this (but this way we arent using csrf, and i can't see a good reason not to) var poly = new Polycast('http://localhost/polycast'); .... }()); </script>
我们在连接事件上注册任何回调
//register callbacks for connection events poly.on('connect', function(obj){ console.log('connect event fired!'); console.log(obj); }); poly.on('disconnect', function(obj){ console.log('disconnect event fired!'); console.log(obj); });
我们通过订阅频道创建频道对象
//subscribe to channel(s) var channel1 = poly.subscribe('channel1'); var channel2 = poly.subscribe('channel2');
并在那些频道上注册特定事件的回调
//fire when event on channel 1 is received channel1.on('Event1WasFired', function(data){ console.log(data);//data is a json decoded object of the events properties });
如果发生错误或需要断开连接,您可以在任何时候这样做
//at any point you can disconnect poly.disconnect(); //and when you disconnect, you can again at any point reconnect poly.reconnect();
就是这样!(目前就是这样)
Bower 使用
polycast 包在 Bower 上使用名称 leemason-polycast
注册,可以通过运行以下命令安装
bower install leemason-polycast
然后可以从 bower_components/leemason-polycast/dist/js/polycast(.min).js
路径访问包脚本。
NPM 使用
polycast 包在 npm 上使用名称 leemason-polycast
注册,可以通过运行以下命令安装
npm install leemason-polycast
然后可以从 node_modules/leemason-polycast/dist/js/polycast(.min).js
路径访问包脚本。
Webpack 使用
polycast 包脚本文件是使用 gulp/webpack 生成的,这在使用脚本加载器开发 JavaScript 时提供了优势。
用法如下
var Polycast = require('leemason-polycast');//this is npm usage, if using bower you will need to provide the full path var poly = new Polycast({...});
该包处于早期开发阶段(但很稳定),因此请期待不久将推出新的方法和功能。
常见问题解答
这个功能需要jQuery吗?
不需要,这里全部使用纯JavaScript,包括AJAX请求。
如果在请求过程中出现问题,我的JavaScript会陷入循环吗?
不会,下一个setTimeout调用将在上一个调用完成后才会发生。
它是如何确定哪些事件发送给谁的?
这是通过通道和事件名称实现的,但包也会监控时间。当JavaScript服务创建连接时,服务器会发送它的当前时间。这个时间被存储在JavaScript对象中,并在后续请求中发送/更新,创建一个“事件名称?在通道?自?类型”的数据库查询。
注意
这是我第一个重量级的JavaScript包,这很好,因为它给了我更多的学习语言的机会。话虽如此,如果您有任何改进意见,请告诉我或者发送pull request。
未来
- 为通道添加授权选项
- 在这里添加一些用于移除通道/事件订阅的帮助程序
- 添加通配符事件名称监听
- 添加在不提供通道的情况下订阅事件的能力