Socket.IO Websocket Send message not working with Firefox and Chrome - html

I have a running server with apache and Socket.IO. I'm trying to send and receive message using socket.io on my website.
This is the code of my server:
var fs = require('fs');
var hskey = fs.readFileSync('file.key');
var hscert = fs.readFileSync('file.crt');
var options = {
key: hskey,
cert: hscert
};
var app = require('https').createServer(options);
var io = require('/usr/local/lib/node_modules/socket.io').listen(app);
app.listen(8181);
io.sockets.on('connection', function (socket) {
socket.emit('serverMessage', 'Bienvenue master!');
socket.broadcast.emit('serverMessage', 'New user online');
});
And this is the webpage:
<!doctype html>
<html>
<head>
<title>Socket.io Test</title>
<script src="./socket.io.js"></script>
</head>
<body>
<script>
var socket;
var firstconnect = true;
function connect() {
if(firstconnect) {
socket = io.connect('https://secure.mysite.com:8181');
socket.on('serverMessage', function(data){ message(data); });
socket.on('connect', function(){ status_update("Connected to Server"); });
socket.on('disconnect', function(){ status_update("Disconnected from Server"); });
socket.on('reconnect', function(){ status_update("Reconnected to Server"); });
socket.on('reconnecting', function( nextRetry ){ status_update("Reconnecting in "
+ nextRetry + " seconds"); });
socket.on('reconnect_failed', function(){ message("Reconnect Failed"); });
firstconnect = false;
}
else {
socket.socket.reconnect();
}
}
function disconnect() {
socket.disconnect();
}
function message(data) {
document.getElementById('message').innerHTML += "<br>" + "Server says: " + data;
}
function status_update(txt){
document.getElementById('status').innerHTML = txt;
}
function esc(msg){
return msg.replace(/</g, '<').replace(/>/g, '>');
}
function send() {
socket.send('clientMessage', 'world');
};
</script>
<h1>Socket.io Test</h1>
<div><p id="status">Waiting for input</p></div>
<div><p id="message"></p></div>
<button id="connect" onClick='connect()'/>Connect</button>
<button id="disconnect" onClick='disconnect()'>Disconnect</button>
<button id="send" onClick='send()'/>Send Message</button>
</body>
</html>
Everything seems to work fine under Safari (websocket) and Opera (json pooling) but with Firefox and Chrome (websocket) I cannot send any message from the client to the server. Everything else is working, I can handshake, connect and gets server messages. I made allot of research but seems like I'm the only one with this problem.
Thanks for helping me!

I found the problem, I was using a different version of socket.io.js then the server side.

when you attach the socket.io module to express it intercepts the socket.io route.
So when you request "https://secure.mysite.com:8181/socket.io" it will respond with
"Welcome to socket.io."
So when you request the client side socket.io.js it comes directly from the socket.io module.
"https://secure.mysite.com:8181/socket.io/socket.io.js"
So If you wan't to mod the client side library you could create a modified copy and let express serve up the file, but as you update socketio through npm you'll have to bump up your modified copy as well manually.

if in FireFox you get this error - first check enabled or no proxy. and turnoff proxy if enabled.

Related

Send data from SerialPort to socket.io

I'm struggling with socket.io, express, and node.js.
I send data from an Arduino to my cmd. This is done with the serialport libary. But now I want this data displayed on my web browser. I'm using the express library for this. I have index.js here is the connection with the arduino and browser. And an index.html
This code do I have:
code from index.js (node.js server):
var express = require('express'),
app = express(),
server = require('http').Server(app),
io = require('socket.io')(server),
port = 8888;
//Server start
server.listen(port, () => console.log('on port' + port))
//user server
app.use(express.static(__dirname + '/public'));
io.on('connection', onConnection);
var connectedSocket = null;
function onConnection(socket){
connectedSocket = socket;
}
//Arduino to CMD
const SerialPort = require('serialport');
const Readline = SerialPort.parsers.Readline;
const usbport = new SerialPort('COM4');
const parser = usbport.pipe(new Readline());
parser.on('data', console.log);
The data what is recieved from the serialport (Arduino), had to be displayed in the index.html (webbrowser). I tried already something but it doesn't work. It has to be printed in the <p></p> in the html code.
The index.html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="text">
<p></p>
</div>
<script>
var text = document.getElementById('text');
var socket = io.connect('http://localhost:8888');
socket.on('data', function(message) {
text.innerHTML = message.data;
});
</script>
</body>
</html>
Instead of
parser.on('data', console.log);
Try this:
parser.on('data', function (data) {
io.emit('data', { data: data });
});
That should send the parsed data from the SerialPort to the socket, which should end up on the client side on the website.

