i prepared a simple chat system while practicing node.js. but theres a problem while sending messages. quite a good amount of delay taking place while sending messages and i couldnt figure out why. can anyone help me how to improve attached code ?
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(client) {
client.on('messageSend', function(data) {
client.broadcast.emit('messageRecieve', data);
});
});
http.listen(9090, function() {
console.log('Listening on port 9090');
io.on('connect', function(socket) {
console.log("Connection established : " + socket.client.conn.remoteAddress);
})
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket Test</title>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
function messageSend() {
var message = document.getElementById("messageInput").value;
console.log(message);
var ul = document.getElementById("messageNode");
var li = document.createElement("li");
li.appendChild(document.createTextNode(message));
li.setAttribute("style", "font-style : italic; color : red;");
ul.appendChild(li);
socket.emit('messageSend', message);
}
socket.on('messageRecieve', function(data) {
var message = data;
var ul = document.getElementById("messageNode");
var li = document.createElement("li");
li.appendChild(document.createTextNode(message));
ul.appendChild(li);
console.log(message);
});
</script>
</head>
<body>
<input id="messageInput" type="text"> <button onclick="messageSend()">Send</button><br>
<ul id="messageNode">
</ul>
</body>
</html>
the official socket.io example sends the message to everyone, including yourself
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
You sent to everyone except yourself (which is the most accurate method)
io.on('connection', function(client) {
client.on('messageSend', function(data) {
client.broadcast.emit('messageRecieve', data);
});
});
The reason for your slowdown is probably becouse your browser puts your out-of-focus tabs in a sort of sleep mode, which makes it update much less frequently... If you compare your code vs socket.io's code between computer and phone via lan. I would guess the speed for your server-sent message would be the same
Right now you are basically competing versus socket.io's "optimistic updates". It pushes the message to your client directly without waiting for the server, which your own code does. As well as browser out-of-focus low priority mode
Related
Edit: Answered below
New to Node.js here, I really want to know why this script hangs forever when I'm attempting to connect to the created server.
I've had this happen often enough when I'm trying to create a server and I'm not sure why, as it seems to happen with very similar code:
Node script:
var http = require("http");
var file = require("fs");
var server = http.createServer(function(request, response)
{
file.readFile("chat.html", "UTF-8", function(error, content)
{
if(error) { console.error(error.stack); response.end(); }
response.writeHead(200, {"content-type" : "text/html"});
response.end(content);
});
}).listen(1994, function(){console.log("Listening");});
var websocket = require("socket.io").listen(server);
websocket.sockets.on("connection", function(socket)
{
socket.emit("message", {"message" : "Hello World"});
});
HTML:
<!DOCTYPE HTML>
<html>
<head>
<title>Chat</title>
<meta charset="utf-8">
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = websocket.connect();
socket.on("message", function(message)
{
console.log(message);
});
</script>
</head>
<body>
<div>Socket file.</div>
</body>
</html>
If there is an error then it should end the response and if there isn't it should end the response, or does it have something to do with the web socket?
Try changing how you are invoking socket.io:
var websocket = require('socket.io')(server);
websocket.on('connection', doStuff);
This example follows directly from the docs on GitHub.
The problem was with websocket.connect(). Socket.io uses io as a global object in the front end, not websocket. So it should have been io.connect().
Please I have this small demo of a collaborative editor in a pub/sub fashion.
Scenario:
Server :S
Clients : A, B
A sends text S.
S receives text and brodcast to B.
B sends text to S.
S receives text and brodcast to A, A receive text, but document.getElementById is not updting the display.
I suspect the problem is with javascript execution order...
I am bit confused, can someone points me what goes wrong with my client ?
Server:
var app = require('express')();
var http = require('http').createServer(app)
var io = require('socket.io').listen(http);
//Server accepting connect on this port
http.listen(3000);
//Establishing connection to client and disconnecting
io.sockets.on('connection', function(socket){
console.log('Connected to a new client');
socket.on('room', function(room) {
socket.join(room);
console.log('join room '+ room);
});
socket.on('disconnect', function(){
socket.disconnect();
console.log('Disconnected from a client');
});
var room= 'room1';
//Data exchange between client and server
//Server receives new data from a client and broadcast it to others
socket.on('client_character',function(msg){
//receive data
console.log('Data from client'+msg.buffer);
socket.in(room).broadcast.emit('server_character',msg.buffer);
//socket.broadcast.to(room).emit('server_character', msg.buffer);
//socket.to(room).emit('server_character',msg.buffer);
});
});
Client:
Run separately on Apache server
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Client</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<link rel="stylesheet" type="text/css" href="styles/style.css">
</head>
<body>
<textarea id="notepad"></textarea><br/>
<script>
$(function () {
var socket = io.connect('http://localhost:3000',
{'sync disconnect on unload':false});
var room = "room1";
socket.on('connect', function() {
socket.emit('room', room);
});
//receive character from server
socket.on('server_character',function(content){
console.log('From Server:'+ content);
document.getElementById('notepad').innerHTML=content;
});
//For each typed character
$('#notepad').on('keypress',function(){
var character= $('#notepad').val();
//send character to servers
socket.emit('client_character',{buffer:character});
console.log('To Server:'+ {buffer:character} );
});
});
</script>
</body>
</html>
style.css:
#notepad{
height:500px;
width:500px;
font-size: 14px;
color: brown;
}
package.json:
{
"name": "collaborative",
"version": "0.0.1",
"description": "none",
"dependencies": {
"express": "^4.10.2",
"socket.io": "^1.4.5"
}
}
Reference Demo:
[https://www.youtube.com/watch?v=I0iikz1F1Lk][1]
I did some thanges in tour code for fix one bug in input and add more logs and this is working here with FF and Chrome ( i dont have IE here )
Server:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io').listen(http);
//Server accepting connect on this port
http.listen(3000);
//Establishing connection to client and disconnecting
io.sockets.on('connection', function(socket){
console.log('Connected to a new client');
socket.on('error', function(err) {
//here i change options
console.log('Error!', err);
});
socket.on('room', function(room) {
socket.join(room);
console.log('join room: '+ room);
});
socket.on('disconnect', function(){
// socket.disconnect();
console.log('Disconnected from a client');
});
var room= 'room1';
//Data exchange between client and server
//Server receives new data from a client and broadcast it to others
socket.on('client_character',function(msg){
//receive data
console.log('Data from client: '+msg.buffer);
socket.in(room).broadcast.emit('server_character',msg.buffer);
//socket.broadcast.to(room).emit('server_character', msg.buffer);
//socket.to(room).emit('server_character',msg.buffer);
});
});
Client:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Client</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<link rel="stylesheet" type="text/css" href="styles/style.css">
</head>
<body>
<textarea id="notepad"></textarea><br/>
<script>
$(function () {
var socket = io.connect('http://localhost:3000',
{'sync disconnect on unload':false});
var room = "room1";
socket.on('connect', function() {
socket.emit('room', room);
});
//receive character from server
socket.on('server_character',function(content){
console.log('From Server:'+ content);
document.getElementById('notepad').innerHTML=content;
});
//For each typed character
$('#notepad').on('keyup',function(){
var character= $('#notepad').val();
//send character to servers
socket.emit('client_character', {buffer:character});
console.log('To Server:', { buffer:character } );
});
});
</script>
</body>
</html>
This question has already been answered, but I can't understand it at all. You can find it at this link.
socket.on calls its callback too many times
I have the same problem as this fellow. I'm attempting to make a chat program with socket.io, but when more than one user joins, each message outputs the number of times of how many users have been connected.
For example, when one user is connected, and he submits a message. It outputs once. When two users are connected, each of their messages output twice.
When three users are connected, each of their messages output three times.
Here is my client side code:
$('document').ready(function() {
var server = io.connect('http://localhost:8888');
$('.chat').keydown(function(event){
var save = this;
if(event.which == 13){
server.emit('message', $(save).val());
$(save).val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
Here is my server side code:
var socket_io = require('socket.io').listen(8888).sockets;
socket_io.on('connection', function(socket){
socket.on('message', function(message){
socket_io.emit('incoming', message)
});
});
Thank you!
You can use socket.broadcast.emit() to send to everyone except that socket:
var io = require('socket.io')(8888);
io.on('connection', function(socket) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
UPDATE: The following example works just fine for me:
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);
});
}
io.on('connection', function(socket) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
index.html:
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$('document').ready(function() {
var server = io.connect('http://localhost');
$('.chat').keydown(function(event) {
if (event.which == 13) {
var $save = $(this);
server.emit('message', $save.val());
$save.val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
</script>
</head>
<body>
<input type="text" class="chat">
<div id="textfield"></div>
</body>
</html>
When pressing enter, the message in the input box is only displayed once to all other connected socket.io users.
Okay, I've finally figured out the problem.
I'm using Express 4.0. That means, I'm using routes to run the server, and I had the socket io code running inside the route. Each time a user connects, it has to go through the route first, and it's all binding onto the same socket_io.
Thanks to everybody who helped!
I also faced it, like multiple socket calls in network tab and i just add this "transports" key object to socket instance, both on client and backend.
socket = io("http://localhost:3002", {
transports: ['websocket']
})
React, Node, AWS EB
I am trying to use node.js and socket.io library to establish websocket connection between client and server. The server will generate a random number per second and it will emit a event which allow client to detect.
The problem is the client(a webpage) can detect the event and display the random number send by server, but it's not real-time. I had to refresh my browser in order to display a new random number. I want the client to display the random number in real-time but I don't know why my websocket app appears to be not real-time.
Server(main.js) source code:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
randomNum();
function randomNum(){
io.on('connection', function(socket){
socket.emit('random', Math.floor((Math.random() * 100) + 1));
});
setInterval(randomNum, 1000);
}
server.listen(8080);
Client(index.html) source code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Websocket</title>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('random', function(data){
document.getElementById("displayNum").innerHTML = data;
});
</script>
</head>
<body>
<p id="displayNum"></p>
</body>
</html>
You shouldn't do this:
function randomNum(){
io.on('connection', function(socket){
socket.emit('random', Math.floor((Math.random() * 100) + 1));
});
setInterval(randomNum, 1000);
}
You set io.on connection every 1s. You should make function for emiting your random and set interval outside this function
Hello guys i'm having a problem in redis pub/sub because my client does not show the message i've published in redis-cli. I used the codes found here in stackoverflow and i made some modification. Here is the link and code. I hope you can help me, my goal is to publish the message to the client index.html using redis publish in redis-cli. I've done this before but i can't make it work again. Thanks in advance guys.
Here is my client index.html
<html>
<head>
<title>PubSub</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<!-- <script src="/javascripts/socket.js"></script> -->
</head>
<body>
<div id="content"></div>
<script>
var socket = io.connect('http://localhost:3000');
var content = $('#content');
socket.on('connect', function() {
});
socket.on('message', function (message){
content.prepend(message + '<br />');
}) ;
socket.on('disconnect', function() {
console.log('disconnected');
content.html("<b>Disconnected!</b>");
});
socket.connect();
});
</script>
</body>
</html>
Here is my server.js
var express = require('express');
var app = express();
var redis = require('redis');
var http = require('http');
var server = http.createServer(app);
var socket = require('socket.io').listen(server);
var publish = redis.createClient();
app.listen(3000);
console.log("Express server listening on port 3000")
app.get('/', function (req,res) {
res.sendfile(__dirname + '/public/index.html');
});
socket.on('connection', function (client) {
var subscribe = redis.createClient();
subscribe.subscribe('pubsub');
subscribe.on("message", function (channel, message) {
publish.send(message);
});
publish.on('message', function (msg) {
});
publish.on('disconnect', function() {
subscribe.quit();
});
});
Redis will not send data to connected clients for you. You must instruct Socket.IO to emit data:
subscribe.on("message", function (channel, message) {
socket.emit('message', message);
});