Why isn't the server sending or the client receiving data via socket.io in my express app? - ajax

My node app posts an object (consisting of data collected in a form on the client) to Salesforce via their API. On receiving a success or error message, I would like to send it to the client-side, then display it. Socket.io seemed like the tool for this in my simple node/express3 app, but beyond the simple demo I'm not able to get data to pass between my server and my client.
My relevant server side code:
var express = require('express');
var port = 5432;
var app = module.exports = express();
var server = require('http').createServer(app);
var nforce = require('nforce');
var org = nforce.createConnection({
clientId: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
redirectUri: 'http://localhost:5432/oauth/_callback'
});
var io = require('socket.io').listen(server);
// here I authenticate with Salesforce, this works fine
app.post('/salesforce', function(req, res){
var lead = nforce.createSObject('Lead');
// here I construct the lead object, which also works fine
org.insert(lead, oauth, function(err, res) {
if (err === null) {
console.log(res);
leadSuccessMessage(res);
}
else {
console.log(err);
var error = {
errorCode: err.errorCode,
statusCode: err.statusCode,
messageBody: err.messageBody
};
console.log(error);
leadErrorMessage(error);
}
});
}
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
io.sockets.on('connection', function (socket) {
socket.emit('sfRes', resp);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
io.sockets.on('connection', function (socket) {
console.log("socket is: " + socket);
socket.emit('sfRes', err);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
And my relevant client side scripts:
<script src="/socket.io/socket.io.js"></script>
<script>
current.page = document.URL;
console.log("current page is: " + current.page);
var socket = io.connect(current.page);
socket.on('sfRes', function (data) {
console.log("client received: " + data);
fst.showLeadStatus(data);
socket.emit('thanks', {message: "received server feedback"});
});
</script>
When I post the form containing valid data using a spicy little AJAX call:
postToSF: function(){
$('#submitLead').on('click', function(e){
e.preventDefault();
var formData = $('#lead_form').serialize();
$.ajax({
type: 'POST',
url: '/salesforce',
data: formData,
success: function(){
fst.log('success!');
},
error: function(xhr, ajaxOptions, thrownError){
console.error(xhr.status); // 0
console.error(thrownError);
}
});
});
}
All I get are tears, and these in the server-side console:
// the result of `console.log(res)`
{ id: '00Qa000001FZfhKEAT', success: true, errors: [] }
// and proof that `leadSuccessMessage()` got called
called success message from server
Instead of calling this function from a client-side object as it's supposed to:
showLeadStatus: function(response){
if (response.success) {
fst.log("showing lead status as: " + response);
$('#leadStatus').addClass('success').removeClass('error').fadeIn().delay(4000).fadeOut();
}
else {
fst.log("showing lead status as: " + response);
$('#leadStatus').text(response.messageBody).addClass('error').removeClass('success').fadeIn().delay('4000').fadeOut();
}
$('#startOver').click();
}
Which works fine if I call it in the console passing it the data the server is supposed to be socketing over:
// this works, gosh darn it
fst.showLeadStatus({ id: '00Qa000001FZfhKEAT', success: true, errors: [] });
The Salesforce post error case doesn't surface anything to the client either. And there are no errors in the client or server console to contend with.
I'm stumped. Please help!

I would do something like this -
var mysocket = null;
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
mysocket = socket;
socket.on('thanks', function (data) {
console.log(data);
});
});
app.post('/salesforce', function(req, res){
....
....
})
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
if(mysocket)
mysocket.emit('sfRes', resp);
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
if(mysocket)
mysocket.emit('sfRes', err);
}

Related

Is there a way to show "Loading data.." option in Rally Grid(ext JS) while making the Ajax request to load the data?

I am trying to set the message to "Data Loading.." whenever the data is loading in the grid. It is working fine if I don't make an Ajax call. But, when I try to make Ajax Request, It is not showing up the message "Loading data..", when it is taking time to load the data. Can someone please try to help me with this.. Thanks in Advance.
_loadData: function(x){
var that = this;
if(this.project!=undefined) {
this.setLoading("Loading data..");
this.projectObjectID = this.project.value.split("/project/");
var that = this;
this._ajaxCall().then( function(content) {
console.log("assigned then:",content,this.pendingProjects, content.data);
that._createGrid(content);
})
}
},
_ajaxCall: function(){
var deferred = Ext.create('Deft.Deferred');
console.log("the project object ID is:",this.projectObjectID[1]);
var that = this;
console.log("User Reference:",that.userref,this.curLen);
var userObjID = that.userref.split("/user/");
Ext.Ajax.request({
url: 'https://rally1.rallydev.com/slm/webservice/v2.0/project/'+this.projectObjectID[1]+'/projectusers?fetch=true&start=1&pagesize=2000',
method: 'GET',
async: false,
headers:
{
'Content-Type': 'application/json'
},
success: function (response) {
console.log("entered the response:",response);
var jsonData = Ext.decode(response.responseText);
console.log("jsonData:",jsonData);
var blankdata = '';
var resultMessage = jsonData.QueryResult.Results;
console.log("entered the response:",resultMessage.length);
this.CurrentLength = resultMessage.length;
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:resultMessage
});
this.pendingProjects = resultMessage.length
console.log("this testcase store:",resultMessage);
_.each(resultMessage, function (data) {
var objID = data.ObjectID;
var column1 = data.Permission;
console.log("this result message:",column1);
if(userObjID[1]==objID) {
console.log("obj id 1 is:",objID);
console.log("User Reference 2:",userObjID[1]);
if (data.Permission != 'Editor') {
deferred.resolve(this.testCaseStore);
}else{
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:blankdata
});
deferred.resolve(this.testCaseStore);
}
}
},this)
},
failure: function (response) {
deferred.reject(response.status);
Ext.Msg.alert('Status', 'Request Failed.');
}
});
return deferred;
},
The main issue comes from your Ajax request which is using
async:false
This is blocking the javascript (unique) thread.
Consider removing it if possible. Note that there is no guarantee XMLHttpRequest synchronous requests will be supported in the future.
You'll also have to add in your success and failure callbacks:
that.setLoading(false);

