如何在前端获取 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);
});
*前端
正如您在代码中看到的那样。我正在尝试制作一个聊天应用程序。我发送的消息被触发,我的事件正在处理中。但问题是我无法从接收方接收消息。我是一名初级开发人员,通过 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);
});