I am creating a simple socket io application. I followed all tutorials online to implement socket-io via Node JS. The current code worked only once and after connecting to the socket it got disconnected automatically. Since then I tried all PnC but it has not connected server side.
Can anyone please help me identify what stupidity I have done? Also I do not understand that whether it is client side problem or library problem.
package.json
{
"name": "IntellicarMaps",
"version": "1.0.0",
"description": "Demo app showing the use of Google Maps for Intellicar",
"main": "server.js",
"author": "Prateek",
"dependencies" : {
"express" : "~4.7.2",
"mongoose" : "~4.1.0",
"morgan" : "~1.2.2",
"body-parser": "~1.5.2",
"jsonwebtoken": "^5.0.2",
"method-override": "~2.1.2",
"socket.io": "~1.4.8"
}
}
server.js
// Dependencies
// -----------------------------------------------------
var express = require('express');
var mongoose = require('mongoose');
var port = process.env.PORT || 3000;
var database = require('./app/config');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var app = express();
var server = require('http').createServer(app);
global.io = require('socket.io').listen(server);
//------------------
// Express Configuration
// -----------------------------------------------------
// Sets the connection to MongoDB
mongoose.connect(database.localtest.url);
// Logging and Parsing
app.use(express.static(__dirname + '/public')); // sets the static files location to public
app.use('/bower_components', express.static(__dirname + '/bower_components')); // Use BowerComponents
app.use(morgan('dev')); // log with Morgan
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.urlencoded({extended: true})); // parse application/x-www-form-urlencoded
app.use(bodyParser.text()); // allows bodyParser to look at raw text
app.use(bodyParser.json({ type: 'application/vnd.api+json'})); // parse application/vnd.api+json as json
app.use(methodOverride());
//----------
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// Routes
// ------------------------------------------------------
require('./app/routes.js')(app);
// Listen
// -------------------------------------------------------
//app.listen(port);
server.listen(port);
console.log('App listening on port ' + port);
//------------------------
// Socket io connection
//------------------------
io.on('connection', function(socket){
console.log('a user connected'); //this is not printing in console.
socket.emit('my other event', { my: 'data' });
//socket.on('disconnect', function(){
//console.log('user disconnected');
//});
});
io.emit('message',{"AlarmName":"CPU_FAN_DOWN"});
addForm.html(Client)
<script src="../lib/socket.io.js"></script>
<script>
var socket = io('http://localhost', {'force new connection': true});
socket.on('message', function (data) {
console.log(data);
});
</script>
socket.io.js in lib folder
this file is always loaded,i have checked in browser console
Related
I have the app.js code:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket){
socket.on('newRideAdded', function(exclude){
io.emit('newRideAdded', exclude);
});
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use(express.static(__dirname + '/public/'));
app.use('/rides', require('./routes/rides'));
app.use('/user', require('./routes/user'));
server.listen("8080", function() {
console.log("Connected to db and listening on port 8080");
});
And I want to move the socket io code to its router's page.
That is the router page:
var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs("ride4you", []);
router.post('/getRides', function(req, res, next) {
db.rides.find(function(err, docs) {
res.json(docs);
});
});
// rest of the restapi in this page.
// I want socket code to be here
module.exports = router;
As you can see i have each socket emits in each router's page and I already have module.exports in routers page.
How can it be done?
Thanks.
Using Express 4, in your app.js file you can use
app.set('socketio', io);
Then in your router or controller, you can use
router.post('/getRides', function(req, res, next) {
var io = req.app.get('socketio');
io.to(//socket.id//).emit("message", data);
db.rides.find(function(err, docs) {
res.json(docs);
});
};
This is a clean way of passing the reference along.
My app.js
const express = require('express'),
morgan = require('morgan'),
bodyParser = require('body-parser'),
path = require('path'),
mongoose = require('mongoose'),
app = express(),
config = require('./config'),
Note = require('./models/note'),
server = require('http').createServer(app),
io = require('socket.io')(server),
socket = io.socket;
mongoose.connect('mongodb://'+config.db.host+'/'+config.db.name);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));
app.use(function(req, res, next) {
const allowedOrigins = [
'http://127.0.0.1:8000',
'http://localhost:8000',
'http://127.0.0.1:3000',
'http://localhost:3000'];
const origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
//res.header("Access-Control-Allow-Origin", "127.0.0.1 localhost");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Credentials', true);
next();
});
calling socket.emit() in handlers after above codes.
My index.js
'use strict';
const app = require('./app'),
// server = http.createServer(app),
PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log(`REST API running on ${PORT}!`);
});
Console output:
Any idea? Thanks
If you're going to do this:
server = require('http').createServer(app),
Then, you can't do:
app.listen(PORT, ...);
because app.listen() will create a new and different server and socket.io will not be associated with that one.
Instead, you need to do:
server.listen(PORT, ...)
using the server value from app.js. And, if you want to require() in the server from app.js, you also need to export it from app.js (something else I don't see your code doing).
For reference, the code for app.listen(), does this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
You can see how it creates a different server than the one you passed to socket.io. Thus the one you passed to socket.io is never started and thus socket.io does not work.
I have made a rest api for my ionic-2 android app but my http request cannot get data from my rest api service
I made a rest api with node.js and source code here
server.js
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
extended:true
}));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
router.get('/',function(req,res){
res.json({
"message":"hello world"
});
});
app.use('/api',router);
app.listen(port);
console.log("Listening Port");
package.json
{
"name": "node-api",
"main": "server.js",
"dependencies": {
"express": "~4.0.0",
"mongoose": "~3.6.13",
"body-parser": "~1.0.1"
}
}
I pushed on heroku service and its address here
my heroku rest api link
My ionic2 app from another directory here
home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
data:any;
constructor(public navCtrl: NavController,http:Http) {
http.get("https://appish.herokuapp.com/api")
.map((res) =>res.json())
.subscribe((data)=>{
this.data = JSON.stringify(data);
})
}
}
home.html
<ion-header>
<ion-navbar>
<ion-title>
Api
</ion-title>
</ion-navbar>
<ion-content padding>
{{data}}
</ion-content>
When I run this code with 'ionic serve' there is no error and no data but if I try other json sites to get data,it is running for example
i am trying ip.jsontest.com
I can get data
Where is the problem
Thank You
~
This looks like a CORS issue.
Try adding this to the beginning of your server.js and see if it resolves your issue.
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
If that doesn't work, you should take a look at the network tab in your browsers debugging tool. If you get a response and can see the data, it is an error in your ionic code. If you don't get any data, it's a problem with your server code or with the connection to the server.
Replaced server.js
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
extended:true
}));
//answer is here..
app.use(function(req,res,next){
res.header("Access-Control-Allow-Origin","*");
res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
next();
});
///
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
router.get('/',function(req,res){
res.json({
"message":"hello world"
});
});
app.use('/api',router);
app.listen(port);
console.log("Listening Port");
I'm having issues deploying my app on Heroku. I keep getting a screen in my browser saying Application Error. From what i've read this is something with MongoLab.
I have set my PROCESS.ENV.MONGOLAB_URI correctly on heroku and I can't get it to work. I have also tried adding a new user to MongoLAB for this DB and even that user won't work as well.
I am Process.env.PORT because I am using Socket.io. Is it something in my app.js?
var express = require('express');
var http = require('http')
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect(process.env.MONGOLAB_URI || 'mongodb://localhost/queueThat');
var db = mongoose.connection;
var routes = require('./routes/index');
var app = express();
var server = http.createServer(app);
//Stuff for Sockets
var io = require('socket.io').listen(server);
//sockets
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);
// 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('/', routes);
//Connect to the Socket
io.on('connection', function(socket){
socket.on('song send', function(song){
io.emit('song send', song)
console.log('artist on')
})
socket.on('artist send', function(artist){
console.log('artist on')
io.emit('artist send', artist)
})
//Disconnect
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
// 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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
var port = (process.env.PORT || 8000);
server.listen(port, function() {
console.log("Listening on " + port);
});
module.exports = app;
I have also tried adding my node and NPM versions to no avail. Any ideas? Package.json looks like this.
{
"name": "queueThat",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"ejs": "^2.3.4",
"express": "~4.13.1",
"mongoose": "*",
"morgan": "~1.6.1",
"serve-favicon": "~2.3.0",
"socket.io": "*"
},
"engines": {
"node": "5.4.0",
"npm": "3.3.12"
}
}
Application Error doesn't mean that there is something wrong with MongoLAB, not necessarily.
To be clear you need to double check few places:
You need to have proper Procfile in the root folder of your project
Be aware of postinstall npm script.
Also you could check your logs on heroku heroku logs -n 200 (200 or more lines if needed) to be sure what's the problem you have.
I am trying to create an Express app with Socket.IO. It seems like Express has changed quite a lot and most of the code online about getting the 2 to work together is out of date. This is what I have:
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 routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io').listen(http);
io.on('connection', function(socket){
console.log('a user connected');
});
// 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(__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('/', routes);
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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
The server starts ok and says
info - socket.io started
However the front-end has a 404 error on http://example.com:3000/socket.io/socket.io.js
edit
If I add
http.listen(8080);
The server runs twice on port 3000 and 8080, the 3000 version does not load socket.io.js and the 8080 version does. How can I have it so the server is only running on 3000? changing it to 3000 errors and it tries to listen twice
The answer was to make the changes in bin/www.js instead of app.js
#!/usr/bin/env node
var debug = require('debug')('test1');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var http = require('http').Server(app);
var io = require('socket.io')(http);
var server = http.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
Change the io include to:
var io = require('socket.io')(http);
And towards the bottom add something like:
http.listen(3000, function() {
console.log('Listening on port %d', http.address().port);
});