Client Recieves Data From Server - javascript

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.

Related

Too long Socketio communication interval

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--;
}

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 do I define Watershed in Node.js?

When I execute the following code, I get the error: Reference Error: Watershed is not defined. How can I define it? Do I need a module to be installed for it?
var restify=require('restify');
var ws= new Watershed();
var server=restify.createServer();
server.get('websocket/attach', function upgradeRoute(req, res, next){
if(!res.claimUpgrade){
next(new Error("Connection must be upgraded."));
return;
}
var upgrade=res.claimUpgrade();
var shed=ws.accept(req, upgrade.socket, upgrade.head);
shed.on('text', function (msg){
console.log("The message is: "+msg);
});
shed.send("hello there");
next(false);
});
server.listen(8081, function(){
console.log('%s listening at %s', server.name, server.url);
});
There is also a section of the restify doc that mentioned how to handle the ability to upgrade sockets. I just struggled with this for an emarrassingly long time and thought I'd share the simple solution. In addtion the #Dibu Raj reply, you also need to create your restify server with the handleUpgrades option set to true. Here is a complete example to make restify work with websocket upgrades and watershed:
'use strict';
var restify = require('restify');
var watershed = require('watershed');
var ws = new watershed.Watershed();
var server = restify.createServer({
handleUpgrades: true
});
server.get('/websocket/attach', function (req, res, next) {
if (!res.claimUpgrade) {
next(new Error('Connection Must Upgrade For WebSockets'));
return;
}
console.log("upgrade claimed");
var upgrade = res.claimUpgrade();
var shed = ws.accept(req, upgrade.socket, upgrade.head);
shed.on('text', function(msg) {
console.log('Received message from websocket client: ' + msg);
});
shed.send('hello there!');
next(false);
});
//For a complete sample, here is an ability to serve up a subfolder:
server.get(/\/test\/?.*/, restify.serveStatic({
directory: './static',
default: 'index.html'
}));
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
For an html page to test your new nodejs websocket server: write this html below into a file at ./static/test/index.html - point your browser to http://localhost:8080/test/index.html - open your browser debug console to see the message exchange.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Web Socket test area</title>
<meta name="description" content="Web Socket tester">
<meta name="author" content="Tim">
</head>
<body>
Test Text.
<script>
(function() {
console.log("Opening connection");
var exampleSocket = new WebSocket("ws:/localhost:8080/websocket/attach");
exampleSocket.onopen = function (event) {
console.log("Opened socket!");
exampleSocket.send("Here's some text that the server is urgently awaiting!");
};
exampleSocket.onmessage = function (event) {
console.log("return:", event.data);
exampleSocket.close();
}
})();
</script>
</body>
</html>
Your browser log will look something like this:
07:05:05.357 index.html:18 Opening connection
07:05:05.480 index.html:22 Opened socket!
07:05:05.481 index.html:26 return: hello there!
And your node log will look like:
restify listening at http://[::]:8080
client connected!
Rest service called started
upgrade claimed
Received message from websocket client: Here's some text that the server is urgently awaiting!
Documentation for this found at:
http://restify.com/#upgrade-requests
You should include the watershed library
var Watershed = require('lib/watershed').Watershed;

socket.io 404 cant connect with socket.io server

