Сокет.io и Redis транслируют всем клиентам, кроме отправителя

#node.js #laravel #redis #socket.io #broadcast

#node.js #laravel #redis #socket.io #трансляция

Вопрос:

Я использую Laravel в фоновом режиме для создания приложения для чата. но когда я использую redis , я не могу использовать broadcast.send функцию. Теперь как отправить сообщение всем клиентам, кроме отправителя? В этом коде ошибка:

io.broadcast.send(канал ‘:’ сообщение.событие, сообщение.данные);

Это весь мой серверный код:

 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('chat');

redis.on('message', function(channel, message) {
    console.log('Message Recieved: '   message);
    message = JSON.parse(message);

    // send all client except sender
    io.broadcast.send(channel   ':'   message.event, message.data); 

});


io.sockets.on('connection', function(socket) {      
    console.log('User Connect with ID: '   socket.id);         
});

// run server
http.listen(3001, function(){
    console.log('Listening on Port 3001');
});
 

и клиентский код:

 var socketClient = io(':3001');
socketClient.on("chat:App\Events\ChatEvent", function(message){
        // increase the power everytime we load test route
        console.log(message);       
    });
 

ChatEvent.php

 <?php

namespace AppEvents;

use AppEventsEvent;
use IlluminateQueueSerializesModels;
use IlluminateContractsBroadcastingShouldBroadcast;

class ChatEvent extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $message;

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


    public function broadcastOn()
    {
        return ['chat'];
    }
}
 

Ответ №1:

Вы могли бы расширить функцию emit() дополнительным аргументом, скажем, send_to_self=True , который вместе с broadcast=True или значением room будет настраивать, должен ли быть включен текущий клиент или нет. По умолчанию все останется прежним, но если для параметра send_to_self установлено значение False, то цикл, который выполняет итерацию по всем клиентам для уведомления, пропустит текущее соединение. Чтобы определить, какой из них является текущим, вы можете использовать request.namespace , который является объектом пространства имен для активного клиента.

Итак, ваш код

 io.emit(channel   ':'   message.event, message.data,send_to_self=false);
 

Ответ №2:

для этого вы можете использовать вспомогательную трансляцию, а затем использовать метод toOthers() ;
более подробная информация приведена в документах https://laravel.com/docs/5.8/broadcasting#only-to-others

Ответ №3:

Попробуйте использовать подстановочный знак

 class messageEvent extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $userid;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($user)
    {

        if($user==Auth::guard('admin')->user()->id){
                  return false;
         }
        $this->userid = $user;


    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {   
        return ['ChatEvent-'.$this->userid];
    }
}
 

В Js внесите изменения

     var socketClient = io(':3001');
    socketClient.on("chat:App\Events\ChatEvent-<?php echo Auth::guard('admin')->user()->id; ?>", function(message){

            console.log(message);       
        });
 

Комментарии:

1. Спасибо @ronak, но я думаю, вы не понимаете моих средств. Я хочу транслировать сообщение всем клиентам, кроме отправителя с сокетом. конфигурация сервера ввода-вывода.

2. @Ehsan «if($user == Auth::guard(‘admin’)-> user()-> id)» в этом условии событие будет запущено с отправителем, и отправитель будет проигнорирован с этим условием..