Too long Socketio communication interval - javascript

My SocketIO server returns a count of 10 to 0 every second, but my web page only updates the number every 10-15 seconds. However, my NodeJS console well displays this count.
In addition, when I manually reload my web page, my browser shows me the correct figure, but suddenly I have to wait 10-15 seconds for it to display the next digit.
NodeJS part
var http = require('http');
var fs = require('fs');
require('events').EventEmitter.prototype._maxListeners = 100;
var server = http.createServer(function(req, res) {
fs.readFile('./serv.html', 'utf-8', function(error, content) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(content);
});
});
function envoi(p1){
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.emit('message', p1);
});
}
main();
function main(){
var interval = setInterval(loop, 1000);
var a = 10;
function loop(){
if(a<1){
clearInterval(interval);
rolling();
}
else{
console.log(a);
a--;
envoi(a);
}
}
}
function rolling(){
console.log('ok');
main();
}
server.listen(8080);
HTML/JS part
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Communication avec socket.io !</h1>
<div id='r'>Connection..</div>
<script src="jquery.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('message', function(message) {
document.getElementById('r').innerHTML = message;
})
</script>
</body>
</html>
Thank you :)
Nathan

There are a few problem with your server side socket.io code that could be causing issues.
Your envoi function is creating a new socket.io server in every loop execution. It is probably returning a cached version, but, you should only invoke listen once. Similar to how creating your http server operates. It should ideally follow your http server creation.
In the same vein, you should only register to the connection event once following your call to listen. You should then store the connected socket somewhere or use the io.socket property to retrieve connected sockets.
Your code that prints down the number should look something like this
let val = 10;
function pushNumber() {
io.sockets.emit('message', val); // Sends message to all sockets on default namespace
val--;
}

Related

Multiple sockets receiving the same randomly generated word - Node.js/Socket.io/Express.js

I would like to generate a random word from an array and then change the innerHTMl of an element to that word. However I would like this to happen so that multiple client browsers are receiving the same word.
Currently every browser is receiving a random word however not the same random word. I understand why this is happening - the function is being called in every browser and therefore generating a unique random word to that browser. How do I ensure that the same randomly generated word is sent out to each individual browser?
Code below:
Index.Js (server side)
var express = require('express')
var socket = require('socket.io')
//App setup
var app = express();
var server = app.listen(8000, function(){
console.log('listening to requests on port 8000')
});
//static files
app.use(express.static('public'));
//socket setup
var io = socket(server);
//listening for connection event from browser on connection fires callback function (backend)
io.on('connection', function(socket) {
console.log('made socket connection', socket.id)
//Listening for colorchange (click event from front end)
socket.on('colorChange', function(){
io.sockets.emit('colorChange')
})
});
button.js Client side
// Make connection (socket for front end)
var socket = io.connect('http://localhost:8000');
let wordList = ['cat', 'dog', 'skunk']
//Accessing DOM
let td1 = document.getElementById("td1")
//Send click to server
td1.addEventListener('click', function(){
socket.emit('colorChange');
});
//Listen for events from back end to execute on front end
socket.on('colorChange', function() {
td1.style.color = "red"
td1.innerHTML = wordList[Math.floor(Math.random() * wordList.length)] //ATTEMPT TO GENERATE RANDOM WORD
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Button Test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
<link href="/style.css" rel="stylesheet"/>
</head>
<body>
<table id="grid">
<tr>
<td id="td1">Hello</td>
</tr>
</table>
<script src="/button.js"></script>
</body>
</html>
Hi here is what you can do:
Index.Js (server side)
var express = require('express')
var socket = require('socket.io')
//App setup
var app = express();
var server = app.listen(8000, function(){
console.log('listening to requests on port 8000')
});
//static files
app.use(express.static('public'));
//socket setup
var io = socket(server);
var wordList = ['cat', 'dog', 'skunk'];
var selectedWord = wordList[Math.floor(Math.random() * wordList.length)];
// when you run server,
// you will have a selectedWord
//listening for connection event from browser on
// connection fires callback function (backend)
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
// everytime someone connecteds send to single user what selectedWord
// currently is
socket.emit('colorChange', selectedWord);
//Listening for colorchange (click event from front end)
socket.on('colorChange', function(){
// when someone wants to change
selectedWord = wordList[Math.floor(Math.random() * wordList.length)];
// we are gonna select a new one and send it to everyone
io.sockets.emit('colorChange', selectedWord);
// so on button.js where you listen this event
// it's gonna set new randomly selected word for every user :=)
})
});
button.js Client side
// Make connection (socket for front end)
var socket = io.connect('http://localhost:8000');
//Accessing DOM
let td1 = document.getElementById("td1")
//Send click to server
td1.addEventListener('click', function(){
socket.emit('colorChange');
});
//Listen for events from back end to execute on front end
socket.on('colorChange', function(word) {
td1.style.color = "red"
td1.innerHTML = word;
});
Edit:
There is also other way that you can create from frontend side and send it to server and broadcast to everyone is also acceptable for your example i'm guessing :)

