I'm having trouble with my chat app, I need to be able to send a private message to a specific user, I was able to select that specific user but for some reason couldn't figure out how to send the private message.
Below you will find the code for my server, please help:
var express = require('express');
var app = express();
var PORT = process.env.PORT || 8000;
var http = require('http').Server(app); // this is a node server that uses express as the boiler plate
var io = require('socket.io')(http); // socket! pass our server as a parameter to it
// use express static to expose a folder
app.use(express.static(__dirname + '/public'));
var users = [],
connections = [];
var onlineClients = {};
// Register events on socket connection
io.on('connection', function(socket){
connections.push(socket);
// console.log("connected socket", connections);
socket.on("disconnect", function() {
users.splice(users.indexOf(socket.username), 1);
updateUsernames();
connections.splice(connections.indexOf(socket), 1);
console.log("disconnected socket", connections.length)
});
socket.on("send message", function(data) {
// console.log(data);
io.emit("new message", {msg: data, user: socket.username});
});
socket.on("notify user", function(data) {
io.emit("notify user", {user: socket.username})
});
socket.on("new user", function(data) {
socket.username = data;
users.push(socket.username);
updateUsernames();
});
function updateUsernames() {
io.emit("get users", users);
};
socket.on("private", function(data, recipientName) {
var recipient = connections.filter(function (recipient) {
return recipient.username === recipientName;
})[0];
console.log(recipient.id);
console.log(data);
io.sockets.socket(recipient.id).emit("received private msg", data);
});
// socket.on("create room", function(room) {
// socket.join(room);
// io.sockets.in(room).emit('event', "hey wusup am in this room");
// console.log(socket);
// })
});
http.listen(PORT, function(){
console.log('Server started on port ' + PORT);
});
First add user in chat room so that will easy to find a user in your private chat room
Your client side code for join private room
<input type="text" class="form-control" id="user_email" placeholder="user_email" />
<button text="join room" class="btn btn-primary btn-block" onclick="a();"> Join Room</button>
your javascript code in client side
function a(){
io.emit('privatechatroom', {email:document.getElementById('user_email').value});
}
your server side code to add user in your room
socket.on('privatechatroom',function(data){
socket.join(data.email);
io.emit('res',{mes:"you are added"})
});
now u can send private message to that person that is recently addedd to this room
client side
function b() {
io.emit('sendmail', { email: document.getElementById('sender_mail').value, message: document.getElementById('message').value });
$('#message').val('');
}
/*serverside code*/
socket.on('sendmail', function (data) {
io.sockets.in(data.email).emit('new_msg', { msg: data.message });
console.log(data.email);
});
Here is the clear solution of mine for your question...
Send a message to Particular client(Private chat)
I hope it will work for you sue..
Related
Okay as I said i the title when I go to my home page the socket connection works perfectly but when I use a route it doesnt work at all here is my index.js
io.of('/admin').on('connection', function(socket) {
console.log('made socket connection', socket.id);
console.log(socket.request.user);
socket.on('chat', async function(data) {
console.log(data);
client.guilds.channels.get('474951005788962846').send(data);
io.sockets.emit('chat', data);
});
});
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
console.log(socket.request.user);
socket.on('chat', async function(data) {
console.log(data);
client.guilds.channels.get('474951005788962846').send(data);
io.sockets.emit('chat', data);
});
});
and on my /admin page here is my script that it is the same but the connection isnt as I added the /admin
<script>
var socket = io.connect('https://domain/admin');
// Query DOM
var serverID = document.getElementById('add_server_id');
var serverRoles = document.getElementById('add_role_ids');
var btnServer = document.getElementById('add_server_save');
//var output = document.getElementById('output');
// Emit events
btnServer.addEventListener('click', function(){
socket.emit('chat', {
serverid: serverID.value,
serverroles: serverRoles.value
});
});
//Listen for events
socket.on('chat', function(data) {
console.log(data);
//output.innerHTML += '<p><strong>' + data.game + '</strong></p>';
});
</script>
if someone can tell me why is it not connecting I would really appreciate it
var socket = io.connect('https://domain/admin');
to
var socket = io.connect('/admin');
The namespace is an implementation detail of the Socket.IO protocol,
and is not related to the actual URL of the underlying transport,
which defaults to /socket.io/….
I have a simple chatroom application using a node express server.
This uses a redis database connection to store the nicknames of the joined clients.
I need to clear the redis SET of nicknames named members when the server is closed/disconnected.
This can be done as following:
redisClient.del("members", function(err, reply){
console.log("members set delete :" + reply);
});
But where should I put this code? How to handle the final event from the server when disconnection, from the server side?
Server code - chatroom.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var redis = require('redis');
var redisClient = redis.createClient();
io.on('connection', function(client){
console.log("client connected...");
});
io.on('connection', function(client){
client.on('join', function(name){
client.nickname = name;
//adding names
client.broadcast.emit("add member", name);
redisClient.smembers('members', function(err, names) {
names.forEach(function(name){
client.emit('add member', name);
});
});
client.emit('add member', client.nickname)
redisClient.sadd("members", name);
});
// remove clients on disconnect
client.on('disconnect', function(name){
client.broadcast.emit("remove member", client.nickname);
redisClient.srem("members", client.nickname);
});
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/views/index.html');
});
server.listen(8080);
Client code - views/index.html
<html>
<head>
<title>Socket.io Client</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<h2>Chat box</h2><br>
<h4 id="status"></h4><br>
<div>
<h3>Active members</h3>
<ul id="members"></ul>
</div>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('connect', function(data){
nickname = prompt("What is your nickname?");
$('#status').html('Connected to Chat Room as \''+nickname+'\'.');
socket.emit('join', nickname);
});
socket.on('add member', function(name) {
var member = $('<li>'+name+'</li>').data('name', name);
$('#members').append(member);
});
socket.on('remove member', function(name) {
$('#members li').filter(function() { return $.text([this]) === name; }).remove();
});
socket.on('disconnect', function(data){
$('#status').html('Chatroom Server Down!');
});
</script>
</body>
</html>
How to clear the redis database set when nodejs server disconnect?
you can use error or end events on redisclient, check the Redis Package Documentation
redisClient.on("error", function (err) {
console.log("Error " + err)
// delete here
});
However, since your connection is closed, it is more healthy to delete on first connection to redis each time. do it on reconnection state too.
When a socket.io connection dies, an event named disconnect is fired. Register your reset logic to that callback.
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
redisClient.del("members", function(err, reply){
console.log("members set delete :" + reply);
});
});
});
Credits : How can i handle Close event in Socket.io?
I am relatively new to node.js and socket.io. While building a sample chat room application I am encountering a case where when I refresh the browser n times, and then send a message, the message gets broadcasted n-times to all the clients. How do I make it not broadcast multiple times and just once? Here goes the server side and client side code.
qaserver.js
var express = require('express')
, app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server, { log : false });
server.listen(4040);
var redis = require('redis');
var r43 = redis.createClient('6379', '127.0.0.1');
r43.select("43");
// Set the view directory to /views
app.set("views", __dirname + "/views");
app.use(express.static(__dirname + '/public'));
// Let's use the Jade templating language
app.set("view engine", "jade");
app.get("/", function(request, response) {
response.end("Welcome to the homepage!");
});
app.get("/qaclient", function(request, response) {
response.render("qaclient", { message: "Welcome to QA Forum" });
io.sockets.once('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(){
// store the username in the socket session for this client
socket.join('test_room');
socket.room='test_room';
console.log("------------- List of connected clients on adduser -------------------");
var clients = io.sockets.clients('test_room'); //
console.log(clients);
//socket.username = username;
socket.emit("welcome_fn",socket.room);
// echo to client they've connected
});
socket.on('message', function (data) {
//io.sockets.in(socket.room).emit('broadcast_message', data.name,data.message);
console.log("------------- List of connected clients on message broadcast -------------------");
var clients = io.sockets.clients('test_room'); //
console.log(clients);
socket.broadcast.to('test_room').emit('broadcast_message', data.name,data.message);
//io.sockets.emit('broadcast_message', data.name,data.message);
console.log(data.name);
console.log(data.message);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
console.log('Socket disconnected : ');
console.log(socket.room);
socket.leave('test_room');
//console.log(socket.leave(socket.room));
});
});
});
--
qaclient.js
window.onload = function() {
var messages = [];
var field = document.getElementById("message");
sendButton = document.getElementById("sendbutton");
//var content = document.getElementById("content");
var name = document.getElementById("name");
var socket = io.connect('http://localhost:4040');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser');
});
socket.on('welcome_fn',function(room)
{
chatcontent.innerHTML = "<b>Welcome to Chat central.. Type your message to start chatting in room "+ room +"</b>";
});
socket.on('broadcast_message', function (name,message) {
var data=new Object();
data.message=message;
data.username=name;
if(message) {
messages.push(data);
var html = '';
console.log(messages.length);
for(var i=0; i<messages.length; i++) {
html += '<b>' + messages[i].username + ': </b>';
html += messages[i].message + '<br />';
}
chatcontent.innerHTML = html;
}
//socket.emit('message', { name: name; message:field });
});
sendButton.onclick = function() {
if($.trim(field.value)=="")
{
alert("Enter the message Foo!");
}
else
{
name_tosend_tmp=name.value;
name_tosend= name_tosend_tmp.replace(/(<([^>]+)>)/ig,"");
message_tosend_tmp=field.value;
message_tosend= message_tosend_tmp.replace(/(<([^>]+)>)/ig,"");
socket.emit('message', { name: name_tosend , message:message_tosend });
var data=new Object();
data.message=message_tosend;
data.username=name_tosend;
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + messages[i].username + ': </b>';
html += messages[i].message + '<br />';
}
chatcontent.innerHTML = html;
document.getElementById("name").value="";
document.getElementById("message").value="";
}
}
}
I have a working socket.io server up and running, and i am trying to implement a server side socket.io client. Below is the code snippet i have been using for testing. The problem with this is that the client outputs the message only once, in this case it receives 'Welcome' only. I have tried sending messages to the private channel, 'message' via browser but it doesn't show any output even though the server can receive and emit the message successfully.
Client
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000', {'force new connection': true});
socket.on('connect', function(){
socket.on('message', function (data) {
console.log(data);
});
});
Server
var io = require('socket.io').listen(server);
var i=0;
io.sockets.on('connection', function (socket) {
socket.emit('message', { 'msg': 'Welcome'});
socket.on('message', function (from, msg) {
socket.emit('message', { 'msg': 'Hello World - ' + i });
i++;
});
});
Have you tried doing this?
console.log(data.msg);
Can you try changing "socket" to "this":
this.emit('message', { 'msg': 'Hello World - ' + i });
You should emit from client side to server. So server can send the data back to client. I guess this code works fine :-)
Client
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000', {'force new connection': true});
socket.on('connect', function(){
socket.on('messageRecieved', function (data) {
console.log(data);
});
socket.emit('message','some message');
});
Server
var io = require('socket.io').listen(server);
var i=0;
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log(msg);
socket.emit('messageRecieved', { 'msg': 'Hello World - ' + i });
i++;
});
});
I am using node.js for creating an application that is maintaing the repository for the courses and its respective lectures and slides. And the retreival of courses of student (from mysql Db) is based on student name, the retreival of lectures is based on course name and soo on. The student name is stored on server and i must get it before calling server for getting course list.
Here is my code with more explanation:
var StdName;
$(document).ready(function () {
//connect to server
connectBind();
var socket = $("#click").data();
/**********Query database For student name!!!**********/
try {
socket.emit('askStdName');
}
catch (err) {
alert(err.message);
}
/********Query database For Courses!!!************/
try {
socket.emit('view-contents', StdName);
}
catch (err) {
alert(err.message);
}
});
//connecting to server
function connectBind() {
// connect to server on this port.
var socket = io.connect('http://localhost:3000');
$("#click").data(socket);
/**********GETTING NAME OF STUDENT*********/ //I WANT TO GET STUDENT NAME BEFORE THE QUERY FOR COURSES GET CALLED
try {
socket.on('get-Studentname', function (data) {
StdName = data;
alert("StdName: " + StdName);
});
}
catch (err) {
alert(err.Message);
}
And here is the server side script:
var express = require('express'); //load express
var http = require('http'); // then http
var socketIO = require('socket.io'); // then socket
var mysql = require('mysql');
var nodemailer = require("nodemailer");
var client = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'smartboard_db'
});
client.connect();
var app = express(); // create application
var server = http.createServer(app); //create server
var io = socketIO.listen(server); // start listening to server.
io.set('log level', 2);
// setup routing for static files.
app.use(express.static(__dirname + '/public'));
//start server
server.listen(3000, function(){
console.log('Server running...');
});
// First page
app.get('/', function(request, response) {
response.sendfile(__dirname + '/student-home.html');
});
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
var sucess;
console.log("client connected");
/************SENDING THE NAME TO CLIENT*************/
socket.on('askStdName', function () {
console.log('sending student name to client');
socket.emit('get-Studentname', stdName);
});
/***********CHANNEL FOR GETTING COURSE LIST************/
socket.on('view-contents', function (stdName) {
//console.log("this is what I get from client for courses: " + stdName);
var DATABASE = 'smartboard_db';
client.query('USE ' + DATABASE);
/*****QUEURY FOR COURSES *****************/
client.query('SELECT courses FROM student_info WHERE name = "' + stdName + '"', function (err, results) {
if (err) {
throw err;
}
else {
console.log(JSON.stringify({ courses: results }));
socket.emit('courses', JSON.stringify({ courses: results }));
}
});
});
});
Can ny one help please?
If the get-Studentname event should always be followed by getting the courses:
// request student name
socket.emit('askStdName');
// wait for the student name to be returned, followed by requesting the courses
socket.on('get-Studentname', function (StdName) {
socket.emit('view-contents', StdName);
});
Alternatively, you can pass a function with the request for the student name, which the server can call to send back the response (instead of having the server emit a response). This does require a different setup on your server though:
// client code
socket.emit('askStdName', function(StdName) {
socket.emit('view-contents', StdName);
});
// server code should look like this:
socket.on('askStdName', function(done) {
// get student name (depends on your setup)
...
// call the function to return the value
done(StdName);
});