socket.io is not consistently connecting - angularjs

I've just added socket.io to my MEAN stack app. It's not consistent in its connections. This is what I get when I fire up the server and connect through a browser:
GET /socket.io/?EIO=3&transport=polling&t=LTnYzIi 200 1.948 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnYzJL 404 1.617 ms - 66
GET /socket.io/?EIO=3&transport=polling&t=LTnYzrU 200 1.612 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnYzs6 404 1.974 ms - 66
GET /socket.io/?EIO=3&transport=polling&t=LTnY-jT 200 1.652 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnY-kE 404 0.975 ms - 66
However, if I stop the server and restart it the moment the browser makes the request (in the background), the client connects and it works fine. It really has to connect everytime there's a communication right?Please tell me what I'm missing.
Here's my package.json socket.io call:
"socket.io": "^1.4.6"
My app.js looks like this:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator')
var mongodb = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/newphase1");
var async = require('async');
var config = require('./config.js');
var routes = require('./routes/index');
var api = require('./routes/api');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(favicon(__dirname + '/public/favicon(4).png'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '/public')));
app.use(expressValidator({
errorFormatter: function(param, msg, value){
var namespace = param.split('.'),
root = namespace.shift(),
formParam = root;
while(namespace.length){
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg:msg,
value:value
};
}
}));
var api = require('./routes/api')(app,express,io);
app.use('/api', api);
app.get('*',function(req,res){
res.sendFile(__dirname + '/public/views/index.html');
});
io.on('connection', function(socket) {
console.log('client connected!');
});
http.listen(config.port,"127.0.0.1",function(err){
if(err){
console.log(err);
}else{
console.log('listening on port 3000');
}
})
My socket.io script file (from CDN) in my index.js(angular):
<script src="https://cdn.socket.io/socket.io-1.4.6.js"></script>
My service for socket.io:
.factory('socketio',function($rootScope){
var socket = io.connect("http://localhost:3000");
return {
on: function(eventName,callback){
socket.on(eventName,function(){
var args = arguments;
$rootScope.$apply(function(){
callback.apply(socket,args);
});
});
},
emit: function(eventName,data,callback){
socket.emit(eventName,data,function(){
var args = arguments;
$rootScope.apply(function(){
if(callback){
callback.apply(socket,args);
}
});
});
}
}
});
It does get connected, but not consistently. Any ideas?

For some reason
npm start
gave me the above inconsistency while
node app.js
works fine.

Related

Why is my react router not passing my express route to server?

