我在Laravel 5.4中使用socket.io在客户端创建聊天应用程序,同时向目标用户发送APNS通知。
当用户向目标用户发送消息时,消息发送多次意味着这取决于与节点socket.io服务器连接的连接数量,我认为它的意思是我的频道('messages')循环该消息连接数量的客户端,因此它在接收方显示不止一次。 在这里我的发送方(Laravel):
$redis = LRedis::connection();
$data = [
'message' => $msg,
'user' => $auth,
'music'=>$music,
'target_user'=>$target_user
];
$redis->publish('message', json_encode($data));
在socket.js:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
var apn = require('apn');
var request = require('request');
var auth_user_id = null;
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "database"
});
con.connect(function(err) {
if (err) throw err;
console.log("Database Connected!");
});
var options = {
token: {
key: "app-keys/APNsAuthKey_U3QV9H86BR.p8",
keyId: "keyId",
teamId: "teamid",
cert: "app-keys/musicChatAppDevelopment.pem",
},
development: true,
production: false,
};
var apnProvider = new apn.Provider(options);
server.listen(8890);
io.on('connection', (socket) => {
var auth_user_id = socket.handshake.query.auth_user_id;
console.log("client connected");
console.log("Client Socket id--"+socket.id+"-----User Id----"+auth_user_id);
var redisClient = redis.createClient();
redisClient.subscribe('message');
if(auth_user_id>0) {
var sql = "UPDATE users SET socket_id ='"+socket.id+"' WHERE id ="+auth_user_id;
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result.affectedRows + " record(s) updated");
});
}
redisClient.on('message', (channel, data) => {
console.log(channel);
let data_= JSON.parse(data);
let message_ = data_.message;
let deviceToken = data_.target_user['ios_token'];
if(data_.user['id']!=data_.target_user['id']) {
console.log(data_.target_user['ios_token']);
var note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 0;
note.sound = "ping.aiff";
note.alert = {
"title" : data_.user['first_name'],
"body" : message_,
};
note.payload = { "aps" : {
"alert" : {
"title" : data_.user['first_name'],
"body" : message_
}
}
}
note.topic = "com.charpixel.hellodemo";
console.log(note);
let socketId = data_.target_user['socket_id'];
apnProvider.send(note, deviceToken).then( (result) => {
console.log(JSON.stringify(result));
});
console.log("Target User Socket id "+data_.target_user['socket_id']);
socket.broadcast(data_.target_user['socket_id']).emit(channel, data);
io.to(socketId).emit(channel,data);
}
});
socket.on('disconnect', () => {
redisClient.quit();
});
});
在index.blade.php:
var ip = '<?php echo config('app.current_ip'); ?>:8890?auth_user_id='+JSON.parse(user_id)['id'];
console.log("Curent_URL"+ip);
var socket = io.connect(ip);
socket.on('message', function (data) {
});
还在我的IOS应用程序上多次获取apns通知。
答案 0 :(得分:3)
对于1-1聊天,您应该为每个聊天创建单独的频道。您的代码会在频道&#39;消息&#39;上发送消息。这是每个客户订阅的。所以这里有很多问题。例如,如果您有3个客户端:
redisClient.on('message')
。 解决方案是您应该为每个聊天创建一个唯一的频道。请参阅this stackoverflow答案作为示例。它不使用redis,但你可以改变它以使用reddis。