I have webrtc / socket.io / nodejs running on a server, everything works fine when i go to the https://domain.com:8080 to test a video conference.
But i want the script to run in my webserver /public_html/
But i dont know why it is not connecting to the 8080 server.
"socket.io.js GET https://domain.com/socket.io/?EIO=3&transport=polling&t=LPgZs2K 404 (Not Found)"
my server (server.js)
// Load required modules
var https = require("https"); // http server core module
var express = require("express"); // web framework external module
var serveStatic = require('serve-static'); // serve static files
var socketIo = require("socket.io"); // web socket external module
var easyrtc = require("../");
const fs = require('fs'); // EasyRTC external module
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
// Set process name
process.title = "node-easyrtc";
// Setup and configure Express http server. Expect a subfolder called "static" to be the web root.
var app = express();
app.use(serveStatic('static', {'index': ['index.html']}));
// Start Express http server on port 8080
var webServer = https.createServer(options, app).listen(8080);
// Start Socket.io so it attaches itself to Express server
var socketServer = socketIo.listen(webServer, {"log level":1});
easyrtc.setOption("logLevel", "debug");
// Overriding the default easyrtcAuth listener, only so we can directly access its callback
easyrtc.events.on("easyrtcAuth", function(socket, easyrtcid, msg, socketCallback, callback) {
easyrtc.events.defaultListeners.easyrtcAuth(socket, easyrtcid, msg, socketCallback, function(err, connectionObj){
if (err || !msg.msgData || !msg.msgData.credential || !connectionObj) {
callback(err, connectionObj);
return;
}
connectionObj.setField("credential", msg.msgData.credential, {"isShared":false});
console.log("["+easyrtcid+"] Credential saved!", connectionObj.getFieldValueSync("credential"));
callback(err, connectionObj);
});
});
// To test, lets print the credential to the console for every room join!
easyrtc.events.on("roomJoin", function(connectionObj, roomName, roomParameter, callback) {
console.log("["+connectionObj.getEasyrtcid()+"] Credential retrieved!", connectionObj.getFieldValueSync("credential"));
easyrtc.events.defaultListeners.roomJoin(connectionObj, roomName, roomParameter, callback);
});
// Start EasyRTC server
var rtc = easyrtc.listen(app, socketServer, null, function(err, rtcRef) {
console.log("Initiated");
rtcRef.events.on("roomCreate", function(appObj, creatorConnectionObj, roomName, roomOptions, callback) {
console.log("roomCreate fired! Trying to create: " + roomName);
appObj.events.defaultListeners.roomCreate(appObj, creatorConnectionObj, roomName, roomOptions, callback);
});
});
//listen on port 8080
webServer.listen(8080, function () {
console.log('listening on http://localhost:8080');
});
my html file on de WEB server. structure like this https://domain.com/test.html
<!DOCTYPE html>
<html>
<head>
<title>EasyRTC Demo:EasyRTC Demo: Video+Audio HD 720</title>
<link rel="stylesheet" type="text/css" href="/easyrtc/easyrtc.css" />
<script src="js/socket.io.js"></script>
<script type="text/javascript" src="js/easyrtc.js"></script>
<script type="text/javascript" src="js/video.js"></script>
<script>
var selfEasyrtcid = "";
function connect() {
easyrtc.setVideoDims(1280,720);
easyrtc.enableDebug(false);
easyrtc.setRoomOccupantListener(convertListToButtons);
easyrtc.easyApp("easyrtc.videoChatHd", "selfVideo", ["callerVideo"], loginSuccess, loginFailure);
}
function clearConnectList() {
var otherClientDiv = document.getElementById("otherClients");
while (otherClientDiv.hasChildNodes()) {
otherClientDiv.removeChild(otherClientDiv.lastChild);
}
}
function convertListToButtons (roomName, data, isPrimary) {
clearConnectList();
var otherClientDiv = document.getElementById("otherClients");
for(var easyrtcid in data) {
var button = document.createElement("button");
button.onclick = function(easyrtcid) {
return function() {
performCall(easyrtcid);
};
}(easyrtcid);
var label = document.createTextNode(easyrtc.idToName(easyrtcid));
button.appendChild(label);
button.className = "callbutton";
otherClientDiv.appendChild(button);
}
}
function performCall(otherEasyrtcid) {
easyrtc.hangupAll();
var acceptedCB = function(accepted, caller) {
if( !accepted ) {
easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(caller) + " was rejected");
}
};
var successCB = function() {};
var failureCB = function() {};
easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB);
}
function loginSuccess(easyrtcid) {
selfEasyrtcid = easyrtcid;
document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid);
}
function loginFailure(errorCode, message) {
easyrtc.showError(errorCode, message);
}
// Sets calls so they are automatically accepted (this is default behaviour)
easyrtc.setAcceptChecker(function(caller, cb) {
cb(true);
} );
</script>
</head>
<body onload="connect();">
<h1>EasyRTC Demo: Video+Audio HD 720p</h1>
<div id="demoContainer">
<div>
Note: your own image will show up postage stamp sized, while the other party"s video will be shown in high-definition (1280x720). Note: not all webcams are seen by WebRTC as providing high-definition video; the fallback is to use standard definition (640x480).
</div>
<div id="connectControls">
<div id="iam">Not yet connected...</div>
<br />
<strong>Connected users:</strong>
<div id="otherClients"></div>
</div>
<div id="videos">
<div style="position:relative;float:left;" width="1282" height="722">
<video autoplay="autoplay" id="callerVideo"></video>
<video class="easyrtcMirror" autoplay="autoplay" id="selfVideo" muted="true" volume="0" ></video>
</div>
<!-- each caller video needs to be in it"s own div so it"s close button can be positioned correctly -->
</div>
</div>
</body>
</html>
Socket.io.js: http://81.171.38.245/js/socket.io.js

triggering a Get request with document.body.appendChild()

We can exchange strings between our express server and a client website (even cross domain) with this code (works perfectly) :
app.js:
var express = require("express");
var app = express();
var fs=require('fs');
var stringforfirefox = 'hi buddy!'
app.get('/getJSONPResponse', function(req, res) {
res.writeHead(200, {'Content-Type': 'application/javascript'});
res.end("__parseJSONPResponse(" + JSON.stringify( stringforfirefox) + ");");
});
app.listen(8001)
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
<script>
function __parseJSONPResponse(data) { alert(data); }
document.onkeypress = function keypressed(e){
if (e.keyCode == 112) {
var script = document.createElement('script');
script.src = 'http://localhost:8001/getJSONPResponse';
document.body.appendChild(script); // triggers a GET request ??????
}
}
</script>
<title></title>
</head>
<body>
</body>
</html>
We use document.createElement() and document.body.appendChild() to trigger a Get request as the highest voted answer here suggested.
Our question: is it fine to create a new Element with evey request, because we plan to make a lot of requests with this. Could that cause any problems. Or should we clear such an Element after we received the response?

Categories

Resources