I tried to add social login to my (already working) react/express app, and I got it working in localhost. However, when I deploy it to production, the social login doesn't work. This is how it gets started
Google+
However, in production, it stays at https://sample.com/api/auth/google in my browser. So, it appears the react router is catching it first before express. How?
In localhost, it works because the proxy in package.js
"proxy": {
"/api": {
"target": "http://localhost:4000",
"ws": true
}
Now, how can I do this for production?
By the way, all my server APIs starts with '/api/...'. Also, in my react routes, I don't have a catch-all component.
UPDATE:
Here is my server.js
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var cookieParser = require('cookie-parser');
var path = require('path');
var fs = require('fs');
var app = express();
var isSecured = true;
app.isDevMode = app.get('env') == 'development'
require('./server/config/log')(app)
var port = (process.env.PORT || app.isDevMode) ? 4000 : (isSecured ? 443 : 80);
app.set('port', port);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ limit: '10mb' }));
app.use(flash()); // use connect-flash for flash messages stored in session
var server = require('http').createServer(app);
if (!app.isDevMode && isSecured) {
var options = {
ca: fs.readFileSync('ca_bundle.crt'),
key: fs.readFileSync('private.key'),
cert: fs.readFileSync('certificate.crt')
}
server = require('https').createServer(options, app);
}
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log('Connected to MongoDB');
var routes = require('./server/routes');
routes.init(app);
if (app.isDevMode) {
app.use(express.static(__dirname));
}
else {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
if (isSecured) {
require('http').createServer(function (req, res) {
res.writeHead(307, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
}
}
server.listen(app.get('port'), function () {
console.log('Server listening on port ' + app.get('port'));
});
});
module.exports = app;
Here is my routes:
app.get('/api/auth/google', passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'] }))
app.get('/api/callback/google', passport.authenticate('google', {successRedirect: '/?action=login&provider=google', failureRedirect: '/?action=login'}))
UPDATE:
Here is the morgan log. I added a number for each line for my reference. Line 4 started when I click the link to send '/api/auth/google', and finished at line 6.
1. GET /api/get/list?parm={%22kind%22:%22Prod%22,%22limit%22:5,%22createdOn%22:-1} 304 - - 22.959 ms
2. GET /images/logo.png 200 3432 - 17.410 ms
3. GET /service-worker.js 200 3097 - 3.398 ms
4. GET /static/js/main.cef8cdac.js 304 - - 5.180 ms
5. GET /images/two.png 304 - - 4.908 ms
6. GET /service-worker.js 200 3097 - 3.838 ms
So, basically, the request didn't come to express server. Actually, if I had a catch all route in react, I can see it's hitting there.
Here is the network log:

Angular 4 Node Mssql

I am a newbie when it comes to web development . I am currently working to get a real time web project up and running . I have a ms sql server 2014 working in my workplace and have installed node.js/ and used express generator to generate out an application . I have used mssql node module to connect and retrieve data from mssql server and it works.Although, Things that are confusing to me at this point:
how do i add angular 4 into the equation to help with the frontend development?i have already done npm install --save anular/cli but do not know where to start regarding creating input forms with drop downs whose values are to retrived from the DB .
my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
my index.js (i tried to create a connection with myssql and display a table in the index.html jade file)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
GetData(function(recordset)
{
res.render('index', {projects: recordset })
});
});
function GetData(callback )
{
var sql = require ('mssql');
const config = {
user: 'sa',
password: 'password',
server: 'localhost\\SQLEXPRESS',
database: 'xxxxx',
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
var connection = new sql.Connection(config, function(err)
{
var request = new sql.Request(connection);
request.query('select * from Project_Type' , function(err, recordset)
{
callback(recordset);
});
});
}
module.exports = router;
Some more questions:
Is this the right place to start a sql connection ? or should i put in in the app.js file
and other advice as to how to setup the environment and angular to properly speak with the db would be highly appreciated.

data from my db returns partial content from my Restful API (206 partial content)...

im having a little problem with my M.E.A.N(mongo, express, angular, node) application, when i do a GET request from my node server, it displays on 10 items instead of all 21 that are in the mongo db. i did some search on google and i read stuff saying it had to do with my CORS set up on my servers side, but i still cant seem to figure it out... here's my code:
index.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var _ = require('lodash');
var cors = require('cors');
// Create the application.
var app = express();
//enable the use of cors
app.use(cors());
// Add Middleware necessary for REST API's
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
// CORS Support
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.models = require('./models/index');
// Load the routes.
var routes = require('./routes');
_.each(routes, function(controller, route) {
app.use(route, controller(app, route));
});
// Connect to MongoDB
var db = mongoose.connect('mongodb://localhost/isdbmeanapp');
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
mongoose.connection.once('open', function() {
// Load the models.
app.models = require('./models/index');
app.listen(3000);
console.log('Server running on localhost port 3000...');
});
i currently have 21 users(dummy data) in my database(mongodb) but when i run the above restangular query, it displays only 10 users. i also tried making requests with postman and thesame thing happens (with a 206 server status code).
im using restangular to make my requests:
Restangular.all('user').getList().then(function(user){
$scope.users = user;
});
please i need help in solving this problem... thanks in advance...

XMLHttpRequest cannot load [url] Response for preflight is invalid (redirect)

I'm making an ionic app for android and today I implemented a server side nodejs (express) Restful API with mongodb on cloud9.
But when I trigger a http request to the url, I keep getting the error mentioned in the title:
This is my angular http request on ionic (simply to test first):
app.controller('DashCtrl', function($scope, $http, $q) {
$http.get('https://[workspace]-[user].c9users.io/api/capture')
.then(function(result) {
console.log(result);
});
});
This is an image of my workspace:
I used the following code to make the database:
api.js
var Capture = require('../models/capture');
module.exports = function(router) {
router.get('/capture', function(req, res){
var capture = new Capture();
// capture.birdname = req.body.birdname;
// capture.place.city = req.place.body.city;
// capture.place.country = req.place.body.country;
capture.birdname = "Pigeon";
capture.save(function(err, data){
if(err)
throw err;
res.json(data);
});
});
router.get('/captures', function(req, res){
Customer.find({}, function(err, data){
res.json(data);
})
})
}
capture.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = mongoose.Schema({
birdname: String,
place: {
city: String,
country: String
}
});
module.exports = mongoose.model('Capture', captureSchema)
database.js
module.exports = {
'url': 'mongodb://' + process.env.IP
}
server.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
mongoose.connect(configDB.url);
var api = express.Router();
require('./server/routes/api')(api);
app.use('/api', api);
app.listen(process.env.PORT, process.env.IP);
console.log('Listening on port ' + process.env.PORT)
Anyone have an idea why I'm getting this error and what I need to do to fix this?
I'm guessing it has something to do with the server allowing me to send requests to the API though I don't know how to implement that.
Is there also a way to secure my database (API key maybe) and how would I implement this?
Thanks in advance

"SyntaxError: Unexpected token n" in Express Node Server

I get this error-
SyntaxError: Unexpected token n
at parse (/Users/afroza/node_modules/body-parser/lib/types/json.js:83:15)
at /Users/afroza/node_modules/body-parser/lib/read.js:116:18
at invokeCallback (/Users/afroza/node_modules/raw-body/index.js:262:16)
at done (/Users/afroza/node_modules/raw-body/index.js:251:7)
at IncomingMessage.onEnd (/Users/afroza/node_modules/raw-body/index.js:308:7)
at IncomingMessage.emit (events.js:104:17)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
I creating a route with nodejs and I'm getting this error,I've tried many things and there's no way, always appears this error,
my server setup in express framework-
var express = require('express');
var app = express()
, fs = require('fs')
, path = require('path');
var env = process.env.NODE_ENV || 'production'
, config = require('./config/config')[env]
, mongoose = require('mongoose');
var http = require('http');
var db = mongoose.connect('mongodb://localhost/orbitax');
app.use(express.static(__dirname + '/public'));
var bodyParser = require('body-parser'); // add body-parser for interact with server and client data
var jsonParser = bodyParser.json(); //join this body parser with json file
var urlencodedParser = bodyParser.urlencoded({ extended: false});
//Initialize Models
var models_path = __dirname + '/app/models'
fs.readdirSync(models_path).forEach(function (file) {
require(models_path+'/'+file)
});
require('./config/routes')(app,config);
var server = app.listen(9000, function(){
var host = server.address().address;
var port = server.address().port;
});
server routing,
var async = require('async')
, mongoose = require('mongoose')
, uploadModel = mongoose.model('uploadModel');
module.exports = function (app) {
// upload routes
var upload = require('../app/controller/upload');
app.get('/newUpload', upload.newUpload);
app.post('/create_new_directory', upload.create_new_directory);
}
exports.create_new_directory = function(req, res)
{
console.log("hello")
console.log(req.body);
}
and from client side request is,
$http({'method': 'post', 'url': '/create_new_directory', data: $scope.directory })
.success(function(data){
console.log(data)
})
.error(function(){
})
Any help would be appreciated, Thanks.
By default, the $http service will only transform request data to a JSON string if the data is an object.
https://github.com/angular/angular.js/blob/v1.4.8/src/ng/http.js#L292
In your case, the request data is a string so it is not getting wrapped in quotes, making it invalid JSON.
You should be able to modify your $http config like this:
$http({
method: 'POST',
url: '/create_new_directory',
data: $scope.directory,
transformRequest: JSON.stringify
}).success(function(data){
console.log(data)
})

Resources