Node.js HTTPS Request for Quandl API

I am using IBM Bluemix to make a web service for a school project.
My project needs to request JSON data from two APIs, for use in the project.
The first one is a http.request, which I executed just fine. For the second one, however, I need a https.request - and that is where the trouble comes from.
I don't know how to get a JSON through a https request. I've been trying to adapt the code for the http one, but my efforts have rendered useless.
How can I request a JSON via https?
Here is my .jsfile:
// Hello.
//
// This is JSHint, a tool that helps to detect errors and potential
// problems in your JavaScript code.
//
// To start, simply enter some JavaScript anywhere on this page. Your
// report will appear on the right side.
//
// Additionally, you can toggle specific options in the Configure
// menu.
function main() {
return 'Hello, World!';
}
main();/*eslint-env node*/
//------------------------------------------------------------------------------
// node.js starter application for Bluemix
//------------------------------------------------------------------------------
// HTTP request - duas alternativas
var http = require('http');
var request = require('request');
//HTTPS request
var https = require('https');
var https = require('https');
var fs = require('fs');
// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
//chama o express, que abre o servidor
var express = require('express');
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
// print a message when the server starts listening
console.log("server starting on " + appEnv.url);
});
app.get('/home1', function (req,res) {
http.get('http://developers.agenciaideias.com.br/cotacoes/json', function (res2) {
var body = '';
res2.on('data', function (chunk) {
body += chunk;
});
res2.on('end', function () {
var json = JSON.parse(body);
var CotacaoDolar = json["dolar"]["cotacao"];
var VariacaoDolar = json["dolar"]["variacao"];
var CotacaoEuro = json["euro"]["cotacao"];
var VariacaoEuro = json["euro"]["variacao"];
var Atualizacao = json["atualizacao"];
obj=req.query;
DolarUsuario=obj['dolar'];
RealUsuario=Number(obj['dolar'])*CotacaoDolar;
EuroUsuario=obj['euro'];
RealUsuario2=Number(obj['euro'])*CotacaoEuro;
Oi=1*VariacaoDolar;
Oi2=1*VariacaoEuro;
if (VariacaoDolar<0) {
recomend= "Recomenda-se, portanto, comprar dólares.";
}
else if (VariacaoDolar=0){
recomend="";
}
else {
recomend="Recomenda-se, portanto, vender dólares.";
}
if (VariacaoEuro<0) {
recomend2= "Recomenda-se, portanto, comprar euros.";
}
else if (VariacaoEuro=0){
recomend2="";
}
else {
recomend2="Recomenda-se,portanto, vender euros.";
}
res.render('cotacao_response.jade', {
'CotacaoDolar':CotacaoDolar,
'VariacaoDolar':VariacaoDolar,
'Atualizacao':Atualizacao,
'RealUsuario':RealUsuario,
'DolarUsuario':DolarUsuario,
'CotacaoEuro':CotacaoEuro,
'VariacaoEuro':VariacaoEuro,
'RealUsuario2':RealUsuario2,
'recomend':recomend,
'recomend2':recomend2,
'Oi':Oi,
'Oi2':Oi2
});
app.get('/home2', function (req,res) {
https.get('https://www.quandl.com/api/v3/datasets/BCB/432.json?api_key=YOUR_API_KEY', function (res3) {
var body = '';
res3.on('data', function (chunk) {
body += chunk;
});
res3.on('end', function () {
var x=json.dataset.data[0][1];
console.log("My JSON is "+x); });
});
});
});
});
});
Your https.get should work as set up. There were a few other issues with your code that caused it to break, which I'm outlining below with explanations:
1. Potentially incorrect nesting of the /home2 route
Your declaration of the /home2 route was inside the declaration of your /home1 route. It is likely that you meant it to be outside. I've fixed this (and also fixed some indentation) in the code below.
2. json is undefined in the /home2 route's https.get callback
The variable json is not defined before use in the https.get callback function. You will need a line similar to the one you have in the http.get callback: var json = JSON.parse(body);.
Here's the fixed code for the routes
app.get('/home1', function (req,res) {
http.get('http://developers.agenciaideias.com.br/cotacoes/json', function (res2) {
var body = '';
res2.on('data', function (chunk) {
body += chunk;
});
res2.on('end', function () {
var json = JSON.parse(body);
var CotacaoDolar = json["dolar"]["cotacao"];
var VariacaoDolar = json["dolar"]["variacao"];
var CotacaoEuro = json["euro"]["cotacao"];
var VariacaoEuro = json["euro"]["variacao"];
var Atualizacao = json["atualizacao"];
obj=req.query;
DolarUsuario=obj['dolar'];
RealUsuario=Number(obj['dolar'])*CotacaoDolar;
EuroUsuario=obj['euro'];
RealUsuario2=Number(obj['euro'])*CotacaoEuro;
Oi=1*VariacaoDolar;
Oi2=1*VariacaoEuro;
if (VariacaoDolar<0) {
recomend= "Recomenda-se, portanto, comprar dólares.";
}
else if (VariacaoDolar=0){
recomend="";
}
else {
recomend="Recomenda-se, portanto, vender dólares.";
}
if (VariacaoEuro<0) {
recomend2= "Recomenda-se, portanto, comprar euros.";
}
else if (VariacaoEuro=0){
recomend2="";
}
else {
recomend2="Recomenda-se,portanto, vender euros.";
}
res.render('cotacao_response.jade', {
'CotacaoDolar':CotacaoDolar,
'VariacaoDolar':VariacaoDolar,
'Atualizacao':Atualizacao,
'RealUsuario':RealUsuario,
'DolarUsuario':DolarUsuario,
'CotacaoEuro':CotacaoEuro,
'VariacaoEuro':VariacaoEuro,
'RealUsuario2':RealUsuario2,
'recomend':recomend,
'recomend2':recomend2,
'Oi':Oi,
'Oi2':Oi2
});
});
});
});
app.get('/home2', function (req,res) {
https.get('https://www.quandl.com/api/v3/datasets/BCB/432.json?api_key=YOUR_API_KEY', function (res3) {
var body = '';
res3.on('data', function (chunk) {
body += chunk;
});
res3.on('end', function () {
var json = JSON.parse(body);
var x=json.dataset.data[0][1];
console.log("My JSON is "+x);
res.send('done https: JSON result: '+x);
});
});
});
Final note
You added your API key in the https URL. I would recommend changing the key, if sensitive information is involved.
The HTTPS server and client API is almost identical to the HTTP API.In fact, the client API is the same, and the HTTPS server only differs in that it needs a certificate file.
Starting the server
To start the HTTPS server, you need to read the private key and certificate. Note that readFileSync is used in this case, since blocking to read the certificates when the server starts is acceptable:
// HTTPS
var https = require('https');
// read in the private key and certificate
var pk = fs.readFileSync('./privatekey.pem');
var pc = fs.readFileSync('./certificate.pem');
var opts = { key: pk, cert: pc };
// create the secure server
var serv = https.createServer(opts, function(req, res) {
console.log(req);
res.end();
});
// listen on port 443
serv.listen(443, '0.0.0.0');
Note that on Linux, you may need to run the server with higher privileges to bind to port 443. Other than needing to read a private key and certificate, the HTTPS server works like the HTTP server.