Client Recieves Data From Server

So I have a Raspberry Pi 4 and im trying to receive data from a JSON file and display it on a text element on my website. sorry if im totally wrong, it's my second day with a Raspberry Pi. I have done basic things like turn an LED on, thanks to w3schools. Im trying to make a bot hosting tool thing for myself, where it will display amount hosted on a TV
index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="index.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
</head>
<body>
<div class="container">
<h1>Bots Hosted:</h1>
<h2 id="bot-qty">0</h2>
</div>
</body>
<script>
var socket = io();
window.addEventListener("load", function() {
var bot_count = document.getElementById("bot-qty");
var times_ran = 0;
const interval = setInterval(function() {
socket.emit("request-count", times_ran);
times_ran++;
}, 20000);
})
socket.on('request-count', function(data) {
document.getElementById("bot-qty").innerText = data;
})
</script>
</html>
webserver.js:
var http = require('http').createServer(handler);
var fs = require('fs');
var io = require('socket.io')(http);
http.listen(1337);
function handler(req, res) {
fs.readFile(__dirname + '/public/index.html', function(err, data) {
if (err) {
res.writeHead(404, { 'Content-Type': 'text/html' });
return res.end("404 Not Found");
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data);
return res.end();
});
}
io.sockets.on('connection', function(socket) {
socket.on('request-count', function(data) {
var bot_count = JSON.parse(fs.readFileSync("config.json", "utf8"));
console.log(bot_count);
socket.emit('request-count', bot_count);
});
});
In console, it says
GET <long_url_here> net::ERR_NAME_NOT_RESOLVER
In the index.html you initialize a new Socket instance by writing
var socket = io();
You don't provide any url, so the socket.io-client will use the default window.location as can be seen here. This might be a problem, so try to set a specific url, e. g.
var socket = io('http://localhost');
or (also specifying the port)
var socket = io('http://localhost:1337');
Also try to make sure that you run your webserver.js with node webserver.js prior to open the website.
Also see this discussion on GitHub.

Socket.io some emmits doesn't trigger while others do

