Js node - socket.io chat modificaion - javascript

Here is a simple chat example. How can I modify the script so that:
in the first 5s, the first user can send a message, and in the next 5s, the user can't send a message
in the next 5s (when the first user cannot send a message), the second user can send message and the first user gets a div (apIdv1) to display
index.html:
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
// 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', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatechat', function (username, data) {
$('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updaterooms', this updates the room the client is in
socket.on('updaterooms', function(rooms, current_room) {
$('#rooms').empty();
$.each(rooms, function(key, value) {
if(value == current_room){
$('#rooms').append('<div>' + value + '</div>');
}
else {
$('#rooms').append('<div>' + value + '</div>');
}
});
});
function switchRoom(room){
socket.emit('switchRoom', room);
}
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
socket.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
</script>
<style type="text/css">
#apDiv1 {
position:absolute;
width:200px;
height:115px;
z-index:1;
left: 150px;
top: 20px;
background-color: #FF9900;
display:none;
}
</style>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>ROOMS</b>
<div id="rooms"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
<div id="conversation"></div>
<input id="data" style="width:200px;" />
<input type="button" id="datasend" value="send" />
</div>
<div id="apDiv1"></div>
app.js
var app = require('express').createServer()
var io = require('socket.io').listen(app);
app.listen(8080);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// usernames which are currently connected to the chat
var usernames = {};
// rooms which are currently available in chat
var rooms = ['room1','room2','room3'];
io.sockets.on('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// store the username in the socket session for this client
socket.username = username;
// store the room name in the socket session for this client
socket.room = 'room1';
// add the client's username to the global list
usernames[username] = username;
// send client to room 1
socket.join('room1');
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected to room1');
// echo to room 1 that a person has connected to their room
socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room');
socket.emit('updaterooms', rooms, 'room1');
});
// when the client emits 'sendchat', this listens and executes
socket.on('sendchat', function (data) {
// we tell the client to execute 'updatechat' with 2 parameters
io.sockets.in(socket.room).emit('updatechat', socket.username, data);
});
socket.on('switchRoom', function(newroom){
// leave the current room (stored in session)
socket.leave(socket.room);
// join new room, received as function parameter
socket.join(newroom);
socket.emit('updatechat', 'SERVER', 'you have connected to '+ newroom);
// sent message to OLD room
socket.broadcast.to(socket.room).emit('updatechat', 'SERVER', socket.username+' has left this room');
// update socket session room title
socket.room = newroom;
socket.broadcast.to(newroom).emit('updatechat', 'SERVER', socket.username+' has joined this room');
socket.emit('updaterooms', rooms, newroom);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
socket.leave(socket.room);
});
});
How can I show apDiv1 for the first 5s to one user, then make it disappear, and vice versa for the second user?
UPDATE with answer:
Why this now dont work?
app.js
var app = require('express').createServer()
var io = require('socket.io').listen(app);
app.listen(8080);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// usernames which are currently connected to the chat
var usernames = {};
// rooms which are currently available in chat
var rooms = ['room1','room2','room3'];
io.sockets.on('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// store the username in the socket session for this client
socket.username = username;
// store the room name in the socket session for this client
socket.room = 'room1';
// add the client's username to the global list
usernames[username] = username;
// send client to room 1
socket.join('room1');
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected to room1');
// echo to room 1 that a person has connected to their room
socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room');
socket.emit('updaterooms', rooms, 'room1');
});
// when the client emits 'sendchat', this listens and executes
socket.on('sendchat', function (data) {
// we tell the client to execute 'updatechat' with 2 parameters
io.sockets.in(socket.room).emit('updatechat', socket.username, data);
});
socket.on('switchRoom', function(newroom){
// leave the current room (stored in session)
socket.leave(socket.room);
// join new room, received as function parameter
socket.join(newroom);
socket.emit('updatechat', 'SERVER', 'you have connected to '+ newroom);
// sent message to OLD room
socket.broadcast.to(socket.room).emit('updatechat', 'SERVER', socket.username+' has left this room');
// update socket session room title
socket.room = newroom;
socket.broadcast.to(newroom).emit('updatechat', 'SERVER', socket.username+' has joined this room');
socket.emit('updaterooms', rooms, newroom);
});
function redLightGreenLight() {
socket1.emit('redLight');
socket2.emit('greenLight');
}
setTimer('redLightGreenLight()', 5000);
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
socket.leave(socket.room);
});
});
index.html
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
// 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', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatechat', function (username, data) {
$('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updaterooms', this updates the room the client is in
socket.on('updaterooms', function(rooms, current_room) {
$('#rooms').empty();
$.each(rooms, function(key, value) {
if(value == current_room){
$('#rooms').append('<div>' + value + '</div>');
}
else {
$('#rooms').append('<div>' + value + '</div>');
}
});
});
function switchRoom(room){
socket.emit('switchRoom', room);
}
*socket.on('greenLight', function (data) {
// change div to enable sending a message
});
socket.on('redLight', function (data) {
// change div to index.html*
});
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
socket.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
</script>
<style type="text/css">
#greenLight {
position:absolute;
width:200px;
height:115px;
z-index:1;
left: 150px;
top: 20px;
background-color: #FF9900;
display:none;
}
</style>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>ROOMS</b>
<div id="rooms"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
<div id="conversation"></div>
<input id="data" style="width:200px;" />
<input type="button" id="datasend" value="send" />
</div>
***<div id="greenLight"></div>***