Web socket connection can't be established

I am able to establish connection between browser and server lately.. But for the past two days the connection is not getting established.. I am unable to figure out what could have gone wrong?
<head>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
var x=document.getElementById('chat').value;
// Let us open a web socket
var ws = new WebSocket("ws://localhost:7869/echo");
ws.onopen = function()
{
// Web Socket is connected, send data using send()
ws.send(x);
var send=document.getElementById('fill');
send.innerHTML = send.innerHTML+'<br>'+ x;
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
var send=document.getElementById('fill');
send.innerHTML = send.innerHTML +'<br>'+ received_msg;
};
ws.onclose = function()
{
// websocket is closed.
alert("Connection is closed...");
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id="sse">
<input type="text" id="chat"></div><br>
<button type='submit' onclick='javascript:WebSocketTest()'>Send</button>
<div id='fill'>hi</div>
</body>
Here is the code and websocket server is listening the 7869 port.

Displaying streaming twitter on webpage with socket.io/node.js

I'm trying to build a Twitter streaming web application using node.js socket.io and twit.
var express = require('express')
, app = express()
, http = require('http')
, server = http.createServer(app)
,Twit = require('twit')
, io = require('socket.io').listen(server);
server.listen(8080);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
var watchList = ['love', 'hate'];
io.sockets.on('connection', function (socket) {
console.log('Connected');
var T = new Twit({
consumer_key: ''
, consumer_secret: ''
, access_token: ''
, access_token_secret: ''
})
T.stream('statuses/filter', { track: watchList },function (stream) {
stream.on('tweet', function (tweet) {
io.sockets.emit('stream',tweet.text);
console.log(tweet.text);
});
});
});
Here's my client side
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script>
$(function(){
var socket = io.connect('http://localhost:8080');
socket.on('tweet', function(tweet) {
$(
'<div class="tweet">' + tweet.text + '</div>');
});
});
</script>
</div>
When I run node app.js and try to connect to localhost:8080 I just get a blank page, even if everything ( soket.io, jquery, ... ) seems to have loaded correctly.
Here's a sample of the server output :
info - socket.io started
debug - served static content /socket.io.js
debug - client authorized
info - handshake authorized pwH0dbx4WvBhzSQXihpu
debug - setting request GET /socket.io/1/websocket/pwH0dbx4WvBhzSQXihpu
debug - set heartbeat interval for client pwH0dbx4WvBhzSQXihpu
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"name":"stream","args":["RT #mintycreative: Great to chat today RT #SharonHolistic: Treatments available tomorrow http://t.co/5Poq3KU08u Book yours now #WestMidsHou…"]}
debug - websocket writing 5:::{"name":"stream","args":["RT #laurenpeikoff: #BREAKING #ScottsdalePD confirms - police are investigating Michael Beasley for alleged sexual assault. #12News #azcentr…"]}
Hope you can help me to correct my mistakes.
Problem solved
Here's the code without any mistakes : (server side)
var express = require('express')
, app = express()
, http = require('http')
, server = http.createServer(app)
,Twit = require('twit')
, io = require('socket.io').listen(server);
server.listen(8080);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
var watchList = ['love', 'hate'];
var T = new Twit({
consumer_key: ''
, consumer_secret: ''
, access_token: ''
, access_token_secret: ''
})
io.sockets.on('connection', function (socket) {
console.log('Connected');
var stream = T.stream('statuses/filter', { track: watchList })
stream.on('tweet', function (tweet) {
io.sockets.emit('stream',tweet.text);
});
});
});
(client-side)
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('stream', function(tweet){
$('#tweetd').append(tweet+'<br>');
});
</script>
<div id="tweetd"></div>
</div>
The first issue is that you are constructing a new twitter listener each time a socket connection is opened. You should move that outside of the connection event. This is likely not ideal. I'm not sure how the twitter module is handling that internally but it likely actually is creating a new connection to their API each time a websocket connects.
On the client side you jQuery could bit a bit different. If you just wanted to add a tweet to the page each time a tweet occurs, append a new tweet to the body element with $('body').append()
See this gist for reference.

