My purpose is to make a chat application using Node.js + Socket.IO, but I met with a difficulty.
The issue is that the minus event doesn't work correctly(Result: 64 - 12 = 65), but the plus event works fine(Result: 42 + 23 = 65).
Maybe the cause of the issue is related to socket.once() function... but I don't know the answer clearly.
The following is the source code of my simplified Node.js app.
app.js:
var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');
var app = http.createServer(function (req, res) {
if (req.url === '/') {
fs.readFile(__dirname + '/index.html', function (err, result) {
if (err)
throw err;
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(result);
});
} else {
res.writeHead(404);
res.end();
}
});
app.listen(3000, function () {
console.log('The server running on port 3000.');
});
var io = socketio(app);
io.on('connection', function (socket) {
socket.on('plus', function (param) {
socket.emit('result', param.a + param.b);
});
socket.on('minus', function (param) {
socket.emit('result', param.a - param.b);
});
});
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title></title>
<script src="http://cdn.socket.io/socket.io-1.0.6.js"></script>
<script>
var socket = io();
socket.emit('plus', {
a: 42,
b: 23
});
socket.once('result', function (result) {
var div = document.createElement('div');
div.innerText = '42 + 23 = ' + result;
document.body.appendChild(div);
});
socket.emit('minus', {
a: 64,
b: 12
});
socket.once('result', function (result) {
var div = document.createElement('div');
div.innerText = '64 - 12 = ' + result;
document.body.appendChild(div);
});
</script>
</head>
<body>
</body>
</html>
Result:
42 + 23 = 65
64 - 12 = 65
Thanks.
because you bind two event callback on 'result' same time.
<script>
var socket = io();
socket.emit('plus', {
a: 42,
b: 23
});
socket.once('result', function (result,obj) {
var div = document.createElement('div');
div.innerText = '42 + 23 = ' + result;
document.body.appendChild(div);
socket.emit('minus', {
a: 64,
b: 12
});
socket.once('result', function (result,obj) {
var div = document.createElement('div');
div.innerText = '64 - 12 = ' + result;
document.body.appendChild(div);
});
});
</script>
You can't overload the "once" result like that - they're both being bound right away rather than synchronously. The correct way to do it would be to use two separate events for the different types of results.
Here's a modified app.js
var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');
var app = http.createServer(function (req, res) {
if (req.url === '/') {
fs.readFile(__dirname + '/index.html', function (err, result) {
if (err)
throw err;
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(result);
});
} else {
res.writeHead(404);
res.end();
}
});
app.listen(3000, function () {
console.log('The server running on port 3000.');
});
var io = socketio(app);
io.on('connection', function (socket) {
socket.on('plus', function (param) {
socket.emit('plus result', param.a + param.b);
});
socket.on('minus', function (param) {
socket.emit('minus result', param.a - param.b);
});
});
And the corresponding index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title></title>
<script src="http://cdn.socket.io/socket.io-1.0.6.js"></script>
<script>
var socket = io();
socket.on('plus result', function (result) {
var div = document.createElement('div');
div.innerText = '42 + 23 = ' + result;
document.body.appendChild(div);
});
socket.once('minus result', function (result) {
var div = document.createElement('div');
div.innerText = '64 - 12 = ' + result;
document.body.appendChild(div);
});
socket.emit('plus', {
a: 42,
b: 23
});
socket.emit('minus', {
a: 64,
b: 12
});
</script>
</head>
<body>
</body>
</html>