Socket.io : very strange - node.js

I try to make a chat with node.js and socket.io but I tried since 6 hours to resolve my problem but I don't succeed.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Communication avec socket.io !</h1>
<div id="formulaire">
<form action="" method="post" id="form">
<input type="text" id="pseudo" placeholder="Pseudo"/>
<input type="text" id="message" placeholder="Message"/>
<input type="submit" value="Envoi"/>
</form>
</div>
<div id="wrapper">
Texte par défaut
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
$("#formulaire").submit(function() {
var pseudo = $("#pseudo").val();
var message = $("#message").val();
alert(pseudo = " " + message);
socket.emit("pseudo", pseudo);
socket.emit("message", message);
});
socket.on("message", function (message) {
alert("bien récupéré depuis serveur: " + message); //It works
var wrapper = document.getElementById('wrapper');
wrapper.innerHTML = "Le message est: " + message; //It doesn't work ?????
});
</script>
</body>
</html>
app.js
var http = require("http");
var fs = require("fs");
// Serving index.html to the client
var server = http.createServer(function(req, res) {
fs.readFile("./index.html", "utf-8", function(error, content) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(content);
});
});
// Loading socket.io
var io = require("socket.io").listen(server);
// Logging in console when a client connects
io.sockets.on("connection", function (socket) {
//socket.emit("message", "A new client has connected");
socket.on("pseudo", function(pseudo) {
console.log(pseudo);
socket.emit("pseudo", pseudo);
});
socket.on("message", function(message) {
console.log(message);
socket.emit("message", message);
});
});
server.listen(8080);
I don't understand because the alert gets opened with the variable from the server message but innerHTML doesn't get filled.

Because pseudo and message are input fields in a form, by default, the page get's reloaded because you click a submit button. To prevent this, you need to put return false; at the end of the submit handler, like this:
$("#formulaire").submit(function() {
var pseudo = $("#pseudo").val();
var message = $("#message").val();
console.log(pseudo = " " + message);
socket.emit("pseudo", pseudo);
socket.emit("message", message);
return false;
});
Note that I replaced alert with console.log, of which the output can be viewed in the console, which you can open with F12 in Google Chrome. I find it to be less annoying for debugging purposes. (it doesn't create a popup and it can print arrays and objects)

Related

redirecting a page and displaying a message through javascript

I have an HTML page which provides input fields for email ID and password, I use these values to connect with my backend SQL server through node js express application .
I have an app.post() method to connect with SQL.
app.post('/user', function (req, res, body) {
uid = req.body.user1;
pwd = req.body.user2;
config = 'Server={ip of server};Database=Dbname;Uid=domain\\user' + uid + ';Pwd=' + pwd;
var dbConn = new sql.Connection(config);
dbConn.connect().then(function () { //using promises instead of callbacks(onceconnect() is done), then go to then()
var request = new sql.Request(dbConn);
console.log('DONE');
res.status(500).json({ status: 'done' })
}).catch(function (err) {
console.log("INVALID");
res.status(500).json({ status: 'invalid' })
});
What I want to achieve is -
If the credentials are valid, displaying an alert 'DONE' at client side.
If the credentials are invalid, displaying an alert 'INVALID' at client side.
Currently, if everything is valid, there is DONE at /user.
If the ID and Password do not match, there is INVALID at /user.
My client side code is
<!DOCTYPE html>
<html>
<body>
<form id ="target" action="/user" method="post">
UserID : <input id="uid" type="text" name="user1" /> <!text fields for date input>
Password : <input id="pwd" type="password" name="user2" />
<input id="Submit1" type="submit" value="LOGIN"/> <!--<!submit button>-->
<input id="Button" type="button" value="show graphs" onclick="btntest_onclick()" />
</form>
$.post("/user", function (data) {
$("#target").html(data)
alert( "Data Loaded: " + data );
});
<script type="text/javascript">
function btntest_onclick() {
setTimeout(function () {
window.location.href = "/../";
},500);
}
</script>
</body>
</html>
I am unable to use $.post() on client to retrieve data back from user- gives 500 error.
How do I proceed? Please help me.
I could solve this by using the jquery ajax callback that returns back data to the client.
$("#target").submit(function (event) {
var formData = {
'uid': $('input[name=uid]').val(),
'pwd': $('input[name=pwd]').val()
};
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: '/user', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true
})
.error(function (data) {
// log data to the console so we can see
alert(data.responseText);
})
.done(function (data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
});
event.preventDefault();
});

Reaching a server from outside the network

I recently tried to run a nodejs chat demo and test it. It worked on the same computer as the program were running on, but the chat couldn't be reached from outside. This is the code for the server:
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({host: 'put_my_ip_in_here',port: 8000});
wss.on('connection', function(ws)
{
console.log('client connected...');
ws.on('message', function(message)
{
console.log('received from client: ' + message);
ws.send('received from server: ' + message);
});
});
I unblocked the port 8000 (udp and tcp as in my router and my firewall and told someone from outside my network to open the following page
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
function connect()
{
var socket = new WebSocket("ws://put_my_ip_in_here:8000");
socket.onopen = function() { message('Socket Status: '+socket.readyState+' (open)'); }
socket.onmessage= function(msg) { message('received: '+msg.data); }
function send()
{
var text = $('#text').val();
socket.send(text);
message('sent : '+text)
$('#text').val("");
}
{
$('#Log').append(msg+'</br>');
}
$('#text').keypress(function(event)
{
if (event.keyCode == '13')
{
send();
}
});
}
connect();
});
</script>
</head>
<body>
<div id="container">
<div id="Log"></div>
Input: <input id="text" type="text" />
</div>
</body>
</html>
But my computer/the chat wasnt reachable :c
Where is the problem? The demos seems to be running fine!

