socket.io not sending to client - javascript

I am trying to create a simple script to send data from a file every to the client every time the file is updated. I have tested and found that the file is read, but the client doesn't receive anything. there are no errors in the console. I am fairly new to socket.io.
node.js code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var fs = require("fs");
var port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/popup.html');
});
fs.watchFile("assets/popup.json", {interval:100}, function(curr, prev)
{
fs.readFile("assets/popup.json",{encoding:"utf8"}, function(err, data){
io.emit("popup", data)
})
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
client code
var socket = io();
socket.on('popup', function(msg){
alert("hello")
});

Whenever things aren't working right like this, you need to resort to "debug mode". In that mode, you need to gather all possible events that might be happening and see what you learn from that. To that end, add this code to the client:
var socket = io();
socket.on('popup', function(msg){
console.log("hello: ", msg)
});
socket.on('connection', function() {
console.log("client connected");
});
socket.on('connect_error', function(err) {
console.log("client connect_error: ", err);
});
socket.on('connect_timeout', function(err) {
console.log("client connect_timeout: ", err);
});
These messages are all documented in the client-side doc on the socket.io Github site which you can find by Googling "socket.io github" at any time.
Then, see what you see in the browser console when the page loads. If you don't know how to open the browser console in whichever browser you are using, google it to find out. You need to be looking at the debug console when the page loads.
FYI, we're assuming that you've loaded socket.io into the page via a script tag before this code. If not, that error will show in the console too.
The OP then gets this error:
client connect_error:
Error: server error at Socket.onPacket (socket.io-1.2.0.js:1)
at XHR.<anonymous> (socket.io-1.2.0.js:1)
at XHR.Emitter.emit (socket.io-1.2.0.js:1)
at XHR.Transport.onPacket (socket.io-1.2.0.js:1)
at callback (socket.io-1.2.0.js:2)
at Object.exports.decodePayload (socket.io-1.2.0.js:2)
at XHR.Polling.onData (socket.io-1.2.0.js:2)
at Request.<anonymous> (socket.io-1.2.0.js:2)
at Request.Emitter.emit (socket.io-1.2.0.js:1)
at Request.onData (socket.io-1.2.0.js:2)
OK, progress. How are you loading socket.io in the client page? This seems like it might be that you have mismatched versions of socket.io in client and server. You should be doing:
<script src="/socket.io/socket.io.js"></script>
and then your server will be feeding the client page the exact same version of socket.io. Also, since this error reports client-side socket.io 1.2.0, what version of socket.io is installed on the server?

try this
socket.on('popup', function(msg){
socket.emit('message',"popup");
});

The issue appears to be you don't actually connect to a local socket.io server. By running node server.js with the code below you can start a web server. Then navigate to localhost in your browser to see the changes in console made to popup.json.
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);
});
}
fs.watchFile("popup.json", {interval: 100}, function (curr, prev) {
fs.readFile("popup.json", {encoding: "utf8"}, function (err, data) {
io.emit("popup", JSON.parse(data));
})
});
index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost');
socket.on('popup', function (data) {
console.log(data);
});
</script>

Related

Node.js Server crashed when Refresh Browser

