Sockets - No data is shown on the client site - javascript

I want to send data via socket.io to my client via nodejs.
The data I am receiving are from pusher.
I am using an express backend and loading my server like that.
#!/usr/bin/env node
var debug = require('debug')('testApp');
var app = require('../app');
var Pusher = require('pusher-client');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
/**
* return pusher data
*/
var API_KEY = 'cb65d0a7a72cd94adf1f';
var pusher = new Pusher(API_KEY, {
encrypted: true
});
/**
* Socket.io
*/
var io = require("socket.io").listen(server, {log: true});
io.sockets.on("connection", function (socket) {
// This will run when a client is connected
// This is a listener to the signal "something"
socket.on("data", function (data) {
var channel = pusher.subscribe("ticker.160");
channel.bind("message", function (data) {
console.log(data);
});
});
// This is a signal emitter called "something else"
socket.emit("something else", {hello: "Hello, you are connected"});
});
On my client I am running the following script:
index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js" />
<script src='/javascripts/socket.js'></script>
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %> Juhu!</p>
</body>
</html>
My socket.js file:
var socket = io.connect(window.location.hostname);
socket.on('data', function(data) {
var total = data.total;
//print data to console
console.log(data);
});
My problem is that nothing gets shown in the console in my webbrowser, even though the data is coming in at my nodejs application.
Any recommendation what I am doing wrong?
I appreciate your replies!