Quoth beginerplus, "maybe is better to server to do job... how to change my script to do that? please write as example on an answer":
On the server:
function redLightGreenLight() {
socket1.emit('redLight');
socket2.emit('greenLight');
}
setTimer('redLightGreenLight()', 5000);
On the client:
socket.on('greenLight', function (data) {
// change div to enable sending a message
});
socket.on('redLight', function (data) {
// change div to index.html
});

There are two ways:
the server sends a message to each client after 5 seconds, using setTimer (or setInterval in case you need to repeat): client #1 can't send a message any more, and client #2 can. Then each client handles the message by changing the div content.
each client uses setTimer or setInterval on its own; this may have some advantages depending on your use case, but probably has the disadvantage that the timers won't start at exactly the same time.

Related

Socket.io show amount of user connections

I got a very simple socket.io application where I'm able to see when a user connects to my site and when a user leaves. The first user is able to see everybody that gets in, however the second will only see the people coming in after him, and so on.... What I want the user that connects to see are all current connected users
Server.js
var io = require("socket.io")(http);
var users = [];
io.on("connection", function (socket) {
console.log("User connected", socket.id);
Some loop to see user connected I think?!
socket.on("user_connected", function (username) {
users[username] = socket.id;
console.log(users);
if (username !== 'null'){
io.emit("user_connected", username);
}
});
socket.on("send_message", function (data) {
io.emit("new_message", data);
});
socket.on("user_left", function (datan) {
io.emit("user_remove", datan);
console.log("user left", datan);
});
});
site.html
window.onbeforeunload = function () {
io.emit("user_left", name);
};
var name = <?php echo json_encode($_SESSION['displayname']); ?>;
var bild = <?php echo json_encode($_SESSION['userpic']);?>;
var dt = new Date();
var tid = dt.getHours() + ":" + dt.getMinutes();
io.emit("user_connected", name);
sender = name;
io.on("user_connected", function (username) {
var html = "";
html += "<li data-username='" + username + "'>" + username + "</li>";
document.getElementById("users").innerHTML += html;
});
Looked into this question, but me a dumb coder doesn't understand what 'my_room' is towards my soloution. Sorry for weird question, I'm just kind of lost
If you want to send a user list to everyone, create an object like users, add a record each time a user connected, and broadcast to everyone.
if someone disconnects, then first remove that from your collection then send only disconnected user's info to clients, so clients can delete that user from their list.
If all you want is total number of questions, just send io.sockets.clients().length

Express not doing anything but sending HTML file

