I am working on a node.js app where I am using socket.io to send data to multiple clients but the socket is only able to send data to one client i.e if I open my webpage in two tabs its not working in both the tabs but when I open just 1 tab of webpage it is able to transmit the data.I dont know why? Can someone help,Here's my code:
server.js
var http = require("http"),
io = require("socket.io"),
fs = require("fs"),
util = require("util");
var backlog_size = 2000;
var filename = process.argv[2];
if (!filename) return util.puts("Usage: node <server.js> <filename>");
var linesCount = 0;
// -- Node.js HTTP Server ----------------------------------------------------------
server = http.createServer(function (req, res) {
console.log(req.url)
filePath = req.url
if(filePath=="/"){
filePath='./index.html'
fs.readFile(filePath, function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading ' + filePath);
}
res.writeHead(200);
res.end(data);
});
}
else
{
if(filePath=="/client"){
filePath = './client.html';
fs.readFile(filePath, function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading ' + filePath);
}
res.writeHead(200);
res.end(data);
});
}}
});
server.listen(8000, "0.0.0.0");
var fsTimeout
var textToSend=""
// -- Setup Socket.IO ---------------------------------------------------------
var socket = io(server, {
cors: {
origin: "*",
},
});
socket.on("connection", function (client) {
fs.watchFile(filename, function (curr, prev) {
console.log("file changed");
if (prev.size > curr.size) return { clear: true };
if(!fsTimeout){
if(prev.ctime.getTime() != curr.ctime.getTime())
{
console.log("file changed")
var stream = fs.createReadStream(filename, {
start: prev.size,
end: curr.size,
});
stream.on("data", function (lines) {
console.log(lines.toString());
textToSend+=lines.toString();
textlen=textToSend.split("\n").length;
// count=lines.toString().split("\n").length
// linesCount += count;
// console.log(linesCount);
console.log(textlen)
if(textlen<10)
{
console.log("me")
client.emit("tail", { lines: lines.toString("utf-8").split("\n") });}
else
{
console.log("client")
client.emit("room", { lines: textToSend.toString("utf-8").split("\n") }); };
});
}
fsTimeout = setTimeout(function() { fsTimeout=null }, 5000)}
}
);
});
In the above code I have added 2 clients,1 page is index.html and other is client.html and both are opening in the browser and getting connected to the socket but the data is not transmitting to any of them.Here's are my client codes:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Websockets tail Server</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="info" class="trebuchet"></div>
<div id="tail" class="monospace selection"></div>
<script type="text/javascript">
(function() {
var lines = 0, notice = $("#info"), buffer = $('#tail');
var socket = io.connect('http://127.0.0.1:8000/');
socket.on('connect', function() {
console.log('Connected to stream');
});
socket.on('room', function(msg) {
console.log("Message:");
console.dir(msg);
buffer.append(msg.lines.join('<br/>'));
buffer.scrollTop(lines*100);
lines = lines + msg.lines.length;
});
})();
</script>
</body>
</html>
client.html
<!DOCTYPE html>
<html>
<head>
<title>Websockets tail Server</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="info" class="trebuchet"></div>
<div id="tail" class="monospace selection"></div>
<script type="text/javascript">
(function() {
var lines = 0, notice = $("#info"), buffer = $('#tail');
var socket = io.connect('http://127.0.0.1:8000/');
socket.on('connect', function() {
console.log('Connected to stream');
});
socket.on('tail', function(msg) {
console.log("Message:");
console.dir(msg);
buffer.append(msg.lines.join('<br/>'));
buffer.scrollTop(lines*100);
lines = lines + msg.lines.length;
});
})();
</script>
</body>
</html>
Both the html files above are my clients and I want them to listen to my socket server but they are not but when I remove one of the clients,it works.
Any help will be appreciated
Related
I have web socket server and http server, and I want to tell socketio server to emit a msg to the client only if an event was emitted using EventEmitter Class, the problem is when I open 2 tabs in browser I noticed that the event was send to all users (broadcasting)
here is the both servers:
const server = require('http').createServer(handler)
, io = require('socket.io')(server)
, url = require('url')
, fs = require('fs')
, EventEmitter = require('events')
, emitter = new EventEmitter();
server.listen(3000);
function handler(req, res) {
var route = url.parse(req.url).pathname;
if (route === '/') {
var stream = fs.createReadStream(__dirname + '/index.html');
stream.pipe(res);
} else if (route === '/testSocket') {
var stream = fs.createReadStream(__dirname + '/test.html');
stream.pipe(res);
// emit event after 5s, the handler is inside socketio server
setTimeout( function() {
emitter.emit('fromEmitterToSocketServer', 'Msg');
}, 5000);
} else {
res.writeHead(404, {"Content-Type": "text/plain"});
res.end('404');
}
}
io.on('connection', function (socket) {
// handle event and then send data to the user
emitter.on('fromEmitterToSocketServer', function(data) {
// here I noticed that socketio emit the event to all users
socket.emit('fromSocketServerToClient', data);
});
});
Index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
<h1>Index</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script>
var socket = io('//localhost:3000');
socket.on('fromSocketServerToClient', function (data) {
console.log(data);
});
</script>
</body>
</html>
test.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test socketIO</title>
</head>
<body>
<h1>Test socketIO</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script>
var socket = io('//localhost:3000');
socket.on('fromSocketServerToClient', function (data) {
console.log(data);
});
</script>
</body>
</html>
If I open two tabs and go to http://localhost:3000 and http://localhost:3000/testSocket I figure out that the msg is logged into the both of them
Thanks
This is my html file:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="Content-Script-Type" content="text/javascript"/>
</head>
<body>
<label for=payload>Payload</label><br>
<textarea id="editor" cols=100 rows=30></textarea><br>
</body>
And the phantomjs script is:
var bodyParser = require('body-parser'),
phantom = require('phantom');
var bk = {"abc":"def"};
//Create Phantom session
var _phSession;
var _page;
var log = console.log;
var config = { logger: { warn:log, info:log, error:log } };
phantom.create([], config).then(function(_session) {
if (_session) {
console.log('Phantom session created');
_phSession = _session;
return _phSession.createPage();
}
})
.then(function(page) {
_page = page;
_page.property('onConsoleMessage', function(msg) {
console.log(msg);
});
_page.property('onLoadStarted', function() {
console.log("load started");
});
_page.property('onLoadFinished', function() {
console.log("load finished");
});
return _page.open("http://myserver/my.html");
})
.then(function(status) {
console.log('Open status:' + status);
if (status != 'success') return;
_page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js')
.then(function() {
//set the new bkstore
_page.evaluate(function(bk) {
jQuery('#editor').val(JSON.stringify(bk));
return jQuery('#editor').val();
}, bkstore)
.then(function(res) {
console.log('Return from set:' + res);
})
});
setTimeout(function() {
_page.evaluate(function() {
console.log('============== EVALUATE AFTER LOADED ===================');
//return jQuery('#editor').val();
return jQuery('body').html();
})
.then(function(res) {
console.log('html:' + res);
});
}, 1000);
After I set the #editor content with bk, I get back the value I set.
In the block of setTimeout, if I try to get the content of #editor again, I still get back the value of bk.
But I get the html of the body tag, I don't see the value of bk in the #editor.
Anyone knows what the problem is?
I have read a lot of tutorial, and sample code to send data from a node.js class to an html page and show this data.
such as link1, link2,link3,link4,link5
and some others.
I am getting some data from UDP listener and need to send it after some processing to an html page to show it. here is my code:
The udp receiver:
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1'
var http = require('http'),
dgram = require('dgram'),
socketio = require('socket.io'),
fs = require('fs');
var html = fs.readFileSync(__dirname + '/html/showMap.html');
var app = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-type': 'text/html'
});
res.end(html);
io.sockets.emit('welcome', { message: 'Welcome!'});
}).listen( server_port, server_ip_address, function() {
console.log('Listening');
});
var io = socketio.listen(app),
socket = dgram.createSocket('udp4');
socket.on('message', function(content, rinfo) {
console.log('got message', content, 'from', rinfo.address, rinfo.port);
io.sockets.emit('udp message', 'content' /*content.toString()*/);
});
socket.bind(5001);
and my html page which is called 'showMap.html'
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Get Data</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="results"> This text will change </div>
<div id="date">sample another temp text</div>
<script>
// client code here
var socket = io.connect('localhost', {port: 8080});
socket.on('udp message', function(message) {
console.log(message)
document.getElementById("date").innerHTML = "My new text!";
});
socket.on('welcome', function(data) {
document.getElementById("results").innerHTML = data.message;
});
</script>
</body>
</html>
but by sending packet, html page has not changed.
Here is my console log of running code:
Atis-MacBook-Pro:startWithNode muser$ npm start
StartWithNodejs#1.0.0 start /Volumes/Project/Project/NodeJS/startWithNode
node index.js
Listening got message from 127.0.0.1 64047
What is wrong in my code?
I tested this locally. In your HTML file I made two changes and it worked.
1 - Replace io.connect('localhost', {port: 8080}); with io.connect('localhost:8080');
2 - There was a strange \u200b character at the end of the document.getElementById("date").innerHTML = "My new text!"; line. I deleted that and ended up with:
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Get Data</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="results"> This text will change </div>
<div id="date">sample another temp text</div>
<script>
// client code here
var socket = io.connect('localhost:8080');
socket.on('udp message', function(message) {
console.log(message)
document.getElementById("date").innerHTML = "My new text!";
});
socket.on('welcome', function(data) {
document.getElementById("results").innerHTML = data.message;
});
</script>
</body>
</html>
Which replaces the content of results.
in this example you will be able to get JSON data from php file and send it to all connected clients.
RunThisFileThroughNodeJs.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
var request = require("request")
var url = "http://localhost/api/index.php";
events = require('events'),
serverEmitter = new events.EventEmitter();
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
setInterval(
function(){
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
io.emit('chat message', body);
}
});
},5000);
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
Don't Forget to install express , request for nodejs
Now make this file i will call it index.html so the response of my file will be here.
index.html
<!doctype html>
<html>
<head>
<title>Prices API</title>
<script src="http://localhost/js/socket.io.js"></script>
</head>
<body>
<div id="price_list"></div>
<script>
var socket = io();
socket.on('chat message', function(msg){
document.getElementById("price_list").innerHTML = JSON.stringify(msg);
console.log(msg);
});
</script>
</body>
</html>
I have 3 iframes with reaveal.js presentations. And while they are not on node.js server they.re working perfectly. But I need socket.io to auto-refresh selected iframe when conents of file with reveal.js presentation is changed (I'm uploading a file using php manipulate it and making new .html file with presentation then I'm overwriting the old file).
Node.js server with chokidar is watching for change of file. And it's working.
But everything if failing when I'm joining socket.io and reveal.js together.
Site is constntly refreshing (don't know why i exluded emits) and because of that browser is crashing.
Server code:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
var chokidar = require('chokidar');
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.emit('news', { hello: 'world' });
// socket.on('my other event', function (data) {
// console.log(data);
// });
// });
var watcher = chokidar.watch('file, dir, or glob', {
ignored: /[\/\\]\./, persistent: true
});
watcher.add('prez/prez1.html');
watcher.add('prez/prez2.html');
watcher.add('prez/prez3.html');
var log = console.log.bind(console);
watcher
.on('change', function(path) { log('File', path, 'changed');
//io.emit('restart1');
})
Client code:
<html>
<head>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost');
// socket.on('news', function (data) {
// console.log(data);
// socket.emit('my other event', { my: 'data' });
// });
// socket.on('restart1', function (data) {
// var iframe = document.getElementById('ramka1');
// iframe.src = iframe.src;
// });
// socket.on('restart2', function (data) {
// var iframe = document.getElementById('ramka2');
// iframe.src = iframe.src;
// });
// socket.on('restart3', function (data) {
// var iframe = document.getElementById('ramka3');
// iframe.src = iframe.src;
// });
</script>
<iframe id="ramka1" width="100%" height="33%" src="prez/prez1.html"></iframe><br>
<iframe id="ramka2" width="100%" height="33%" src="prez/prez2.html"></iframe><br>
<iframe id="ramka3" width="100%" height="33%" src="prez/prez3.html"></iframe><br>
<style type="text/css">
iframe {
border:none;
}
</style>
</body>
</html>
Example presentation code:
<html>
<head>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/white.css">
</head>
<body>
<div class="reveal">
<div class="slides">
<section>Slide 1</section>
<section>Slide 2</section>
</div>
</div>
<script src="js/reveal.js"></script>
<script>
Reveal.initialize({controls: false, loop: true, autoSlide: 1000});
</script>
</body>
</html>
I am trying to write a Node.js project from a tutorial, but the server.js file does not seem to be working properly:
var http = require('http');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {};
function send404(response) {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: not found');
response.end();
}
function sendFile(response, filePath, fileContents) {
response.writeHead(
200,
{"content-type": mime.lookup(path.basename(filePath))}
);
response.end(fileContents);
}
function serveStatic(response, cache, absPath) {
if (cache[absPath]) {
sendFile(response, absPath, cache[absPath]);
} else {
fs.exists(absPath, function(exists) {
if (exists) {
fs.readFile(absPath, function(err, data) {
if (err) {
send404(response);
} else {
cache[absPath] = data;
sendFile(response, absPath, data);
}
});
} else {
send404(response);
}
});
}
}
var server = http.createServer(function(request, response) {
var filePath = false;
if(request.url == '/') {
filePath = 'public/index.html';
} else {
filePath = '/public/' + request.url;
}
var absPath = './' + filePath;
serveStatic(response, cache, absPath);
});
server.listen(26353, function() {
console.log("Listening...");
});
When I go to my URL the index.html content is displayed, but none of the stylesheets or attached files from the index.html are displayed, I get:
GET http://myURL.com/stylesheet/style.css 404 (NOT FOUND)
Here is my index.html:
<html>
<head>
<title>Chat</title>
<link rel='stylesheet' href='/stylesheet/style.css'></link>
</head>
<body>
<div id='content'>
<div id='room'></div>
<div id='room-list'></div>
<div id='messages'></div>
<form id='send-form'>
<input id='send-message' />
<input id='send-button' type='submit' value='Send' />
<div id='help'>
Chat commands:
<ul>
<li>.....</li>
</ul>
</div>
</form>
</div>
<script src='/socket.io/socket.io.js' type='text/javascript'></script>
<script src='http://code.jquery.com/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='/javascript/chat.js' type='text/javascript'></script>
<script src='/javascript/chat_ui.js' type='text/javascript'></script>
</body>
</html>
I'm not sure what is wrong.
My project directory has the server.js, the node-modules and the public folder, the public folder has a stylesheet directory and javascript folder where the files are.
My web host has is set up so that http://myURL.com/node/ is where port 26353 is bound to (don't know if that's the right word). So if I go to http://myURL.com/node I see the index.html file but none of the stylesheets or javascript works.
Sending file is not so trivial in node.js. There is a code from my framework
core.sendFile = function(filename, context)
{
if (fs.exists(filename, function (exists)
{
if (exists) fs.stat(filename, function (err, stats)
{
if (err) core.catch_err(err);
else if (stats && !stats.isDirectory())
{
var filestream = new fs.ReadStream(filename);
var mimme = mime.lookup(filename);
context.response.writeHead(200, {'Content-Type': mimme });
filestream.pipe(context.response);
filestream.on("error", function (err) { context.response.statusCode = "500"; context.response.end("Server error"); core.log("Server error while sending " + filename, "err"); });
context.response.on("close", function () { filestream.destroy(); });
core.logger.log("Sending file " + filename);
}
});
else core.not_found(context);
}));
}
The idea is to read and write file as a stream, and to process some errors and closing of streams. "Core" is just a library object.
remove the first / from your url, so it should be stylesheet/style.css instead of /stylesheet/style.css