#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)» в этом условии событие будет запущено с отправителем, и отправитель будет проигнорирован с этим условием..