如何在前端获取 socket.on 函数?事件被触发和处理。我正在使用 socket.io、NodeJS 服务器和 Redis.io

How to fetch socket.on function in frontend? The Event is triggered and processed. I'm using socket.io, NodeJS server, and Redis.io

*前端

正如您在代码中看到的那样。我正在尝试制作一个聊天应用程序。我发送的消息被触发,我的事件正在处理中。但问题是我无法从接收方接收消息。我是一名初级开发人员,通过 youtube 教程制作应用程序。谢谢...

<script>
     $(function (){
            let $chatInput = $(".chat-input");

            let $chatInputToolbar = $(".chat-input-toolbar");

            let $chatBody = $(".chat-body");

            let $messageWrapper = $("#messageWrapper");


            let user_id = "{{ auth()->user()->id }}";

            let ip_address = 'http://127.0.0.1';

            let socket_port = '8005';

            let socket = io(ip_address + ':' + socket_port);

            let friendId = "{{ $friendInfo->id }}";
            
            socket.on('connect', function() {
                
                socket.emit('user_connected', user_id);
            });

            socket.on('updateUserStatus', (data) => {
                let $userStatusIcon = $('.user-status-icon ');
                $userStatusIcon.removeClass('text-success');
                $userStatusIcon.attr('title', 'Away');
                

                $.each(data, function (key, val) {
                    if (val !== null && val !== 0) {
                       
                        let $userIcon = $(".user-icon-"+key);
                        $userIcon.addClass('text-success');
                        $userIcon.attr('title','Online');
                    }
                });

            });

            $chatInput.keypress(function (e) {
                let message = $(this).html();                       //text
                if (e.which === 13 && !e.shiftKey) {
                    $chatInput.html("");
                    sendMessage(message);
                    return false;

                }
            });

              function sendMessage(message) {
                let url = "{{ route('message.send-message') }}";
                let form = $(this);
                let formData = new FormData();
                let token = "{{ csrf_token() }}";

                formData.append('message', message);
                formData.append('_token', token);
                formData.append('receiver_id', friendId);

                appendMessageToSender(message);

                $.ajax({
                    url: url,
                    type: 'POST',
                    data: formData,
                        processData: false,
                        contentType: false,
                        dataType: 'JSON',
                    success: function (response) {
                        if (response.success) {
                            console.log(response.data);
                        }
                    }
                });


            }

              function appendMessageToSender(message) {
                let name = '{{ $myInfo->name }}';
                let image = '{!! makeImageFromName($myInfo->name) !!}';

                let userInfo = '<div class="col-md-12 user-info">\n' +

                                    '<div class="chat-image">\n' + image +
                                       
                                    '</div>\n' +

                                    '\n' +

                                    '<div class="chat-name font-weight-bold">\n' +

                                        name +

                                        '<span class="small time text-gray-500" 
                                        title="'+getCurrentDateTime()+'">\n' +

                                        getCurrentTime()+'</span>\n' +

                               
                                    '</div>\n' +

                                    '</div>\n';

                
                                    
                 let messageContent = '<div class="col-md-12 message-content">\n' +

                                            '<div class="message-text">\n' +
                                                message +
                                            '</div>\n' +

                                            '</div>';     
                                            
                                            

                let newMessage = '<div class="row message align-item-center mb-2">'
                +userInfo + messageContent +
                '</div>';

                $messageWrapper.append(newMessage);

            }

           

            function appendMessageToReceiver(message) {
            let name = '{{ $friendInfo->name }}';
            let image = '{!! makeImageFromName($friendInfo->name) !!}';
           
            let userInfo = '<div class="col-md-12 user-info">\n' +
                '<div class="chat-image">\n' + image +
                '</div>\n' +
                '\n' +
                '<div class="chat-name font-weight-bold">\n' +
                name +
                '<span class="small time text-gray-500" 
                title="'+dateFormat(message.created_at)+'">\n' +
                timeFormat(message.created_at)+'</span>\n' +
                '</div>\n' +
                '</div>\n';
            let messageContent = '<div class="col-md-12 message-content">\n' +
                '<div class="message-text">\n' + message.content +
                '</div>\n' +
                '</div>';
            let newMessage = '<div class="row message align-items-center mb-2">'
                +userInfo + messageContent +
                '</div>';
                $messageWrapper.append(newMessage);
           
            
            }



            {
                
                appendMessageToReceiver(message);
                
                
            });

我想我在 socket.on 函数中遗漏了一些东西: socket.on("私有频道:App\Events\PrivateMessageEvent", 函数(消息)

            socket.on("private-channel:App\Events\PrivateMessageEvent", function (message)
            {
                
                appendMessageToReceiver(message);
                
                
            });


        });

后端服务器

var app = require('express')();


var http = require('http').Server(app);

var io = require('socket.io')(http, {
    cors: {
        origin: "*",
        
      }
});

var Redis = require('ioredis');
var redis = new Redis();

var users = [];

http.listen(8005, function() {
    console.log('Listening to port 8005');

});

redis.subscribe('private-channel', function() {
    console.log('subscribed to private channel');
});

redis.on('message', function(channel, message) {
    message = JSON.parse(message);
    console.log(message);
    if (channel == 'private-channel') {
        let data = message.data.data;
        let receiver_id = data.receiver_id;
        let event = message.event;

        io.to('${users[receiver_id]}').emit(channel + ':' + event, data);

    }
    
});

io.on('connection', function (socket) {
    socket.on("user_connected", function (user_id) {
            users[user_id] = socket.id;
            io.emit('updateUserStatus', users);
            console.log("user connected "+ user_id);
    });

    socket.on('disconnect', function() {
        var i = users.indexOf(socket.id);
        users.splice(i, 1, 0);
        io.emit('updateUserStatus', users);
        console.log('users');
    });

});

PrivateMessageEvent

namespace App\Events;

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

class PrivateMessageEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    Public $data;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('private-channel');

    }

.env

这是我的 .env 文件。

APP_NAME=chat_application
APP_ENV=local
//App_key
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=chat_application
DB_USERNAME=root
DB_PASSWORD=


BROADCAST_DRIVER=redis
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}

我注意到在您的服务器端代码中发出的事件中存在一个问题,这是发出套接字事件的代码

io.to('${users[receiver_id]}').emit(channel + ':' + event, data);

所以,您尝试使用字符串插值和上述语法是不正确的。基本上,这只是一个字符串 '${users[receiver_id]}'。这需要更改为`${users[receiver_id]}`,下面是更新后的代码

io.to(`${users[receiver_id]}`).emit(channel + ':' + event, data);

因此,在使用字符串插值时,您需要使用反引号而不是单引号。 另一点是确保 io.to('${users[receiver_id]}').emit(channel + ':' + event, data); 中的 channel + ':' + event 与客户端代码中的客户端事件相同 - "private-channel:App\Events\PrivateMessageEvent",

socket.on("private-channel:App\Events\PrivateMessageEvent", function (message) {                
  appendMessageToReceiver(message);
});