I tried to build a chat box server by node.js. When the browser requestes the page, it workes well at first. But when I refresh the page, the Server crashes.
Below is the error message:
events.js:183
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at _errnoException (util.js:1022:11)
at TCP.onread (net.js:615:25)
I used the node --inspect index.js, but could not find the point.
Below is the code of index.js:
const http = require('http');
const fs = require('fs');
const extract = require('./extract');
const wss = require('./websockets-server');
var handleError = function (err,res) {
res.writeHead(404);
res.end();
}
var server = http.createServer(function (req, res) {
console.log("Responding to a request.");
var filePath = extract(req.url);
console.log("filePath:"+filePath);
fs.readFile(filePath,function (err,data) {
if(err){
handleError(err,res);
return;
}else {
res.end(data);
}
})
})
server.listen(3000);
When I comment the 4th line, the import of websockets-server. Server works well when I refresh the page. Maybe it's about the websocket while it works without websocket.
Below is code of websockets-server.js:
const WebSocket = require('ws');
var WebSocketServer = WebSocket.Server;
var port = 3001;
var ws = new WebSocketServer({
port:port
});
var message = [];
console.log('websockets server started');
ws.on('connection', function (socket) {
console.log('client connection established');
message.forEach(function (msg) {
socket.send(msg);
})
socket.on('message', function (data) {
console.log('message received: ' + data);
message.push(data);
ws.clients.forEach(function (clientSocket) {
clientSocket.send(data);
});
});
});
Does the problem is about the websocket? Whether should I do process when the client shutdown the connection with the server while refreshing the page.
extract.js below:
const path = require('path');
var extractFilePath = function (url) {
var filePath;
var fileName = 'index.html';
if(url.length > 1){
fileName = url.substring(1);
}
console.log('The fileName is: ' + fileName);
filePath = path.resolve(__dirname, 'app', fileName);
return filePath;
}
module.exports = extractFilePath;
I guess that you maybe execute var ws = new WebSocket("ws://localhost:3001"); in html file. I haven't figured out exact reason about your error as I'm not proficient in WebSocket. But there is a solution:
window.onbeforeunload = function () {
ws.close();
}
close connection before reload, then the error will not reappear.
You need to add an error listener on the socket. Error listener only on the websocket instance does not help in this case.
socket.on('error', function(e){
console.log(e);
});
The ECONNRESET error means that the other side (browser) closed the connection abruptly. On browser refresh, browser simple killed the connection with the websocket server.
To solve this, you have to listen for the error event on the websocket server instance.
// listen for "error" event so that the whole app doesn't crash
wss.on("error", function(error){
console.log(error);
}
I was having the same problem, but it resolved after this command:
npm install #ionic/app-scripts#nightly --save-dev

Socket.io - Connect from client to server via https

I have created a socket.io chat application on my virtual server (Ubuntu), which runs as an systemd service and which is active running.
My server.js is located in:
/var/www/vhosts/mywebpage.de/w1.mywebpage.de/chat/
The server.js looks like this:
const io = require('socket.io')(3055);
io.on('connection', function(socket) {
// When the client emits 'addUser', this listens and executes
socket.on('addUser', function(username, room) {
...
});
// When the client emits 'sendMessage', this listens and executes
socket.on('sendMessage', function(msg) {
...
});
// Disconnect the user
socket.on('disconnectUser', function(username, room) {
...
});
});
In my website (https) I try to connect as follow:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript">
var loSocket;
$(document).ready(function() {
if(typeof(loSocket) == 'undefined') {
loSocket = io('https://w1.mywebpage.de:3055', {
reconnectionAttempts: 5,
forceNew: true
});
}
});
</script>
But I can't get a valid connection.
The developer tools say this:
(failed) ERR_CONNECTION_CLOSED with initiator polling-xhr.js:264.
What could be the error ?
From what I have done in the past I would create a https server which serves the SSL cert and create the socket server using the https server you created, this will allow you to connect via https and you will need to enable secure on socketio (use this question as a ref)
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.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Use this code as ref on how to create a socketio server using http
You can find this code on the socket.io docs
NOTE: You will need to you https not http like shown in the example

How do I properly emit data to server from client using Node.js?

When the client connects to the server a message is supposed to be emitted to the console. I'm not getting any errors so I'm confused as to what my problem actually is.
Server: As you can see the client connects.
Client: The message doesn't appear in the console.
(Forgive me for the links, I don't have 10 reputation)
How do I get the message to print to the console?
I've read other posts like this one, but they weren't helpful :(
When you do io.connect(), that call is asynchronous and not immediate. You cannot immediately emit to the server until the client generates the connect event:
var socket = io.connect()
socket.on('connect', function() {
// it is safe to call `.emit()` here
socket.emit("sndMsg", someData);
});
index.html
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('i am client', {data: 'foo!', id: data.id});
});
socket.on('time', function(data) {
addMessage(data.time);
});
socket.on('error', console.error.bind(console));
socket.on('message', console.log.bind(console));
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
</script>
</head>
<body>
<ul id='messages'></ul>
</body>
</html>
server.js
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync(__dirname + '/index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
// Send current time to all connected clients
function sendTime() {
io.emit('time', { time: new Date().toJSON() });
}
// Send current time every 10 secs
setInterval(sendTime, 10000);
// Emit welcome message on connection
io.on('connection', function(socket) {
// Use socket to communicate with this particular client only, sending it it's own id
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('i am client', console.log);
});
app.listen(3000);

Node.js socket.io webserver provide other file than index.html

I started learn socket.io and use this example of chat.
When I go to ip:8080/public/index.html, I also need access to other files, for example other JS scripts, which will be used on client side in the browser. But when I put script load like this:
<script src="/js/phaser.js" type="text/javascript"></script>
the web server does not return it, and I need it on this handler code.
I have this code:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(8080);
function handler (req, res) {
console.log(req.headers.referer);
fs.readFile(__dirname + '/public/index.html', // <--- I need here put filename which client wants it, but when I console.log to req it return HUGE data, I not found anythink usefull
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) {
socket.broadcast.emit('new message', data);
console.log(data);
});
socket.on('msg', function(data){
console.log(data);
})
});
You can use Express static for serving static files like your *.js files.

Socket.io has some trouble when handling from modules

Hi i am working with socket.io and node.js (express.js).
I saw a lot of examples, coding from the app.js file. Now i would like to organize better the code, i would like to have all my sockets.io handlers in other modules/files.
This is what i have now:
app.js
var moduleExports = require('./routes/moduleExports');
app.get('/', function(req, res){
res.sendfile(path.join(__dirname + '/index.html'));
io.on('connection', function(socket){
moduleExports.socketio(io, socket);
});
});
moduleExports.js
module.exports = {
init: function(){
//some other functions
}, socketio: function(io, socket){
socket.emit('chat', 'Wellcome!');
socket.on('chat', function (data) {
socket.broadcast.emit('chat', data);
//socket.broadcast.emit('chat', data);
});
socket.on('disconnect', function () {
socket.broadcast.emit('chat', 'Disconnected');
//socket.broadcast.emit('chat', data);
});
}
};
PROBLEM:
If I open 2 different browsers, one browser is for John and one browser is for Doe.
If John sends a message, Doe recieve it two times. If I open again a third browser, and send a message from John, Doe and the third browser are reciving three times the message.
I dont know exactly why this happen. I know something is happen with the "moduleExports.js" file. But I need a way to code my socket.io handlers outside of app.js. So i thought this would be a good pattern but it isnt.
By the way, the client code (it works):
<script src="/socket.io/socket.io.js"></script>
var socket = io();
function submit(){
socket.emit('chat', $('#m').val());
$('#m').val('');
return false;
}
The io.on('connection' you should have it just once in your code, everytime a client connects to your server that event will be thrown, if you have it multiple times I guess it runs more times. What I would do is the the following:
var moduleExports = require('./routes/moduleExports');
io.on('connection', function(socket){
moduleExports.socketio(io, socket);
});
app.get('/', function(req, res){
res.sendfile(path.join(__dirname + '/index.html'));
});

Categories

Resources