Receiving "Error: InvalidStateError: DOM Exception 11" on HTML5 websocket when calling .send(data) using Node.js

I am currently trying to develop a small chat application using node.js. This is my first node project but I am getting an error and I'm not really sure how to solve it.
I have written a simple chat server in node which is below.
var port = 3000;
var net = require('net');
var clients = [];
var server = net.createServer(function (socket) {
clients.push(socket);
bindEventHandlers(socket);
});
setInterval(function(){
console.log(clients.length);
}, 2000);
server.listen(port);
console.log('Server is listening on localhost:' + port);
function bindEventHandlers(socket) {
socket.on('data', function(data){
broadcastDataToAllClient(data, socket);
});
socket.on('close', function(){
clients.splice(clients.indexOf(socket), 1);
});
socket.on('error', function(){
console.log('Known Error << "It\'s a feature!"');
})
}
function broadcastDataToAllClient(data, socket) {
for (var client in clients) {
if(clients[client] == socket){ continue; }
clients[client].write(data);
}
}
And a quick client interface
<!DOCTYPE HTML>
<html>
<head>
<title>Node.js Chat Server</title>
<script type="text/javascript">
function init(){
if (window.WebSocket) {
var input = document.getElementById('messageBox');
var webSocket = new WebSocket("ws://localhost:3000/");
input.onkeyup = function(e){
if(e.keyCode == 13) {
console.log('sending message');
webSocket.send('some data');
}
};
webSocket.onopen = function(e){
alert('Open');
}
webSocket.onmessage = function(e){
console.log('Message');
}
webSocket.onclose = function(e){
console.log('Close');
}
webSocket.onerror = function(e){
console.log('Error');
}
} else {
console.log('unable to support :(');
}
}
</script>
</head>
<body lang="en" onload="init();">
<h1>Node.js Chat Server</h1>
<h3>Welcome to this simple chat server!</h3>
<input id="messageBox" size="50" />
</body>
</html>
When I call the webSocket.send('some data') I receive this error Error: InvalidStateError: DOM Exception 11. In the chat-server code I have a loop which logs the number of current clients so I know that the browser is connected.
Not sure where to go from here and any help would be much appreciated.
Alex
When you do webSocket.send('some data') the socket connection must be established, or specifically socket.readyState == 1.
You can check the websocket events here. To make sure this never happens, you should send after connection open, by using Socket.onopen event handler. You can do it like this.
if(webSocket.readyState == 1){
webSocket.send('some data');
}
else{
webSocket.onopen = function(e){
webSocket.send('some data');
}
}