I've been trying to get familiarized with socket.io so use it in a real time app. I went through the basic example, a chat room, then I used ngrok to do a test with more than one client and it's all good. Now I'm looking to use TAFFY to save a log of the conversation on deploy it to a new user that connects to it so I added another emmit to send that log, and this particular emmit doesn't seem to ever trigger the on sentence in the client's side.
These are the server instructions
io.on('connection', function(socket){
console.log("someone connected");
var chatLog={log:[]};
log().each(function (iter){ //this is the taffy var
chatLog.log.push({"usr":iter.usr,"msg":iter.msg});
});
var stringLog=JSON.stringify(chatLog);
console.log(stringLog);
socket.emit('cargaLog', stringLog);// THIS is the naughty emmit
socket.on('chat message', function(msg){
var mensaje=JSON.parse(msg);
log.insert({"usr":mensaje.usr,
"msg":mensaje.msg
});
io.emit('chat message', mensaje.usr.toUpperCase()+" dice: "+mensaje.msg);
});
});
Client's side
$(function () {
var socket = io();
socket.on('cargaLog', function(log){
alert(log); //this never happens
console.log(log);
});
$('form').submit(function(){
var mensaje=$('#m').val();
var json='{"usr":"'+person+'","msg":"'+mensaje+'"}';
socket.emit('chat message', json);
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
var html='<li><img src="defaultUsrImg.png" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
});
I've been staring at this code for a while and none of the solutions that worked with other people work for me (i.e. using io.connect() or io.connect('http://0.0.0.0:8080') on the client's side or having an emmit from the client that asks for the server emmit to be triggered).
Anyone has any idea why this happens?
Altenatively, anyone have any idea that could help me troubleshoot this better?
Other details are:
Running windows 10
Node version 8.2.1
socket.io version 2.0.3
This how I use the node requires:
var TAFFY = require('taffy');
var express=require('express');
var app = express();
var http = require('http');
var path=require('path');
var port = process.env.PORT || 3000;
var server= http.createServer(app).listen(port);
var io = require('socket.io').listen(server);
var log=TAFFY({"usr":"SERVER",
"msg":"WELCOME"
});
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
Client html code (only the boddy because mt html includes and it would bee way too long
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script type="text/javascript" src="./socket.io/socket.io.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<!-- <script src="/mensajes.js"></script> THIS IS THE OLD CODE-->
<script >
var person = prompt("Introduce tu nombre o seudonimo", "anon"); //THIS IS THE WORKING CODE
if(person === null || person===""){
alert("Necesitas un nombre para participar");
}
else{
$(function () {
var socket = io();
socket.emit('ia iege',person);
socket.on('usrConectado',function(usr){
var html='<li><h6>'+(usr)+' se ha conectado</h6></li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
$('form').submit(function(){
var mensaje=$('#m').val();
var json='{"usr":"'+person+'","msg":"'+mensaje+'"}';
socket.emit('chat message', json);
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
var html='<li><img src="https://dujrsrsgsd3nh.cloudfront.net/img/emoticons/419693/pedreiro-1500067445.PNG" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
socket.on('cargaLog', function(log){
console.log(log);
var oldLog=JSON.parse(log);
cargaLog(oldLog);
});
});
function cargaLog(newLog){
//newLog is an object
newLog.log.forEach(function(iter){
var msg=iter.usr.toUpperCase()+' dijo: '+iter.msg;
var html='<li><img src="https://dujrsrsgsd3nh.cloudfront.net/img/emoticons/419693/pedreiro-1500067445.PNG" alt="Usr_img" heigth="40" width="40">'+(msg)+'</li>';
$('#messages').append(html);
window.scrollTo(0, document.body.scrollHeight);
});
}
}
</script>
</body>
I reduced your code down to just the basics and I'm getting the message just fine that you were having trouble with. Here's the reduced code that works just fine:
Server code:
var express = require('express');
var app = express();
var http = require('http');
var path = require('path');
var port = process.env.PORT || 3000;
var server= http.createServer(app).listen(port);
var io = require('socket.io').listen(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/s1.html');
});
io.on('connection', function(socket) {
console.log("someone connected");
var chatLog = {log: [{usr: "someuser", msg: "somemsg"}]};
var stringLog = JSON.stringify(chatLog);
console.log(stringLog);
socket.emit('cargaLog', stringLog); // THIS is the naughty emmit
});
Client Code:
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
<script>
function dbg(x) {
let str = x;
if (typeof x === "object") {
str = JSON.stringify(x);
}
$("#log").append("<div>" + str + "</div>");
}
$(function() {
var socket = io();
socket.on('cargaLog', function(log) {
dbg(log);
});
});
</script>
</head>
<body>
Empty Content, waiting for message to arrive.
<div id="log"></div>
</body>
</html>
When I load the page, the browser immediately displays the cargaLog message that you were having trouble with. I would suggest that you backtrack to something super simple like this until you prove it works and then add things back one at a time until you find what is introducing the problem. If this code does not work for you, then you must have something goofed up in your environment and I'd probably do a reinstall of various components (socket.io, node.js, express, etc...).
Try
socket.emit('chat message' , { usr: person, msg: mensaje});
I think you can try to look at this repository https://github.com/egin10/socket-chat-example/blob/master/app.js for your server side.
and you can try this one for your client side https://github.com/egin10/socket-chat-example/blob/master/chat.html
Note: Just remember about socket.on(params, callback), it's for fetching data from emmiter, and io.emit(params, obj) on server side is for emmiting data.
so, you must make sure about what is your emmiting to server or client and what's your fetching (socket.on()) from serveror client must have same params.
and you must make sure about your object is var chatLog={log:[]};. if you want to get log, you must do like this chatLog.log.
It's work to me. i hope it can help you.

Unable to send data from one Client to another in socket.io Node.JS

I have two clients which can interchange some data over socket.io. I also have a server. What i need to do is i want to send data from client 1 to client 2 over a socket and i am unable to figure out that how i can achieve it.Please note that client 1 and client 2 are different html pages.
Server.JS
var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var ip=process.env.IP||"192.168.1.5";
app.use(express.static(__dirname));
server.listen(port,ip, function () {
console.log('Server listening at port %d ', port);
});
app.get('/index', function(req, res) {
res.sendFile(path.join(__dirname,'/test.html'));
})
app.get('/index1', function(req, res) {
res.sendFile(path.join(__dirname,'/test1.html'));
})
io.on('connection', function (socket) {
socket.on('broadcast', function (message) {
console.log(message);
socket.broadcast.emit('message', message);
});
console.log("connected");
});
Client1.JS
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script >
var socket = io.connect();
socket.emit('broadcast',"Broadcasting Message");
socket.on('message', function (data) {
alert(data)
});
</script>
</body>
Client2.JS
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script >
var socket = io.connect();
socket.on('message', function (data) {
alert(data)
//socket.emit('message',"Hello world");
});
</script>
</body>
Ok, here is what I did on my local and you may change it by your needs.
server.js
var io = require('socket.io')(80);
io.on('connection', function (socket) {
socket.on('broadcast', function (message) {
console.log(message);
socket.broadcast.emit('message', message);
});
console.log("connected");
});
client1.js
var socket = io.connect('ws://127.0.0.1');
socket.emit('broadcast',"Broadcasting Message");
socket.on('message', function (data) {
$('#client1').html(data);
});
client2.js
var socket = io.connect('ws://127.0.0.1');
socket.on('message', function (data) {
$('#client2').html(data);
});
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src='https://code.jquery.com/jquery-1.12.4.min.js'></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="client1.js"></script>
<script type="text/javascript" src="client2.js"></script>
</head>
<body>
<div> <h1> CLIENT 1 </h1><div id="client1"></div></div>
<div> <h1> CLIENT 2 </h1><div id="client2"></div></div>
</body>
</html>
On a termminal after you run, node server.js and reload your page, you will see client2 will have Broadcasting message html appended
Make sure to pass the URL to the server when instantiating WS on the client side... for example var socket = io.connect('http://localhost');
On the server side, each WS connection with each client is a unique instance. That is to say that for this purpose you must be deliberate about which WS connection you target when emitting events.
The first thing to solve is how to associate WS connection instances with specific clients. The answer to this is to use a map/dictionary/plain ol' javascript object with some sort of unique client identifier as the key and the instance of the WS connection as the value. Pseudo-code:
let connections = { 'client1': WSinstance, 'client2': WSinstance };
You would add to this object every time you create a new WS instance. Assuming you have a way to uniquely identify a client and that is stored in the variable clientId, you could do the following:
io.on('connection', function (socket) {
connections[clientId] = socket;
}
Now if you want to emit a message to just client1 you can use the WS instance associated with them by grabbing it from the object connections.client1 or if you want to target client2 connections.client2

how to send messages using socket.io

I want to use socket.io and node as a layer for my "push notification feature", so I'm running both apache and node.
I have the following code on my server (node)
var app = require('http').createServer(handler)
, io = require('C:/path/to/file/socket.io').listen(app)
, fs = require('fs');
app.listen(8080);
function handler(req, res) {
console.log(req);
fs.readFile('C:/path/to/file/index.html',
function (err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.on('my event', function (msg) {
console.log("DATA!!!");
});
});
the page is then served by apache from localhost without 8080 port
and on the client I have the following code:
var socket = io.connect('http://localhost:8080');
and when a button is clicked:
socket.emit('my event', {data:"some data"});
I see nothing on the node console ... why is that? cross domain issue?
Update:
it works just fine on safari 5.1.5 and even IE 9, but not on chrome(18.0.1025.151) or firefox (11.0) ... what am I missing?
here is the node log:
info - socket.io started
debug - served static content /socket.io.js
debug - client authorized
info - handshake authorized 4944162402088095824
debug - setting request GET /socket.io/1/websocket/4944162402088095824
debug - set heartbeat interval for client 4944162402088095824
debug - client authorized for
debug - websocket writing 1::
debug - setting request GET /socket.io/1/xhr-polling/4944162402088095824?t=13
33977095905
debug - setting poll timeout
debug - discarding transport
debug - cleared heartbeat interval for client 4944162402088095824
That should work fine, just make sure that in your index.html you have :
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
also, since you're serving your page via Apache, you really don't need the handler and the http server in you node file.
this should work just fine :
var io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket) {
socket.on('my event', function (msg) {
console.log("DATA!!!");
});
});
and for the index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello World!</title>
<meta charset="utf-8">
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var socket = io.connect('http://localhost:8080');
$("#button").click(function() {
socket.emit('my event' ,"Hello World!");
})
})
</script>
</head>
<body>
<button type="button" id='button'>Send Message</button>
</body>
</html>
Edit: This works in both Firefox and Chrome.

Categories

Resources