node.js - Socket IO times out after some time

I'm trying to build up a socket.io server for my own multiplayer game, but for some reason the server goes down after a certain amount of time and I don't know why. I have tried several ways to run the server (nodemon and forever, everything with or without screen). I don't think that this is an inactivity problem because I added a random stuff generator to simulate some activity on the server, yet the problem persists. My cpu load with the running server stays between 2-3 %. I'm running node 4.x and the current stable socket.io build (1.3.6).
And here is my code:
var shortId = require('shortid'),
io = require('socket.io')(process.env.PORT || 4567),
mysql = require('mysql'),
connection = mysql.createConnection({
host: 'localhost',
user: 'xxx',
password: 'xxx',
database: 'xxx'
});
var clients = [];
var clientLookup = {};
//Placed Components (builded stuff from players or enviroment)
var placed_components = 'Server1_PlacedC';
connection.connect(function (err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
});
setInterval(function () {
var random = Math.random();
//connection.query(
// 'INSERT INTO '+placed_components+' SET ?',
// {data:countdown},
// function(err,result){
// if (err) throw err;
// }
//);
console.log(random);
}, 100);
io.on('connection', function (socket) {
var currentClient;
console.log('connected', socket.id);
//////////////////////////////////////////////////////////////////////////////
socket.on('disconnect', function () {
console.log('player disconnected', currentClient.id);
socket.broadcast.emit('disconnected', currentClient)
var index = clientLookup[currentClient.id];
clients.splice(index, 1);
})
///////////////////////////////////////////////////////////////////////////// /
socket.on('register', function (data) {
currentClient = {
id: shortId.generate(),
health: 100,
isDead: false
};
console.log('registering', currentClient.id);
clients.push(currentClient);
clientLookup[currentClient.id] = currentClient;
socket.emit('registerSuccess', {id: currentClient.id});
socket.broadcast.emit('spawn', {id: currentClient.id});
console.log('connected players', clients.length);
clients.forEach(function (client) {
if (currentClient.id == client.id)
return;
socket.emit('spawn', {id: client.id});
console.log('sending spawn to new player for playerid', client.id);
})
});
socket.on('beep', function () { // Beep Request
socket.emit('boop');
console.log("received some beep!");
});
socket.on('move', function (data) {
data.id = currentClient.id;
socket.broadcast.emit('move', data);
//console.log(JSON.stringify(data));
});
socket.on('ShareObject', function (data) {
data.id = currentClient.id;
socket.broadcast.emit('ReveiveObject', data);
console.log(JSON.stringify(data));
});
socket.on('SharePlayerAnimation', function (data) {
data.id = currentClient.id;
socket.broadcast.emit('BroadcastPlayerAnimation', data);
console.log("a Player changed his animation" + JSON.stringify(data));
});
//////////////////////////////////////////////////////////////////////////////
socket.on('benchmark', function (data) {
console.log(data);
});
//////////////////////////////////////////////////////////////////////////////
})
console.log('server started');

