Issue about socket.io real-time text display - javascript

I am trying to use node.js and socket.io library to establish websocket connection between client and server. The server will generate a random number per second and it will emit a event which allow client to detect.
The problem is the client(a webpage) can detect the event and display the random number send by server, but it's not real-time. I had to refresh my browser in order to display a new random number. I want the client to display the random number in real-time but I don't know why my websocket app appears to be not real-time.
Server(main.js) source code:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
randomNum();
function randomNum(){
io.on('connection', function(socket){
socket.emit('random', Math.floor((Math.random() * 100) + 1));
});
setInterval(randomNum, 1000);
}
server.listen(8080);
Client(index.html) source code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Websocket</title>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('random', function(data){
document.getElementById("displayNum").innerHTML = data;
});
</script>
</head>
<body>
<p id="displayNum"></p>
</body>
</html>

You shouldn't do this:
function randomNum(){
io.on('connection', function(socket){
socket.emit('random', Math.floor((Math.random() * 100) + 1));
});
setInterval(randomNum, 1000);
}
You set io.on connection every 1s. You should make function for emiting your random and set interval outside this function

Related

node js simple chat app delay on event trigger

i prepared a simple chat system while practicing node.js. but theres a problem while sending messages. quite a good amount of delay taking place while sending messages and i couldnt figure out why. can anyone help me how to improve attached code ?
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(client) {
client.on('messageSend', function(data) {
client.broadcast.emit('messageRecieve', data);
});
});
http.listen(9090, function() {
console.log('Listening on port 9090');
io.on('connect', function(socket) {
console.log("Connection established : " + socket.client.conn.remoteAddress);
})
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket Test</title>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
function messageSend() {
var message = document.getElementById("messageInput").value;
console.log(message);
var ul = document.getElementById("messageNode");
var li = document.createElement("li");
li.appendChild(document.createTextNode(message));
li.setAttribute("style", "font-style : italic; color : red;");
ul.appendChild(li);
socket.emit('messageSend', message);
}
socket.on('messageRecieve', function(data) {
var message = data;
var ul = document.getElementById("messageNode");
var li = document.createElement("li");
li.appendChild(document.createTextNode(message));
ul.appendChild(li);
console.log(message);
});
</script>
</head>
<body>
<input id="messageInput" type="text"> <button onclick="messageSend()">Send</button><br>
<ul id="messageNode">
</ul>
</body>
</html>
the official socket.io example sends the message to everyone, including yourself
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
You sent to everyone except yourself (which is the most accurate method)
io.on('connection', function(client) {
client.on('messageSend', function(data) {
client.broadcast.emit('messageRecieve', data);
});
});
The reason for your slowdown is probably becouse your browser puts your out-of-focus tabs in a sort of sleep mode, which makes it update much less frequently... If you compare your code vs socket.io's code between computer and phone via lan. I would guess the speed for your server-sent message would be the same
Right now you are basically competing versus socket.io's "optimistic updates". It pushes the message to your client directly without waiting for the server, which your own code does. As well as browser out-of-focus low priority mode

Socket IO output too many times

This question has already been answered, but I can't understand it at all. You can find it at this link.
socket.on calls its callback too many times
I have the same problem as this fellow. I'm attempting to make a chat program with socket.io, but when more than one user joins, each message outputs the number of times of how many users have been connected.
For example, when one user is connected, and he submits a message. It outputs once. When two users are connected, each of their messages output twice.
When three users are connected, each of their messages output three times.
Here is my client side code:
$('document').ready(function() {
var server = io.connect('http://localhost:8888');
$('.chat').keydown(function(event){
var save = this;
if(event.which == 13){
server.emit('message', $(save).val());
$(save).val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
Here is my server side code:
var socket_io = require('socket.io').listen(8888).sockets;
socket_io.on('connection', function(socket){
socket.on('message', function(message){
socket_io.emit('incoming', message)
});
});
Thank you!
You can use socket.broadcast.emit() to send to everyone except that socket:
var io = require('socket.io')(8888);
io.on('connection', function(socket) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
UPDATE: The following example works just fine for me:
server.js:
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.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) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
index.html:
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$('document').ready(function() {
var server = io.connect('http://localhost');
$('.chat').keydown(function(event) {
if (event.which == 13) {
var $save = $(this);
server.emit('message', $save.val());
$save.val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
</script>
</head>
<body>
<input type="text" class="chat">
<div id="textfield"></div>
</body>
</html>
When pressing enter, the message in the input box is only displayed once to all other connected socket.io users.
Okay, I've finally figured out the problem.
I'm using Express 4.0. That means, I'm using routes to run the server, and I had the socket io code running inside the route. Each time a user connects, it has to go through the route first, and it's all binding onto the same socket_io.
Thanks to everybody who helped!
I also faced it, like multiple socket calls in network tab and i just add this "transports" key object to socket instance, both on client and backend.
socket = io("http://localhost:3002", {
transports: ['websocket']
})
React, Node, AWS EB

Change html text based on node.js server setTimeout()

How would one change the text of a div to another string of text after a certain period of time using node.js and the setTimeout function?
The main caveat is that the text should be changed for all users at the same time.
Let's say an h2 title on the index page would initially say "Welcome to this page."
5 seconds later (after the server time, not after the time of a request), that h2 title should change to "Let's get started."
If another request came in 6 seconds after the server started, they should see "Let's get started." and never see "Welcome to this page." since the h2 title should have been universally changed.
Any guidance hugely appreciated.
Here is what you may try (Express + SocketIO 1.0 example):
server.js:
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(80);
var dir = __dirname;
app.get('/', function(req, res) {
res.sendfile(dir + '/index.html');
});
var header = 'Welcome to this page.';
setTimeout(function() {
header = 'Let\'s get started.';
io.emit('change_header', {
header: header
});
}, 5000);
io.on('connection', function(socket) {
socket.emit('change_header', {
header: header
});
});
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var socket = io();
socket.on('change_header', function(data) {
document.getElementById('header').innerHTML = data.header;
});
});
</script>
</head>
<body>
<h2 id="header"></h2>
</body>
</html>

Redis Pub/Sub not displaying published message in client using redis-cli

Hello guys i'm having a problem in redis pub/sub because my client does not show the message i've published in redis-cli. I used the codes found here in stackoverflow and i made some modification. Here is the link and code. I hope you can help me, my goal is to publish the message to the client index.html using redis publish in redis-cli. I've done this before but i can't make it work again. Thanks in advance guys.
Here is my client index.html
<html>
<head>
<title>PubSub</title>
<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 src="/javascripts/socket.js"></script> -->
</head>
<body>
<div id="content"></div>
<script>
var socket = io.connect('http://localhost:3000');
var content = $('#content');
socket.on('connect', function() {
});
socket.on('message', function (message){
content.prepend(message + '<br />');
}) ;
socket.on('disconnect', function() {
console.log('disconnected');
content.html("<b>Disconnected!</b>");
});
socket.connect();
});
</script>
</body>
</html>
Here is my server.js
var express = require('express');
var app = express();
var redis = require('redis');
var http = require('http');
var server = http.createServer(app);
var socket = require('socket.io').listen(server);
var publish = redis.createClient();
app.listen(3000);
console.log("Express server listening on port 3000")
app.get('/', function (req,res) {
res.sendfile(__dirname + '/public/index.html');
});
socket.on('connection', function (client) {
var subscribe = redis.createClient();
subscribe.subscribe('pubsub');
subscribe.on("message", function (channel, message) {
publish.send(message);
});
publish.on('message', function (msg) {
});
publish.on('disconnect', function() {
subscribe.quit();
});
});
Redis will not send data to connected clients for you. You must instruct Socket.IO to emit data:
subscribe.on("message", function (channel, message) {
socket.emit('message', message);
});

using a Websocket page from the local Machine

I'm working on an applicatioin that I want to use with websocket interaction. I've used a node.js and socket.io based server and simple chat page as a starter for my page. I'm making modifications and figuring out the interactions between the server and html page.
The person who wrote the basic chat page used inline javascript on the html page as the client side of the chat, so I've broken that out into its own javascript file, no big deal there.
The issue is that I want to use the html and associated javascript file from the local machine, to connect to the node.js server I'm creating on the web-server. His setup was accessing the html page on the web-server in the same folder as the server.js file that acted as the web-socket server.
I'm trying to figure out how to get the client side javascript file to start doing it's thing when the page is opened (i'm guessing an on load event is needed), and how to set it up to call to the webserver javascript file.
I'm going to post his code here, it's not mine, I just used his tutorial to make the chat.html and server.js. Basically copy and paste.
Any help or guidance is greatly appreciated as always.
-----------------chat.html--------------------------
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Chat</title>
<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 URL = window.location.protocol + "//" + window.location.host;
console.log("Connecting to " + URL);
var socket = io.connect(URL);
// 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 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
// 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>
</head>
<body>
<h1>WebSocket Chat</h1>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>USERS</b>
<div id="users"></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>
</body>
</html>
---------------------server.js-----------------------------
var port = 5000;
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
console.log("Listening on port " + port);
server.listen(port);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/chat.html');
});
// usernames which are currently connected to the chat
var usernames = {};
io.sockets.on('connection', function (socket) {
// when the client emits 'sendchat', this listens and executes
socket.on('sendchat', function (data) {
// we tell the client to execute 'updatechat' with 2 parameter
io.sockets.emit('updatechat', socket.username, data);
});
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected');
// update the list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
});
// 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');
});
});

Categories