【问题标题】:Socket.IO duplicated messageSocket.IO 重复消息
【发布时间】:2018-12-28 00:52:42
【问题描述】:

我正在尝试使用 Laravel、node js 服务器、socketio 和 redis 构建一个聊天应用程序。我有的是这样的:

客户端 JS:

var socket = io('http://localhost:3005');
 var room = '17';
  $("#send").click(function(){
    content = $("textarea").val();
    id =$("#id").val();
    $.ajax({
      url: "{{route('send.message')}}",
      method: "POST",
      data: {content, id, room},
      success: function(){
      }
    });
  });

  socket.on('cacad', function(message){
          console.log(message); //multiple copies here
      });

  socket.on('connect', function(){
    console.log("Connected!");
    socket.emit('room', room);
  });

Laravel 控制器:

public function sendMessage(Request $request){
 event(new EventName($request->all()));
  $message = new Message;
  $message->message = $request->content;
  $redis = LRedis::connection();
  $redis->publish('chat-channel', json_encode($request->all()));
  $message->save();
}

节点服务器:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var redis = require('ioredis');

var myMessage;
var redis_client = redis.createClient();

redis_client.subscribe('chat-channel');

io.on('connection', function(socket) {

    redis_client.on('message', function(channel, message) {
      var myData = JSON.parse(message);
        socket.broadcast.to('17').emit('cacad', 'u i u a a');
    });


    socket.on('room', function(room){
        socket.join(room);
    });

    socket.on('disconnect', function(){
      console.log("disconnected!");
    });
});


http.listen(3005, function() {
    console.log('Listening on Port 3005');
});

我正在尝试在 17 号房间广播消息 u i u a a。但是当我在控制台中收到它时,它会显示它的多个副本,2x-4x。在 Laravel 控制器中,我使用 redis 发布消息,并在节点服务器中订阅它。它已成功接收,但问题在于消息的多个副本(客户端)。

请问哪里错了?谢谢你:)

【问题讨论】:

  • 你为什么使用 PHP 和 NodeJS,执行 AJAX 请求来发送客户端的消息?作为聊天应用程序,以这种方式发送它效率不高。因为每个请求都包含 HEADERS,所以创建一个新请求,它是一个连接,然后关闭它。你已经有了插座。只需使用发射?参考socket.io/docs/client-api他们有一个很好的聊天例子..
  • 我执行 AJAX,因此数据保存在数据库中。在这种情况下,除了通过 AJAX 之外,你还会如何触摸 Laravel 的控制器?我期待您的回复。
  • 我不熟悉 Laravel,但正如我所见,你的 Laravel 和 NodeJS 都使用相同的 redis 对吗?为什么不简单地将您需要的内容保存在 nodejs 中?使用 Laravel 代码有不同的优势吗?
  • 我的主要应用程序是使用 Laravel。但回到我的问题,它并没有真正回答为什么我会收到重复的消息。有什么原因吗?

标签: node.js laravel redis socket.io


【解决方案1】:

我非常确信我找到了这个问题,尽管我不得不搜索一下那些简单的 API 用法,因为我最近没有使用该库。

查看docs 可以很清楚地解释您的问题。

你正在收听一个新的连接,

io.on('connection', function(socket) {

如果客户要求加入特定房间,您就加入他:

socket.on('room', function(room){
    socket.join(room);

到目前为止,它就像docs

io.on('connection', function(socket){
  socket.join('some room');
});

但是您的问题在于您的发射,在每个客户端连接上,您都会收听来自 redis 的消息。然后你将它广播到房间并发出连接的客户端。

您可以这样做:

io.on('connection', function(socket) {
    socket.on('room', function(room){
        socket.join(room);
    });

    socket.on('disconnect', function(){
      console.log("disconnected!");
    });
});

redis_client.on('message', function(channel, message) {
    var myData = JSON.parse(message);
      io.to('17').emit('cacad', 'u i u a a');
  });

【讨论】:

  • 那么它是否因为连接的客户端数量而显示重复的消息?我只连接了一个客户端。
  • 谢谢!它正在工作。我只是有点困惑同时使用 Redis 和 Socket IO。还是个初学者。
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 2023-01-05
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 2021-03-17
相关资源
最近更新 更多