I'm using an app.post method in Express like so:
app.post('/race', function(req,res) {
let raceResponse = {
user_name: req.body.userName
}
console.log('Express has received race.');
//Socket.IO
let race = io.of('/race').on('connection', (socket) => {
console.log('A user has entered the race!');
socket.on('racePageReady', function() {
console.log('race page ready recieved');
socket.emit('racePageInfo', raceResponse);
});
socket.on('createRoom', function(roomName) {
socket.join(roomName);
let clients = io.sockets.adapter.rooms[roomName].sockets;
console.log("A room with the name " + roomName + "was created.");
console.log(clients);
socket.emit('roomCreated', clients);
});
socket.on('joinRoom', function(roomName) {
socket.join(roomName);
let clients = io.sockets.adapter.rooms[roomName].sockets;
console.log('A user joined the room with the name: ' + roomName + ". The user's name is " + raceResponse.user_name);
console.log(clients);
socket.emit('roomCreated', clients);
});
});
res.sendFile(path.join(__dirname, '/client/race/index.html'));
}
The page is being sent fine, but the console.log and all the other Socket.IO stuff just doesn't happen. I'm finding this peculiar, because I have a different app.post method that works just fine, all console.logging and Socket.IO business happens. Here's the code:
app.post('/city', function(req,res) {
let cityResponse = {
user_name: req.body.userName
}
console.log('Express has received city.');
//Socket.IO
let city = io.of('/city').on('connection', (socket) => {
socket.id = Math.random();
socket.name = cityResponse.user_name;
SOCKET_LIST[socket.id] = socket; //defined earlier
User.onConnect(socket); //defined earlier
socket.on('cityPageReady', function() {
socket.emit('cityPageInfo', cityResponse);
console.log('city page ready recieved');
});
console.log('A user has connected to the city!');
console.log("Socket: " + socket);
console.log("Socket ID: " + socket.id);
console.log("SOCKET_LIST: ");
console.log(SOCKET_LIST);
socket.on('chat message', function(msg, user) {
console.log('User ' + user + ' sent the message : ' + msg);
socket.emit('chat message', msg, user);
});
});
res.sendFile(path.join(__dirname, '/client/city/index.html'));
});
As far as I can tell, both methods look pretty much the same, except for the Socket.IO stuff in the middle. I'm fairly certain that the io.of method is correct, as it's working for the City page, but not the race.
The only other difference is the way that the two pages are accessed. The City page is accessed through a HTML form with an action attribute, whereas the Race page is accessed through a HTML link (on the City page) with a href attribute.
Both methods are shown below:
CITY
<form id="cityForm" action="http://localhost:4000/city" method="POST">
User name: <input type="text" name="userName">
button type="submit" id="formSubmit">Submit</button>
</form>
RACE
<div><a href="http://localhost:4000/race"></div>
Can anyone see why this peculiar behaviour is occuring? If any other information is needed please let me know so that I can include it.
When clicking an on HTML link, the browser does a GET HTML request. When you submit a Form (with method="POST"), the browser does a POST request.
When using app.post(), you tell express to listen for POST requests. If you want express to listen for GET requests, you should use app.get()

Not showing client welcome message in socket.io / node.js

i made a primitive chatroom in nodejs and socket.io here and i am trying to get it to display the username and a welcome message to just the user as well as a message that shows all the other users that he/she joined here is my code
server code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var usernames = {};
app.get('/', function(req, res){
res.sendfile('index.html');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
socket.on('adduser', function(username){
socket.username = username;
socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected to this room' + '<hr>');
socket.emit('welcomeuser', 'SERVER Welcome', username + '<hr>');
});
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconected');
});
socket.on('chat-message', function (message) {
console.log('message : ' + message.text);
//excludes "socket" from getting the emit
socket.broadcast.emit("chat-message",message);
});
});
and here is my client code
var username = "";
var socket = io();
socket.on('connect', function(){
socket.emit('adduser', prompt("What's your name?"));
});
socket.on('updatechat', function (username, data) {
$('#chatlog-display-div').append('<b>'+username + ':</b> ' + data + '<br>');
});
socket.on('welcomeuser', function(username, data){
jQuery("#chatlog-display-div").append( username +'<hr>');
});
$('form').submit(function(e) {
e.preventDefault();
//gets the value from the message text feild and sets it as the message var
var message = {
text : $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message',message);
//append the message to the chatlog-display-div
$('#chat-box-div-txtinpt').focus().val('');
jQuery("#chatlog-display-div").append('<div>'+message.text+'</div><hr>');
}
});
//clear the value of the txtinput after you focus it.
socket.on('chat-message', function (message) {
jQuery("#chatlog-display-div").append('<div>'+message.text+'</div><hr>');
});
can someone please help me

printing a variable into a div

I am atempting to build a chatroom with NodeJS and Socket.io and I have gotten so far as to get the users input and send it to the Node server but that's all I want to be able to display it up in a div
Client-side script
var socket = io();
$('form').submit(function(e) {
e.preventDefault();
// gets the value from the message text feild and sets it as the message var
var message = {
text: $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
}
$('#chat-box-div-txtinpt').focus();
document.getElementById('chat-box-div-txtinpt').value='';
});
Server-side script
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconected');
});
socket.on('chat-message', function (message) {
console.log('message: ' + message.text);
});
});
Here is the site
It appears you're using jQuery, so for this line: document.getElementById('chat-box-div-txtinpt').value=''; you could just do $('#chat-box-div-txtinpt').val('');
to answer your question: you could just do $('#chatlog-display-div').append(message.text)
Your code would end up looking something like this
$('form').submit(function(e) {
e.preventDefault();
//gets the value from the message text feild and sets it as the message var
var message = {
text : $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
//append the message to the chatlog-display-div
$('#chatlog-display-div').append(message.text);
}
//clear the value of the txtinput after you focus it.
$('#chat-box-div-txtinpt').focus().val('');
});
please mark as accepted answer if you feel this adequately solves the issue.
To send messages to everyone from the server use emit() from io
on server
socket.on('chat-message', function (message) {
console.log('message : ' + message.text);
io.emit("chat-message",message);
});
on client
socket.on('chat-message',function(message){
//add message to the chat window
});
If you do not want the person sending the message to get the chat-message emit then use broadcast.emit() from the socket that sent it
//server
socket.on('chat-message', function (message) {
console.log('message : ' + message.text);
//excludes "socket" from getting the emit
socket.broadcast.emit("chat-message",message);
});
To actually put the message in the div just use any of jQuery's various methods html()/text()/append()
//client
socket.on('chat-message', function (message) {
jQuery(".chat-window").append('<div>'+message.text+'</div>');
});
You could simple .append the text to "chatlog-display-div" with a templet if you use ES6 could be something like
$('form').submit(function(e) {
e.preventDefault();
//gets the value from the message text feild and sets it as the message var
var message = {
text : $('#chat-box-div-txtinpt').val()
}
if (message.text.trim().length !== 0) {
socket.emit('chat-message', message);
document.getElementById('chatlog-display-div').append('<divclass="message-style" > ${message.text}</div>')
}
$('#chat-box-div-txtinpt').focus();
document.getElementById('chat-box-div-txtinpt').value='';
});