I do believe the problem is when you use: socket.emit("something else", {hello: "Hello, you are connected"});
but have this in client-side: socket.on('data', function(data) {.
When you emit, you use the channel "something else", but on the client-side you are checking on the channel "data".
So on client-side you should be having socket.on('something else', function(data){.
Hope I helped. There isn't much info I could find on sockets.io, so I do not know if there is a preexisting channel called 'data'. Do enlighten me if so :)

Related

I don't see on client in real time the value of json file with node js

I see this example on a precedent question on this link how to display a realtime variable in nodejs in HTML and i dont't see in real time the value of json file on client
despite the answer is defined correctly.
Moreover in the bash i launch the command node --inspect socketProva.js (socketProva.js is the name of my server file) and i see in the page of inspect this message "WebSockets request was expected". The strange thing is that the server show correctly in real time the data of json file but the communication with client it does not seem to happen.
Thanks for the answers and excuse for my bad english.
socketProva.js and index.html
var io = require('socket.io')(8080); // The port should be different of your HTTP server.
var fs = require('fs');
var obj = JSON.parse(fs.readFileSync('prova.json', 'utf8'));
io.on('connection', function (socket) { // Notify for a new connection and pass the socket as parameter.
console.log('new connection');
var incremental = 0;
setInterval(function () {
console.log('emit new value', obj);
obj = JSON.parse(fs.readFileSync('prova.json', 'utf8'));
socket.emit('update-value', obj); // Emit on the opened socket.
incremental++;
}, 1000);
});
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p id="messages"></p>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<pre id="incremental"></pre>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var socket = io('http://localhost:8080'); // Connect the socket on the port defined before.
socket.on('update-value', function (value) { // When a 'update-value' event is received, execute the following code.
console.log('received new value', value);
$('#incremental').html(value);
});
</script>
</body>
</html>
JSON File: prova.json
{
"football":{
"id": 1,
"home": "Liverpool",
"away": "Chelsea",
"score": "1-0",
"last scorer":"Gerrard"
}
}
If the prova.json don't change during time, there is no need to read it using fs.readFileSync. You can require it.
var obj = require('prova.json');
The full example is shown below: (remember I changed the client socket.io.js version)
server:
var io = require('socket.io')();
var data = require('./data.json')
io.on('connection', function (socket) {
console.log('connected:', socket.client.id);
setInterval(function () {
data.value = Math.random();
socket.emit('update-value', data);
console.log('message sent to the clients');
}, 1000);
});
io.listen(8080);
client:
<!DOCTYPE html>
<html>
<head>
<!-- this changed -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<body>
<div id="incremental"></div>
<script>
var socket = io('http://localhost:8080');
socket.on('update-value', function (data) {
console.log('received new value', data);
var $div = $('<div>');
$div.text(data.value)
$('#incremental').append($div);
});
</script>
</body>
</html>
And data.json:
{
"value": 1
}

node js simple chat app delay on event trigger

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

Sending socket.io instance to express route

I am trying to create a nodejs app that will search in various web sites using their API. The result will be sent to the client as soon as it receive result from those API using socket.io. The front end will then add those result using jQuery.
What is the best way to implement this?
So Far I have tried:
Sample code 1
At first I created a middleware for express that add the socket to the request like -
var socketMiddleWare = function(req, res, next){
io.on('connection', function(socket){
console.log(io.engine.clientsCount + " clients connected.");
req.socket = socket;
socket.on('disconnect', function(){
console.log(io.engine.clientsCount + " clients after disconnec.");
});
});
next();
};
then added this middleware to my route -
app.use('/users', socketMiddleWare, users);
It works but the problem is it create multiple event listener each time user refresh the page.
Sample code 2
So then I tried (sample code)
io.on('connection', function(socket){
console.log("user connected");
global.socket = socket;
socket.on('disconnect', function(){
console.log("disconnect");
});
socket.on('my message', function(){
console.log("My message received");
});
});
and on my test route I did
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
if(socket){
socket.emit('response', 'nothing');
}
res.render('index', { title: 'Express' });
});
module.exports = router;
It solved the previous problem of multiple event listener on refresh But most of the time it can not emit the response. And even it emit my browser can not show the result. On client side I did something like this -
var socket = io.connect('http://localhost');
socket.on('response', function(data){
console.log(data);
document.getElementById("change").innerHTML += data;
});
I can see the response in browser console but my browser show the change for a few milliseconds before it disappear.
I think the the main problem is The page loads before establishing socket connection.
I am currently learning node.js and socket.io. So please help me.
Conclusion
I do have plan to add social network features like one to one message, live friends feed update on home page etc using socket.io in future. Please let me know if there is any good documentation or open source project that can help me implementing it.
I am searching for solution for last couple of days but with no luck so far. I am ready to learn any new methodology or fully rewrite my code.
TL;DR
When a user client search for item, push contents to the client that requested the content when new data available. Data is available after processing response from website like "The Movie Database" and "TheTVDB.com" through their API.
You can use the ID of the socket to keep track of which socket to send results to.
Client
When the user then searches for something the ID is included in the query parameters.
<body>
<form>
<!-- Disable the search bar until the socket is connected -->
<input type="search" name="q" placeholder="Search" disabled>
</form>
<div id="results"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
var resultsElement = document.querySelector("#results");
var search = document.querySelector("form [type=search]");
var socket = io("http://localhost:3000");
socket.on("connect", function(){
search.disabled = false;
});
socket.on("results", function(results){
for(var i = 0;i < results.length;i++){
var result = document.createElement("div");
result.textContent = results[i];
resultsElement.appendChild(result);
}
});
document.querySelector("form").addEventListener("submit", function(event){
fetch("/search?socketID=" + encodeURIComponent(socket.id) + "&q=" + encodeURIComponent(search.value));
event.preventDefault();
});
</script>
</body>
Server
When the server receives the search request it gets the socket using the socket ID sent in the query parameters and starts sending results back to the client.
var app = require("http").createServer(handler);
var io = require("socket.io")(app);
var fs = require("fs");
var url = require("url");
app.listen(3000);
function handler(req, res) {
var query = url.parse(req.url, true).query;
if(req.url.startsWith("/search")){
var results = ["things", "stuff", "items"];
// Server-side IDs have "/#" in front of them
var socket = io.sockets.connected["/#" + query.socketID];
if(socket){
// Get and send "search results"
var interval = setInterval(function(){
var popped = results.pop();
if(popped){
socket.emit("results", [query.q + " " + popped]);
}else{
clearInterval(interval);
}
}, 1000);
}
res.writeHead(204);
res.end();
}else{
fs.readFile(__dirname + "/index.html", function(err, data) {
res.writeHead(200);
res.end(data);
});
}
}

Why does my Node.js server hang with this small script?

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().

Socket IO output too many times

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

Categories