I'm following the Socket.IO tutorial, but I am running into an issue where the number of messages that display on the page increase exponentially, making the chat client ineffective.
Some cursory searching is telling me that it involves event handlers, but I haven't found anything definitive on how to use them in this context. What and where do I need to use these event handlers, and why?
My index.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
// console.log('a user connected');
// socket.on('disconnect', function(){
// console.log('user disconnected');
// });
socket.on('chat message', function(msg){
//console.log('message: ' + msg);
io.emit('chat message', msg);
});
});
http.listen(8080, function(){
console.log('listening on *:8080');
});
And my HTML:
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
function doDid(){
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
};
</script>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button onclick="doDid()">Send</button>
</form>
</body>
</html>
The problem is that you subscribe to the "chat message" event each time you press your button.
You should only run this code once:
var socket = io();
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
So you should change your code like this:
<script>
var socket = io();
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
function doDid(){
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
};
</script>
var socket = io();
This line creates a connection to socket.io. Each time you call it you are creating another connection. Try only calling that once instead of on each send.
To clarify, the io() function is a factory not an accessor.
Edit:
Looks like the socket.io client actually does cache sockets it creates and doesn't create multiple connections.
However, I also noticed you are binding events in that function, but are calling it each click, so you are rebinding each time. Call your function only once at startup.
Related
Here is the full code :-
index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chatIN', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chatOUT', function(msg){
$('#messages').append('<li><span>'+msg+'</span></li>');
});
});
</script>
</body>
</html>
And here is my index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket){
socket.on('chatIN', function(msg){
console.log('message:'+ msg);
socket.emit('chatOUT:'+ msg);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
I am facing a problem while trying out a socket.io beginner's tutorial, I followed this tutorial
https://socket.io/get-started/chat/
Everything seems to be okay till the very last thing, when they build a chat app, and when you hit submit in textbox, it updates the contents of the element.
I can see the messages getting printed in the node js console, but nothing in chrome's console. I also tried debugging it using developer options, but the control just never goes in this method in the index.html.
socket.on('chat message', function(msg){
Can someone please help ? I am really new to socket.io and nodejs.
Thanks
You are sending the wrong message from the server.
On the server, change this:
socket.emit('chatOUT:'+ msg);
to this:
socket.emit('chatOUT', msg);
Your client code is listening for the chatOUT message so that's the exact message name need to send. Here's the matching client code:
socket.on('chatOUT', function(msg){...}
Below is my server side code where I want to display if user is connected or disconnected.But the user is connected and user is disconnected message is appearing twice. Can somebody help me why is it appearing twice?
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
io.on('connect', function(socket) {
socket.broadcast.emit('chat message', 'a user connected!');
socket.on('disconnect', function() {
socket.broadcast.emit('chat message', 'user disconnected');
});
socket.on('chat message', function(msg) {
socket.broadcast.emit('chat message', msg);
});
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
Client Code
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
<script>
var typing = false;
var timeout = undefined;
function timeoutFunction(){
typing = false;
socket.emit(noLongerTypingMessage);
}
function onKeyDownNotEnter(){
if(typing == false) {
typing = true
socket.emit(typingMessage);
timeout = setTimeout(timeoutFunction, 3000);
} else {
clearTimeout(timeout);
timeout = setTimeout(timeoutFunction, 3000);
}
}
</script>
</body>
</html>
You have two copies of this in your client file:
script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
Remove one of them.
Correct your order
io.on('connect', function(socket) {
socket.broadcast.emit('chat message', 'a user connected!');
socket.on('chat message', function(msg) {
socket.broadcast.emit('chat message', msg);
});
socket.on('disconnect', function() {
socket.broadcast.emit('chat message', 'user disconnected');
});
});
For a few days I've been trying to get the socket.io chat example to work from here. First I tried it by typing everything myself. But it didnt work. After that I tried it with the files from github.
the part
After I got the files from github I tried it did not work I have run
npm install
and it downloaded the dependencies into the node_modules folder, I also ran
npm install --save express#4.10.2
npm install --save socket.io
I got no errors on any of the commands.
I start the program with
node index.js
Which gives me the following message:
listening on *:30000
If I go to localhost:3000, I get the chat application as in the example. But no messages show up when posting the form.
However, when I use the following code to check connection:
io.on('connection', function(socket){
console.log('user connected');
});
it works, so the problem is in emitting data.
Also, the following code works:
server index.js
io.on('connection', function(socket){
var tweet = {user: "nodesource", text: "Hello, world!"};
// to make things interesting, have it send every second
var interval = setInterval(function () {
socket.emit("tweet", tweet);
console.log("tweeting");
}, 1000);
socket.on("disconnect", function () {
clearInterval(interval);
});
});
Client
socket.on("tweet", function(tweet) {
// todo: add the tweet as a DOM node
console.log("tweet from", tweet.username);
console.log("contents:", tweet.text);
});
So emitting and receiving from the server to the client works.
What I've tried
Run in different browsers
Run on different PC's
Copy from github
Type everything myself
Check the console in Chrome for errors (no errors found)
Change ports
Different paths (used c:\chat , d:\chat, c:\personalfiles\chat )
Disable firewall
What works
When following the tutorial, the part where a user connects and gets logged on the console work.
I get the chat page
Console says its listening
No errors
Any tips on how to solve this, or how to find what's wrong?
My index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
$('form').submit(function(){
console.log('Send message');
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
</body>
</html>
My index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
try this (for version <= 0.8):
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
});
for version 1.0.x it would be something like:
var io = require('socket.io').listen(http, {
"transports": ['websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling',
'polling'],
"polling duration": 10
});
Yours:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
Are you sure it's not supposed to be this instead?
io.sockets.on('connection', function (socket) {
socket.on('chat message', function(msg){
io.sockets.emit('chat message', msg);
});
});
server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var clients = [];
var sequence = 1;
io.on('connection', function(socket){
console.log('Client connected (id=' + socket.id + ').');
clients.push(socket);
socket.on('login', function(msg){
console.log(msg);
io.emit('login', msg);
});
socket.on('disconnect', function(){
var index = clients.indexOf(socket);
if (index != -1) {
clients.splice(index, 1);
console.info('Client gone (id=' + socket.id + ').');
}
});
});
http.listen(3011, function(){
console.log('listening on *:3011');
});
client:
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io('http://localhost:3011');
$('form').submit(function(){
socket.emit('login', $('#m').val());
$('#m').val('');
return false;
});
socket.on('login', function(msg){
//alert(msg);
$('#messages').append($('<li>').text(msg));
});
socket.on('connect', function() {
console.log('connected');
});
socket.on('message', function(msg){
console.log(msg);
});
socket.on('disconnect', function() {
console.log('disconnected');
});
socket.on('error', function (e) {
console.log('System', e ? e : 'A unknown error occurred');
});
</script>
</body>
</html>
This work perfect on localhost.
server log:
listening on *:3011
Client connected (id=Kk-LUoJep5Uw0qWLAAAA).
message
Client gone (id=Kk-LUoJep5Uw0qWLAAAA).
But if i work with ec2 server. NodeJS and socket.io can't send message.
log ec2 server:
listening on *:3011
Client connected (id=1Phd18CNKLEnRH3LAAAA).
Client gone (id=1Phd18CNKLEnRH3LAAAA).
Port 3011 open.
he is get connect and disconnect event, but cant get or send message.
How to fix it? Thx.
I have two files, one named index.js and the other index.html.
When I press the send button the message doesn't appear
The code of the file index.js is the following:
app = require('express.io') ();
app.http().io();
app.get('/', function(req, res){
res.sendfile('index.html');
});
app.io.on('connection', function(socket){
socket.on('chat message',function(msg) {
app.io.emit('chat message' ,msg)
});
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
app.listen(3000);
The code of the file index.html is the following:
<!doctype html>
<html>
<head>
<title>Example of chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
</body>
</html>
write this instead
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000);
app.get('/', function (req, res) {
res.sendfile('index.html');
});
io.on('connection', function (socket) {
socket.on('chat message', function (data) {
socket.broadcast.emit('chat message',data);
});
});