【问题标题】:Laravel event broadcasting with socketio and redis is not working in laravel 5.4?使用 socketio 和 redis 进行 Laravel 事件广播在 laravel 5.4 中不起作用?
【发布时间】:2018-03-09 18:38:09
【问题描述】:

我试图在用户登录网站时显示实时消息通知计数。为此,我使用了 socketio、redis 和 laravel 事件。但它不起作用。在 laravel 日志中,我收到一条消息。在此消息中,count 正在显示,但 socket 为空。我想我错过了什么。我的 gitbash 显示频道已订阅且用户已连接。

Gitbash

vagrant@homestead:~/Code/cabinapi$ node socket.js
    listening on *:3000
    Redis: message-channel subscribed
    a user connected

Laravel 日志

[2017-09-28 07:21:57] local.INFO: Broadcasting [App\Events\MessageEvent] on channels [message-channel] with payload:
{
    "count": 9,
    "socket": null
}

控制器

public function privateMessageAPICount($id)
{
        $count = PrivateMessage::where('receiver_id', new \MongoDB\BSON\ObjectID($id))
            ->where('read', 0)
            ->count();

        if ($count > 0){
            event(new MessageEvent($count));
        }
}

routes->web.php

Route::get('/message/count/{id}', 'Cabinowner\DashboardController@privateMessageAPICount');

.env

APP_URL=http://cabinapi.app
BROADCAST_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MessageEvent.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class MessageEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $count;
    public function __construct($count)
    {
        $this->count = $count;
    }

    public function broadcastOn()
    {
        return ['message-channel'];
    }
}

views->owner->layouts->app.blade.php

<body>
<span class="label label-success msgSpan"><span class="msgCountRemove">{!! $miscellaneous->privateMessageCount() !!}</span></span>

<script src="{{ asset('plugins/jQuery/jquery-2.2.3.min.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
    <script>
        var socket = io('{{ env("APP_URL") }}:3000');
        socket.on('message-channel:App\\Events\\MessageEvent', function(data){
            $('.msgCountRemove').remove();
            $('.msgSpan').append('<span class="msgCountRemove">'+data.count+'</span>');
        });
    </script>

</body>

config->app.php

'Redis' => Illuminate\Support\Facades\Redis::class,

socket.js

var app   = require('express')();
var http  = require('http').Server(app);
var io    = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('message-channel', function () {
    console.log('Redis: message-channel subscribed');
});
redis.on('message', function(channel, message) {
    console.log('Redis: Message on ' + channel + ' received!');
    console.log(message);
    message = JSON.parse(message);
    io.emit(channel + ':' + message.event, message.data);
});

io.on('connection', function(socket){
    console.log('a user connected');
    socket.on('disconnect', function(){
        console.log('user disconnected');
    });
});
http.listen(3000, function(){
    console.log('listening on *:3000');
});

【问题讨论】:

  • 你从哪里得到的日志?你能检查一下 config/broadcasting.php 吗?也许您将广播驱动程序设置为在那里登录,所以 .env 不起作用?
  • @HanlinWang,我从 storage->logs->laravel.log 获得的日志。不,我没有将广播设置为记录。 'default' =&gt; env('BROADCAST_DRIVER', 'null'),
  • 我在本地测试了您的代码,一切正常,是的,socket 为空,这是控制台的日志,带有您的 socket.js {"event":"App\\Events\\MessageEvent","data":{"count":1,"socket":null},"socket":null} ,所以您没有收到这样的日志,对吧?
  • @HanlinWang,我的问题是计数在我看来没有更新
  • 所以你可以在FE上接收事件,只是js代码没有更新你的html,对吧?

标签: php laravel laravel-5 laravel-5.4


【解决方案1】:

没有找到它在 laravel 5.4 中不起作用的确切原因。 但是我添加了一些更改。现在我得到实时消息通知计数。我在下面列出了我所做的更改。

我在redissocketio 的帮助下完成了实时通知计数

socket.js (Removed ioredis and included redis)

var redis = require('redis');
io.on('connection', function(socket){
    console.log('a user connected');

    var redisClient = redis.createClient();
    redisClient.subscribe('message');
    redisClient.on('message', function(channel, message){
       console.log('new message in queue', channel, message);
       socket.emit(channel, message);
    });

    socket.on('disconnect', function(){
        redisClient.quit();
        console.log('user disconnected');
    });
});

控制器

$redis = Redis::connection();
$redis->publish('message', $message);

views->owner->layouts->app.blade.php

<script>
        var socket = io('{{ env("APP_URL") }}:3000');
        socket.on('message-channel:App\\Events\\MessageEvent', function(data){
            $('.msgCountRemove').remove();
            $('.msgSpan').append('<span class="msgCountRemove">'+data+'</span>');
        });
    </script>

删除 MessageEvent.php

【讨论】:

  • 您没有使用事件广播,您只是将我面临相同问题的内容发布到 redis,并希望使用 even() 助手而不是 Redis::publish()
猜你喜欢
  • 1970-01-01
  • 2017-04-28
  • 2016-06-12
  • 2017-08-02
  • 2018-12-19
  • 2015-08-29
  • 2021-08-15
  • 2021-06-01
  • 1970-01-01
相关资源
最近更新 更多