I want to make a web page for give the client the news of his friends every 1 second using socket.io + node.js.
My codes :
Client :
var socket = io.connect('http://localhost:port');
socket.on('connect', function(){
socket.emit('hello', 'Hello guest');
});
socket.on('news_by_server', function(data){
alert(data);
});
setInterval(function(){
socket.emit('news', 'I want news :D ');
}, 1000);
server:
var io = require('socket.io').listen(port);
io.sockets.on('connection', function (socket) {
socket.on('hello', function(data){
console.log('new client connected');
});
socket.on('news', function(data){
socket.emit('news_by_server', 1);
});
});
that's the mains codes, but my question is about the INTERVAL, is it good the make realtime news or there's a way better then it.
There is no need for the client to ask for news. You can force the server if you want to emit every 1 second - as long as there are clients connected, they will receive updates. If there are no clients connected, you will see in the logs that nothing happens.
On the server
setInterval(function(){
socket.emit('news_by_server', 'Cow goes moo');
}, 1000);
On the client
socket.on('news_by_server', function(data){
alert(data);
});
That's pretty much the standard way to do it. If you've not already looked the example apps page on socket.io, there's a beibertweet example that does just this using setInterval.
Also there's a slightly more advanced example on this blog.
Plus .. I found Ryan Dahls's intro on YouTube really useful for understanding the basics of node operation.
Hope that helps.
Related
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
app.use(express.static(__dirname + '/public'));
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('messages', 'Hello');
});
});
index.html
<script>
var socket = io.connect('http://localhost:7777');
socket.on('connect', function(data) {
socket.emit('join', 'Hello World from client');
});
socket.on('messages', function(data) {
alert(data);
});
</script>
I tried to implement very basic of Socket.io.
However, data sending from client to server is available but from server to client doesn't work.
In the command running server.js, 'Hello World from client' is printed. However, alert window doesn't work in the web browser.(I've also tried to console.log).
How to solve this?
Editted
I've put server.js codes in the app.get('/', function(req, res)){ ... }
Then, it doesn't work. Why it doesn't work in app.get?
Try this, I hope it works:
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('join', data); //this code sending data from server to client
});
});
If you're just trying to fetch some data with an Ajax call such as /test, then there is no need to use socket.io. That's just a classic request/response.
app.get('/test', function(req, res) {
// collect your data and then send it as a response
res.json(data);
});
If you're just trying to incorporate data into a web page that is requested, then you can use res.render() with the template engine of your choice (ejs, handlebars, pug, etc...). That would typically look like this:
app.get('/test', function(req, res) {
// collect your data and then pass it to res.render() to render your
// your template using that data
res.render('someTemplateName', data);
});
The main thing that socket.io is useful for is "pushing" data from server to client without a client request. So, if something happened on the server that the client was not aware of and the server wanted to tell the client about it, then socket.io would be used for that. The classic example is a chat app. Person A sends a chat message to the server that is addressed to Person B. The server receives that message and then needs to "push" it to Person B. That would be perfect for an already connected socket.io connection because the server can just push the data directly to the Person B client, something the server can't do with request/response (since there is no request from person B).
If you still think you need socket.io, then please describe exactly what you're trying to do with it (step by step what you're trying to send to the client).
socket.on("message",function (reply_data) {
console.log('inside on message functions ')
console.log(reply_data);
})
please change 'messages' to "message" that worked for me
Im having something like the below code.
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:8080');
socket.on('connect', function(){
socket.on('some-event', function(data) {});
});
socket.on('disconnect', function(){});
</script>
Inside the connect callback I have some code that responds to messages. This works perfectly fine on chrome. On first page load it works fine on firefox. If you reload the page then the connect event does not get called.
Im using 1.4.8 version of server and js client
I solved it using the following code. Not very clean but for the time being this helped us to progress with the project. As you can see the problem is the connect event not firing after a page reload, so I decided to attach the events after a timeout if connect was never fired.
function attachEventListners() {
socket.on('some-event', function(data) {});
}
var attached = false;
socket.on('connect', function(){
attachEventListners();
attached = true;
});
setTimeout(function() {
if (!attached) {
attachEventListners();
}
}, 1000);
You don't have to declare event listeners inside a connect listener, so even though I don't know a direct solution to your problem, I think this'll work around it:
<script>
var socket = io('http://localhost:8080');
socket.on('some-event', function(data) {});
socket.on('disconnect', function(){});
</script>
Because being able to receive messages implies that the socket is connected.
Instead of a timeout, you should use the load event listener on window
window.addEventListener("load",attachEventListners);
I've been trying to make a basic notification system that uses rooms in Socket.io. However, for some reason, it only works every other time you refresh the page.
I've simplified the code to make it easier to debug, but the issue remains. Each time I refresh the page, everything seems to work except joining a room (which only works half the time). What could be going on?
edit: I'm using Socket.io version 1.1.0 and Node.js version 0.10.31
edit2: Added FunnyLookinHat's suggestion (but it still doesn't solve the problem)
Client-Side Code:
socket = io.connect('example.com:8081'),
socket.on('connect', function () {
socket.on('startup', function(data) {
console.log(data.message);
});
socket.emit('joinRoom');
});
Server-Side Code:
var io = require('socket.io').listen(8081);
io.sockets.on('connection', function (socket) {
console.log(socket.id + ' connected!');
socket.emit('startup', { message: 'Socket started!' });
socket.on('joinRoom', function(){
console.log(socket.id + ' joining room lobby'); // prints on every other request
socket.join('lobby');
});
socket.on('disconnect', function() {
console.log(socket.id + ' disconnected!');
});
});
Client Console:
Socket started!
(refreshed page)
Socket started!
Server Console:
UIBqVuOiF1fegMIMAAAB connected!
UIBqVuOiF1fegMIMAAAB joining room lobby
UIBqVuOiF1fegMIMAAAB disconnected!
(refreshed page)
x3nMilBOjjFVjBFJAAAC connected!
(after about a minute once the client window has been closed or refreshed)
x3nMilBOjjFVjBFJAAAC disconnected!
Race condition! Try doing the following in your client code:
socket = io.connect('example.com:8081'),
socket.on('connect', function () {
socket.on('startup', function(data) {
console.log(data.message);
});
socket.emit('joinRoom');
});
I want to build a simple chat room system on top of Socket.IO where user can create a new chat room and then people can start chatting.
This sound simple but as the Socket.IO 0.9.4 I'm running now, after reading a few SO posts together with the document on socket.io, i'm getting more and more confused. So, I hope that someone can provide me with instruction that WORK with 0.9.4:
I need a way to subscribe to a room. The room name is chosen by user. When a message is posted in a room, the user should receive it. How should I write the server code, how should I write the client code?
A user can join multiple rooms simultaneously.
I want another system to send a message to all user in a certain room. This 'another system' send the message through a request handled by express. How would I write that request handler?
This is all pretty straightforward with the socket.io rooms feature. Take a look at the documentation on LearnBoost wiki.
https://github.com/LearnBoost/socket.io/wiki/Rooms
It allows for being connected to multiple rooms over a single socket. I put together a quick test with the following code.
Server
io.sockets.on('connection', function(client){
client.on('subscribe', function(room) {
console.log('joining room', room);
client.join(room);
})
client.on('unsubscribe', function(room) {
console.log('leaving room', room);
client.leave(room);
})
client.on('send', function(data) {
console.log('sending message');
io.sockets.in(data.room).emit('message', data);
});
});
Client
var socket = io.connect();
socket.on('message', function (data) {
console.log(data);
});
socket.emit('subscribe', 'roomOne');
socket.emit('subscribe', 'roomTwo');
$('#send').click(function() {
var room = $('#room').val(),
message = $('#message').val();
socket.emit('send', { room: room, message: message });
});
Sending a message from an Express route is pretty simple as well.
app.post('/send/:room/', function(req, res) {
var room = req.params.room
message = req.body;
io.sockets.in(room).emit('message', { room: room, message: message });
res.end('message sent');
});
Error: The connection to <websocket> was interrupted while the page was loading.
Source File: localhost/socket.io/node_modules/socket.io-client/dist/socket.io.js
Line: 2371
I am new to socket.io and I have tried to search for this, but I didn't get an answer.
Websocket is interrupted when I refresh page on Firefox. That's why server side is waiting to authorise client.
Here is code:
server.js
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs')
app.listen(8080);
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.sockets.on('connection', function (socket) {
socket.emit('news', {
hello: 'world'
});
socket.on('my other event', function (data) {
//alert(JSON.stringify(data));
console.log(data);
});
});
index.html
<script src="node_modules/socket.io-client/dist/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('news', function (data) {
alert(JSON.stringify(data));
console.log(data);
socket.emit('my next event', { my: 'data' });
});
</script>
It happens because, you are not closing your open websocket.
This code would remove this error:
$(window).on('beforeunload', function(){
socket.close();
});
This seems to be an open bug in Firefox (as of 2015-03-29):
https://bugzilla.mozilla.org/show_bug.cgi?id=712329
The workaround (for now) is to call close() on the websocket on beforeunload, as Alexander pointed out.
Update 2016-04: According to Bugzilla, this will be fixed in Firefox 48
I was just running through the Socket.IO tutorials and I ran into this exact problem. I tried the posted solutions but they didn't seem to work at all.
After some fiddling and some screaming and some rubber-ducking, I finally figured out what the issue was. The issue is that it's trying to connect to the socket before the socket variables have been properly initialized. Javascript boo boo #1.
If you will ammend your file to include jQuery and then wrap your functions like so:
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script>
$(function(){
var socket = io.connect('http://localhost:8080');
socket.on('news', function (data) {
alert(JSON.stringify(data));
console.log(data);
socket.emit('my next event', { my: 'data' });
});
});
</script>
You will have much more success.
What impact does this have on your application? My guess is that it's just not great to see an error in the console.
The problem here is that you are seeing Firefox loggin this error and there's nothing you can do about it. It's not possible to capture this error with a try...catch block or via websocket.onerror/websocket.onclose.
See: How do I catch a WebSocket connection interruption?
Related:
Should WebSocket.onclose be triggered by user navigation or refresh?
Firefox - Race condition allows ghost WebSocket connections to live after tab closed
I've had this problem with our custom Undertow-based webserver for years -- my problem was that my server was not responding to the socket close message.
Based on a comment by Jan Wielemaker I checked my socket close handler code for AbstractReceiveListener.onFullCloseMessage and realized I had not called the super method. After adding super.close() the socket closes cleanly on the client and no error is emitted.
One solution is to put a timeout on the disconnect event.
setTimeout(() => {
$('#offlineModal').modal('show')
}, 5000)