node, socket.io - update client when new entry added to news feed?

I've created client and server of node with socket.io. server is executing 4 get requests of news feed and fetched the data. These data is sent to the client with socket.io.
client is displaying news feed on the occurrence of specific socket.io event.
This works well for once. Here is the code and working fiddle
server.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, redis = require("redis");
var http = require("http");
// initialize the container for our data
var data = "";
var nfs = [
"http://economictimes.feedsportal.com/c/33041/f/534037/index.rss",
"http://www.timesonline.co.uk/tol/feeds/rss/uknews.xml",
"http://www.independent.co.uk/news/business/rss",
"http://www.dailymail.co.uk/money/index.rss"
];
//setInterval(function() {
for(var i=0; i<nfs.length; i++){
//console.log(nfs[i]);
http.get(nfs[i], function (http_res) {
// this event fires many times, each time collecting another piece of the response
http_res.on("data", function (chunk) {
// append this chunk to our growing `data` var
data += chunk;
});
// this event fires *one* time, after all the `data` events/chunks have been gathered
http_res.on("end", function () {
// you can use res.send instead of console.log to output via express
console.log("data received");
});
});
}
//}, 30000);
app.listen(8080);
function handler (req, res) {
fs.readFile(__dirname + '/client.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
//setInterval(function() {
socket.emit('news', data);
/*socket.on('my other event', function (data) {
console.log(data);
});*/
//}, 5000);
});
client.html
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
//socket io client
var socket = io.connect('http://localhost:8080');
//on connetion, updates connection state and sends subscribe request
socket.on('connect', function(data){
setStatus('connected');
socket.emit('subscribe', {channel:'notif'});
});
//when reconnection is attempted, updates status
socket.on('reconnecting', function(data){
setStatus('reconnecting');
});
//on new message adds a new message to display
socket.on('news', function (data) {
console.log(data);
//socket.emit('my other event', { my: 'data' });
addMessage(data);
});
/*socket.on('news', function (data) {
debugger;
socket.emit('my other event', { my: 'data' }
var msg = "";
if (data) {
msg = data;
}
addMessage(msg);
});*/
//updates status to the status div
function setStatus(msg) {
$('#status').html('Connection Status : ' + msg);
}
//adds message to messages div
function addMessage(msg) {
//debugger;
var $xml = $(msg);
var html = '';
$xml.find("item").each(function() {
var $item = $(this);
html += '<li>' +
'<h3><a href ="' + $item.find("link").text() + '" target="_new">' +
$item.find("title").text() + '</a></h3> ' +
'<p>' + $item.find("description").text() + '</p>' +
// '<p>' + $item.attr("c:date") + '</p>' +
'</li>';
});
$('#result').prepend(html);
}
</script>
</head>
<body>
<div id="status"></div><br><br>
<ul id="result"></ul>
</body>
</html>
What I understand about socket.io is that we don't need long server polling and so how do server come to know that news is added to the respected news feed.
How do I update the client with newly added news when news is added to the news feed rss ???
Update
Ok so from all the responses I get the point that it is not possible for socket.io to know that new entry has been added. So, how do I know (which tools/libraries do require to know that new entry has beed added and update the client as well) ???
Retrieving the messages from the news feeds are completely independent of socket.io unless the news feeds implement sockets on their end and your server becomes their client. So you will have to continue to poll them with http requests to know whether they have updated data.
In order to notify your clients of the update you would just emit the news event. Presumably you would have logic on the server to make sure you are only sending events which have not previously be sent.
There is no way for "node" to know when a new entry is added to the news feed. You will have to poll the news service like you are doing now. This really has nothing to do with Node or Socket.io unless I completely misunderstand what you are asking.

Categories