Twilio-unable to accept or reject incoming call

My browser will ring, but Im unable to accept or reject the call. The accept and reject buttons do not show when I receive an incoming call. Am I missing something in my code? Need help!
my snippet is:
<!DOCTYPE html>
<html>
<head>
<title> Screenpop </title>
<script type="text/javascript"
src="//static.twilio.com/libs/twiliojs/1.2/twilio.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js">
</script>
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<head>
<link href="/images/stylesheets/favicon.ico"
type="image/x-icon" rel="icon" />
<link href="/stylesheets/playusclient.css"
type="text/css" rel="stylesheet" />
<script type="text/javascript">
var socket = io.connect();
$(function() {
$(".call").on("click", function() {
// The properties of this object will be sent as POST
// Parameters to URL which generates TwiML.
Twilio.Device.connect({
CallerId:'<%= phone_number %>' ,
// Replace this value with a verified Twilio number:
// https://www.twilio.com/user/account/phone-numbers/verified
PhoneNumber:$("#number").val() //pass in the value of the text field
});
});
$(".hangup").on("click", function() {
Twilio.Device.disconnectAll();
});
/* Create the Client with a Capability Token */
Twilio.Device.setup('<%= token %>', {debug: true});
/* Let us know when the client is ready. */
Twilio.Device.ready(function (device) {
$("#log").text("Ready");
});
Twilio.Device.incoming(function(connection) {
$( "#dialog-confirm" ).dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
"Accept": function() {
connection.accept();
$("#log").html("Call answered!");
$( this ).dialog( "close" );
},
"Reject": function() {
connection.reject();
$("#log").html("Call rejected! Awaiting next call.");
$( this ).dialog( "close" );
}
}
});
$("#log").html("Incoming call from " + connection.parameters.From);
socket.emit("incoming",connection.parameters.From);
});
Twilio.Device.disconnect(function(connection) {
$("#log").html("Ready");
});
/* Report any errors on the screen */
Twilio.Device.error(function (error) {
$("#log").text("Error: " + error.message);
});
Twilio.Device.connect(function (conn) {
$("#log").text("Successfully established call");
});
socket.on('foundPerson', function(data) {
$("#dialog-confirm").html("<i>" + data.number + "
</i><br /><b>" + data.name + "</b><img src='" +
data.photo + "' />");
$( "#dialog-confirm" ).dialog( "open" );
});
});
</script>
</head>
<body>
<div id="dialog-confirm" title="Receive Call?" style="display: none">
</div>
<button class="call">
Call
</button>
<button class="hangup">
Hangup
</button>
<input id="number" type="text" placeholder="Enter a number like
+16519998888"/>
<div id="log">Loading pigeons...</div>
</body>
</html>
Twilio developer evangelist here.
I think you may be opening your JQuery UI dialog incorrectly here.
What you want to do is set up the dialog outside of the incoming call event and then, when you get the call event, open the dialog.
So, it should be a bit more like this:
<script type="text/javascript">
var socket = io.connect();
// set up the dialog
$(function() {
var dialog = $("#dialog-confirm").dialog({
resizable: false,
modal: true,
autoOpen: false,
buttons: {
"Accept": function() {
Twilio.Device.activeConnection().accept();
$("#log").html("Call answered!");
$( this ).dialog( "close" );
},
"Reject": function() {
Twilio.Device.activeConnection().reject();
$("#log").html("Call rejected! Awaiting next call.");
$( this ).dialog( "close" );
}
}
});
// do other Twilio.Device setup here
Twilio.Device.incoming(function(connection) {
// open the dialog
dialog.dialog("open");
$("#log").html("Incoming call from " + connection.parameters.From);
socket.emit("incoming",connection.parameters.From);
});
// do other Twilio.Device setup here
</script>
Let me know if that helps at all!

How to show a file updated constantly on the browser?

My goal is to update the web page with some file. When I edit and save the file, and instantly its content appears updated to a page.
I´m using socket.io to handle this issue. But. I need some modifications on my code to approaches it.
:: My server side code:
var PORT = 8001;
var io = require("socket.io").listen(PORT);
var fs = require("fs");
io.sockets.on('connection', function(socket) {
console.log("Connected!");
socket.emit('connected', { accept: true});
console.log("Trying to send a content file to client...");
fs.readFile("file.txt","UTF-8", function(err, data) {
if (err) throw err;
socket.emit("requestFile", data );
console.log("Conteúdo:", data);
})
});
console.log("Application has started! Port: " + PORT);
:: My page
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="http://localhost:8001/socket.io/socket.io.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
.arquivo {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
width: 900px;
border: 2px solid black;
-moz-border-radius: 3px;
}
</style>
<script type="text/javascript">
console.log("Try to logon...");
var socket = io.connect("localhost", {"port" : "8001"});
socket.on("connected", function(data) {
console.log("Connected User?", data.accept);
});
//recebe o arquivo indefinidamente
var requestFile = socket.on("requestFile", function(data) {
$("#arquivoSaida").html(data + "<br/>");
console.log(data);
});
setInterval(requestFile, 200);
</script>
</head>
<body>
<h3 style="font: Arial, Verdana; font-size: 14px; font-weight: bold;">
File updated:
</h3>
<div id="arquivoSaida">
</div>
</body>
</html>
I have used a setInterval to fires at 200 ms to request a file to a server. Any cue will be very welcome.
Thanks in advance!
-- UPDATED with Solution:
:: I did some alterations from my original code. This solution was provided by PuerkitoBio. Thanks, man!
The code updated:
var PORT = 8001;
var io = require("socket.io").listen(PORT);
var fs = require("fs");
io.sockets.on('connection', function(socket) {
console.log("Connected!");
socket.emit('connected', { accept: true});
console.log("Trying to send the content to a client...");
console.log("dir", __dirname);
fs.watch(__dirname + "/arquivo.txt", function(event, filename) {
console.log("Event:", event);
if (event == "change") {
fs.readFile("arquivo.txt","UTF-8", function(err, data) {
if (err) throw err;
socket.emit("receiveFile", data );
console.log("Content:", data);
})
}
});
});
console.log("Application has started! Port: " + PORT);
You can use fs.watchFile() and compare curr.mtime with prev.mtime to detect if the file has been modified. Then use readFile to send the content to your connected client. From the docs.
With sockets, you don't poll the data from the client, it gets pushed from the server when required (when your file changes, in your case). So you don't need the setInterval from the client side (you will watch for changes server-side using fs.watchFile, and push the content to your client, so your "requestFile" handler on the client will get called automatically (should be renamed receiveFile or something to be more accurate!).

Sending messages to all browsers with socket io

I am messing around with socket.io and node.js, and was wondering how to accomplish the following: I have a simple form that sends a text string to the server, and the server sends it back, and it gets appended to a div. what I would like to do is have that div update for all users in all browsers, currently it only updates the one that the message was sent from.
code from app.js (node.js server) :
io.sockets.on('connection', function(socket) {
socket.on('send_message', function(data) {
data.message = data.message + ' yo<br/>';
socket.emit('get_message',data);
});
});
code on client-side:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$(document).ready(function() {
var socket = io.connect('http://localhost:3000');
$('#sender').live('click',function() {
var user_message = $('#message_box').val()
socket.emit('send_message',{message: user_message});
});
socket.on('get_message', function(data) {
$('#data').append(data.message);
});
});
</script>
and the html:
<div id='data'></div>
<input type='text' id='message_box' placeholder='send message'>
<button id='sender'>Send Message</button>
what should I be doing to send messages to multiple browsers?
Change
socket.emit('get_message',data);
To
socket.broadcast.emit('get_message',data);
To broadcast it to all connected users, except to the socket where you are calling the broadcast on.
If you also want to include that socket you can do
io.sockets.emit('get_message', data);

Resources