I am creating a chat application in Laravel 5.4 using socket.io on the client side, also sending an APNS notification to the target user.
By doing this, when the user sends a message to the target user that sending the message more than once means that it depends on the number of connections connected to the node socket.io server, which I think means that my channel ("messages") is a message for the connected number of clients, so that it shows more than once on the receiver side. Here is my sender side (Laravel):
$redis = LRedis::connection();
$data = [
'message' => $msg,
'user' => $auth,
'music'=>$music,
'target_user'=>$target_user
];
$redis->publish('message', json_encode($data));
In 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;
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();
});
});
In 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) {
});
Also receiving apns notifications several times in my iOS app.