windows下使用laravel5.1+redis+socket.io实现事件广播

因为要重构一个studio的招新系统,碰到的问题就是面试官点击下一个面试者之后,需要把消息传达给等候室,本来考虑到直接搭个多人聊天就完事了,通知的消息由面试官自己发送到前台,但是看到之前师兄写的代码,用到了laravel的事件,就想着为何不直接广播一条通知消息给前台呢?效率肯定比面试官手动发送要快,而且发送的数据是直接从数据库拿到的,不易出错。 

于是就查阅了一下laravel的官方文档跟网上的一些资料,搞一下事件广播。

PS:因为我用的是laravel5.1的版本开发的,看了下相关资料,laravel5.5之后很多地方都进行了改动,广播事件这一部分有了较大的改动,具体可以去看一下laravel5.5的官方文档。

注意:因为我这个是在本地搞的事件广播,本地开发环境为windows

进入正题:

准备工作:

  • laravel5.1

  • redis

  • node.js

    • socket.io , ioredis


laravel默认驱动为pusher,因为用到的是redis作为广播驱动,所以要把项目里面的广播驱动改为redis。

将laravel项目中的config/broadcasting.php文件下的

'default' => env('BROADCAST_DRIVER', 'pusher')

改为 

'default' => env('BROADCAST_DRIVER', 'redis')

配置好laravel的database配置文件

位置:项目根目录中的config/database.php

'redis' => [

    'cluster' => false,

    'default' => [
        'host'     => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port'     => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

]

进行相关的配置,端口,主机,密码这些。


laravel的配置部分搞好之后,就定义一个被广播的事件

在目录app/Providers中一个事件服务提供者的文件,叫EventServiceProvider,在这个文件里面进行事件跟监听器的注册。

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\SomeEvent' => [
            'App\Listeners\EventListener',
        ],
    ];

    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        //
    }
}

 laravel项目默认帮我们注册了一对事件跟事件监听器,所以只需要运行php artisan 的命令便可以为我们创建时间与监听器,如果想要自己重新注册事件的话,就在listen的数组里面重新注册一对事件与监听器

在项目根目录下,命令行运行:

php artisan event:generate

 执行命令后,laravel会按照你所注册的时间与监听器来创建一对事件与监听器,事实上在这个监听器的作用并没有发挥到。创建好事件后,事件要实现一个shouldBroadCast接口,这样才能实现广播

class BroadCastMsgEvent extends Event implements ShouldBroadcast

laravel中事件类的public属性的内容都会被序列化广播 

class someEvent extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $user_id;//public属性会被序列化广播
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($uid)
    {
        $this->user_id = $uid;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    //广播的频道
    public function broadcastOn()
    {
        return ['test-channel'];
    }
    //定义广播内容的格式
    public function broadcastWith()
    {
        return ['user_id'=>$this->user_id];
    }
}

附上参考链接,链接为laravel5.1的官方文档,里面会有更详细的介绍:事件广播

redis:

 redis在网上很有很多的教程,这里就不写了,略过一下


node:

这些工作做完之后,轮到下一步了,下载socket.io,ioredis

下载socket.io 跟 ioredis的前提是要下载node.js

node的下载安装就省略了,很多文章都有教你怎么安装

安装之后,配一下环境变量,配为全局

cmd进入命令行,随意在哪个位置(前提是配好全局环境变量),输入:

node  -v

然后看到版本就代表你安装好了

安装好node之后,接下来就是通过node来下socket.io 跟 ioredis

进入到你的项目根目录,在根目录下使用命令行,输入

npm init -f

 这个命令是初始化项目,-f是强制,不加f的话会要求你填入一些信息,比如名字,版本,仓库等等,会自动生成一个叫 packget.json的文件

初始化项目之后,安装socket.io, ioredis

npm install ioredis socket.io  --save

 安装完成后,项目的根目录会多一个叫 node_modules  文件夹,里面包含了 ioredissocket.io 等文件夹

配置socket服务文件

创建一个index.js文件,内容为

var app = require('http').createServer(handler);
var io = require('socket.io')(app);
var Redis = require('ioredis');
var redis = new Redis();/*这里的Redis的端口跟域名可以自己配置,默认端口是6379,域名是本地localhost*/

/*监听的端口为3000*/
app.listen(3000, function() {
    console.log('Server is running! Listening on Port 3000');
});
function handler(req, res) {
    res.writeHead(200);
    res.end('');
}
io.on('connection', function(socket) {
    //
});
redis.psubscribe('*', function(err, count) {
    //
});
redis.on('pmessage', function(subscribed, channel, message) {
    message = JSON.parse(message);
    io.emit(channel + ':' + message.event, message.data);
});

这个服务端文件名字可以自己取,可以直接卸载根目录下,也可以创建个文件单独存起来

接下来是服务端的配置

我是在laravel项目中的public写的测试样例

客户端代码如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>广播测试</title>
    <script src="js/socket.io-client/dist/socket.io.js"></script>
    <script>
        var socket = io('http://localhost:3000');
        socket.on('connection', function (data) {
            console.log(data);
        });
        socket.on('test-channel:App\\Events\\someEvent', function(message){
            console.log(message);
        });
//        console.log(socket);
    </script>
</head>
<body>
    客户端测试
</body>
</html>

注意的是:

<script src="js/socket.io-client/dist/socket.io.js"></script>

 这里的文件是我把 node_modules/socket.io-client 这个文件夹复制了一份到public下的js文件夹中,核心文件是socket.io.js

这里我参考了很多文章,可能有的 node_modules的结构不一样,所以引进的路径也不一样,正如上面所说,核心文件就是socket.io.js,找到这个文件所在的文件夹,赋值一份过去,然后客户端引一下就可以

可以看到这一段代码:

socket.on('test-channel:App\\Events\\someEvent', function(message){
    console.log(message);
});

这里面的 test-channel 就是事件类中 broadcastOn的订阅频道, App\\Events\\someEvent 就是事件在你项目中的路径,具体路径要看个人的项目目录分布,这里只是参考

最后:

自己在项目的route文件中定义一个触发事件的路由:

Route::get('BroadcastTest',function(){
    event(new \App\Events\someEvent(666));
    return "广播测试";
});

 cmd 运行redis:

redis-server.exe

重新开一个cmd,运行服务文件:

node index.js 

 最后,打开浏览器,访问触发时间的路由,再打开客户端的页面,并打开控制台,就会看到广播的内容了

效果如下:

laravel+redis+socket.io实现事件的广播主要参考了这篇文章:链接

有不对的地方大佬们可以斧正。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值