Can't update a single doc in Mongo with Node

Hopefully someone can point out my error here.
In my app a user clicks on a button to insert a doc into the database. When they click on another button, a timestamp is added to an array.
Here's the code to create the doc (it works):
// Add User
function addUser(event) {
event.preventDefault();
ident = makeWords(2);
var newUser = {
'ident' : ident,
'group': '',
'timestamps': [],
'date_created': Date()
}
// Use AJAX to post the object to our adduser service
$.ajax({
type: 'POST',
data: newUser,
url: '/users/adduser',
dataType: 'JSON'
}).done(function( response ) {
if (response.msg === '') {
console.log('user added');
} else {
alert('Error');
}
});
};
And here's the route which handles it:
/*
* POST to adduser.
*/
router.post('/adduser', function(req, res) {
var db = req.db;
var collection = db.get('testcol'); //'testcol' is the name of my collection
collection.insert(req.body, function(err, result){
res.send(
(err === null) ? { msg: '' } : { msg: err }
);
});
});
I kind of thought that updating a doc would be just as easy. I'm grabbing the doc by the ident field, which will be unique to each user. However, I can't seem to make the client-side stuff pass to the server. Here's my client-side update:
function addError(event) {
event.preventDefault();
// If it is, compile all user info into one object
var errorUpdate = {
'$push': {'error_button': Date()}
}
// Use AJAX to post the object to our adduser service
$.ajax({
type: 'PUT',
data: errorUpdate,
url: '/users/errorUpdate',
dataType: 'JSON'
}).done(function( response ) {
if (response.msg === '') {
console.log("update sent, didn't receive an error");
}
else {
alert('Error');
}
});
};
This code executes, but the server-side just throws 500s. Here's that function:
/*
* update mongo doc
*/
router.put('/errorUpdate', function(req, res) {
var db = req.db;
var collection = db.get('testcol');
collection.update({'ident': ident},req.body, function(err, result){
if (err) {
console.log('Error updating menu: ' + err);
res.send({'users.js: error':'An error has occurred'});
} else {
console.log('doc has been updated');
res.send(item);
}
});
});
Any idea where I'm going wrong?
I solved this and it was a really really stupid mistake.
You might notice in my server-side code I use a variable called ident:
router.put('/errorUpdate', function(req, res) {
var db = req.db;
var collection = db.get('testcol');
collection.update({'ident': ident},req.body, function(err, result)...
ident is a global variable from my client-side stuff (global.js, which makes the ajax call), and it never made it to the server.
Further, I tried to send the Mongo update statement with the ident variable, which is totally unnecessary and just caused headaches.
Here's how I fixed it. This is client-side (where I only send the ident variable):
function addError(event) {
event.preventDefault();
// If it is, compile all user info into one object
var identifyMe = {
'ident': ident
}
// Use AJAX to post the object to our adduser service
$.ajax({
type: 'POST',
url: '/users/errors',
data: identifyMe,
dataType: 'JSON'
}).done(function( response ) {
// Check for successful (blank) response
if (response.msg === '') {
console.log('update sent, no errors received');
}
else {
console.log('Error detected. Response was: ' + response);
}
});
};
... and this is server-side, where I take that identifier and do the update (this works because all I'm doing is inserting a time stamp):
router.post('/errors', function(req, res) {
console.log(req.body);
var identifier = req.body.ident;
var db = req.db;
var collection = db.get('testcol');
collection.update({'ident': identifier}, {$push: {'error_button': Date()}}, function(err, result){
res.send(
(err === null) ? { msg: '' } : { msg: err }
);
});
});
You might notice that I'm pulling out that ident variable from the JSON that's being passed, with req.body.ident.
Hope this helps someone else struggling with updating a Mongo doc by posting to Express routes via Ajax with Node! :)

How can I handle a ajax request response in the Flux Architecture?

Looking at the Flux Documentation I can't figure out how the code to a ajax update, and a ajax fetch would fit into the dispatcher, store, component architecture.
Can anyone provide a simple, dummy example, of how an entity of data would be fetched from the server AFTER page load, and how this entity would be pushed to the server at a later date. How would the "complete" or "error" status of request be translated and treated by the views/components? How would a store wait for the ajax request to wait? :-?
Is this what you are looking for?
http://facebook.github.io/react/tips/initial-ajax.html
you can also implement a fetch in the store in order to manage the information.
Here is an example (it is a concept, not actually working code):
'use strict';
var React = require('react');
var Constants = require('constants');
var merge = require('react/lib/merge'); //This must be replaced for assign
var EventEmitter = require('events').EventEmitter;
var Dispatcher = require('dispatcher');
var CHANGE_EVENT = "change";
var data = {};
var message = "";
function _fetch () {
message = "Fetching data";
$.ajax({
type: 'GET',
url: 'Url',
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = error;
MyStore.emitChange();
}
});
};
function _post (myData) {
//Make post
$.ajax({
type: 'POST',
url: 'Url',
// post payload:
data: JSON.stringify(myData),
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = "update failed";
MyStore.emitChange();
}
});
};
var MyStore = merge(EventEmitter.prototype, {
emitChange: function () {
this.emit(CHANGE_EVENT);
},
addChangeListener: function (callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getData: function (){
if(!data){
_fetch();
}
return data;
},
getMessage: function (){
return message;
},
dispatcherIndex: Dispatcher.register( function(payload) {
var action = payload.action; // this is our action from handleViewAction
switch(action.actionType){
case Constants.UPDATE:
message = "updating...";
_post(payload.action.data);
break;
}
MyStore.emitChange();
return true;
})
});
module.exports = MyStore;
Then you need to subscribe your component to the store change events
var React = require('react');
var MyStore = require('my-store');
function getComments (){
return {
message: null,
data: MyStore.getData()
}
};
var AlbumComments = module.exports = React.createClass({
getInitialState: function() {
return getData();
},
componentWillMount: function(){
MyStore.addChangeListener(this._onChange);
},
componentWillUnmount: function(){
MyStore.removeChangeListener(this._onChange);
},
_onChange: function(){
var msg = MyStore.getMessage();
if (!message){
this.setState(getData());
} else {
this.setState({
message: msg,
data: null
});
}
},
render: function() {
console.log('render');
return (
<div>
{ this.state.message }
{this.state.data.map(function(item){
return <div>{ item }</div>
})}
</div>
);
}
});
I hope it is clear enough.

Load chat messages upon page load using websockets on node.js

Hi I'm developing a chat application using nodejs I'm new to node so I'm not very well familiar on its capabilities... I have made my application store its chat messages on mysql database only but I need to also display the past message and current one of a user here is the index.js
var mysql = require('mysql');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var validator;
var connection = mysql.createConnection({ // setup the connection
host : "localhost",
user : "root",
password: "",
})
function getStdout(command, args, fn) {
var childProcess = require('child_process').spawn(command, args);
var output = '';
childProcess.stdout.setEncoding('utf8');
childProcess.stdout.on('data', function(data) {
output += data;
});
childProcess.on('close', function() {
fn(output);
});
}
app.use('/assets', require('express').static(__dirname + '/assets'));
app.use('/temp', require('express').static(__dirname + '/temp'));
app.get('/', function(req, res){
//res.sendfile(__dirname + '/' +validator);
res.send(validator);
});
//you should have only one io.on('connection')
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
var myMsg= msg; // obtain the incoming msg
var strQuery = "INSERT INTO chat_storage(chat) VALUES(?)"; // your SQL string
connection.query("use schat"); // select the db
connection.query( strQuery, myMsg, function(err, rows){
if(err) {
// handle errors
} else {
io.emit('chat message', msg);
// message received
}
});
});
});
getStdout('php', ['message.php'], function(output) {
validator = output;
//start your server after you get an output
http.listen(3000, function(){
console.log(validator);
});
});
now here is the page for loading the chat messages
<?php startblock('script') ?>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(document).ready(function(){
$.ajax({
url: "localhost:3000/includes/message/store_chat.php",
type: "POST",
dataType: "html",
success: function (result) {
$("#messages").html(result);
}
});
});
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>
<?php endblock(); ?>
My idea was to the chat messages once the page loads I was trying to achieve it using ajax as you can see on the script that I have provided.. but it was no good didnt work at all Please help me
Couple of suggestions:
1) Store all of your messages in-memory ( unless you see this growing to several MB of data ) so that you can catch up any new client quickly.
2) Use socket.io to send the chat messages that have been stored rather than an AJAX call.
I've also included SequelizeJS instead of raw MySQL - It has a much cleaner raw query model and allows you to transition into a DAO model of sorts if you want to.
app.js
// Highly suggest replacing raw mysql with SequelizeJS - http://sequelizejs.com/
var Sequelize = require('sequelize'),
app = require('express')(),
http = require('http').Server(app),
io = require('socket.io')(http);
var validator;
var messages = [];
var sequelize = new Sequelize('schat', 'root', '');
app.use('/assets', require('express').static(__dirname + '/assets'));
app.use('/temp', require('express').static(__dirname + '/temp'));
app.get('/', function(req, res){
res.send(validator);
});
io.on('connection', function(socket){
// Send all previously sent messages
for( i in messages ) {
socket.emit('chat message', messages[i]);
}
socket.on('chat message', function(msg){
console.log('message: ' + msg);
// Push the message into the in-memory array.
messages.push(msg);
// Storage the message for when the application is restarted.
sequelize.query('INSERT INTO chat_storage(chat) VALUES("'+msg'")').success(function() {
// Insert was successful.
}).error(function (err) {
// Error inserting message
});
// Send the message to everyone
socket.broadcast.emit('chat message', msg);
});
});
function getStdout(command, args, fn) {
var childProcess = require('child_process').spawn(command, args);
var output = '';
childProcess.stdout.setEncoding('utf8');
childProcess.stdout.on('data', function(data) {
output += data;
});
childProcess.on('close', function() {
fn(output);
});
}
// Load Messages
sequelize.query('SELECT chat FROM chat_storage').success(function (rows) {
for( i in rows ) {
messages.push(rows[i].chat);
}
getStdout('php', ['message.php'], function(output) {
validator = output;
http.listen(3000, function(){
// Start server.
});
});
}).error(function (err) {
// Error!
});
php include
<?php startblock('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());
$('#messages').append($('li').text($('#m').val()));
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
<?php endblock(); ?>

Resources