I am using Locomotive framework for creating a nodejs web-application.
In config/environments/all.js I have:
var express = require('express')
, poweredBy = require('connect-powered-by')
, util = require('util')
, connectAssets = require('connect-assets')
, redis = require('redis')
, RedisStore = require('connect-redis')(express)
, sessionStore = new RedisStore();
........
........
this.use(express.cookieParser());
this.use(express.bodyParser());
..........
..........
this.use(express.session({
secret: 'LoremIpsumDolorSit_Amet',
store: sessionStore
}));
However the session object is not present in the request object. ie. in a controller instance:
this.req.session is undefined. What am I missing and How do I configure the connect-session middleware to use redis data-store ?
My redis server is running on default port and it shows a client connected when I run my server. The client gets disconnected only when I terminate the server.
I am using Node 0.6.18, redis server version 2.4.8, locomotive version 0.3.3 and express 3.0.4 on Fedora 16.
For sessions to work in express, the three of the following must be in this very order:
this.use(express.cookieParser());
this.use(express.session(...));
this.use(this.router);
In my implementation, I had the third statement above the second.
Apparently, this is a known idiosyncrasy with Express and I am not informed enough about the inner workings of Express to explain why this is the case. Probably someone who has more experience with NodeJS can elaborate on the details.
With this.use(), you add middleware to Express' request/response handling: incoming requests pass through all middleware before ending up at your application, and outgoing responses go back up the middleware chain before being sent back to the client.
The order in which you install middleware matters: if you have one middleware (like express.session) which depends on another middleware (like express.cookieParser, to parse session cookies), you install the dependency first.
In most cases, this.router should be installed last, or almost last (usually followed by an error handling middleware), because it depends on cookies and sessions having been handled before it get called.
Related
I am new to js and I am trying to develop a simple node.js-mysql app. No matter what I do I can't get the standard
var express = require("express");
statement to work.
I have installed node.js and express correctly, express is in package.json. I have a local server running. But this simple line will not work.
On the node.js side at Windows command line I have no error but when I go to localhost:3000 on the browser, I get
'Uncaught Error: Module name "express" has not been loaded yet for
context: _. Use require([])' error at js console.
I tried changing it to
require(['express']`, function (express) {}
as suggested at node.js web site but then at the Windows command terminal I get a different error saying like
'expecting a string but received an array....'.
I have tried import instead of require and I have tried every suggestion that I could find on the Internet. I have been blowing my brains for weeks to get this to work with no success. I am so frustrated that I am seriously thinking about giving up all together. If someone can help I will be forever greatfull to him/her.
My main js code is as follows:
var port = 3000;
// Import or load node.js dependency modules.
var express = require("express");
var app = express();
var path = require("path");
var bodyParser = require("body-parser");
app.use(express.urlencoded({ extended: true })); // to support URL-encoded bodies.
app.listen(port, () => {
console.log(`server is running at http://127.0.0.1:8887`);
});
app.get('/', function(req, res){
res.sendFile("D:/Behran's files/Web projects/havuzlusite/index.html");
});
Require.JS is for loading AMD modules (and is, honestly, obsolete in today's JS landscape).
Node.js modules are either ECMAScript modules (which use import and export) or CommonJS modules (which use require and module.exports).
Even though both AMD and CommonJS modules use a function named require they are not compatible.
There are methods you can use to run ES modules and CommonJS modules in the browser however they can't replace APIs that are provided by runtimes.
Express.js needs to be able to listen for incoming HTTP requests. Browsers do not provide any mechanism to make that possible. Node.js does.
If you want to run Express.js you have to run it using Node.js and not a browser.
Express.js creates an HTTP server. A browser can make requests to it (e.g. if you type http://127.0.0.1:3000 into the address bar.
(Your code says server is running at http://127.0.0.1:8887 but the port constant is set to 3000).
All your Express.js code must run through Node.js.
You can't send a copy of that code to the browser and run it there too.
I have used socket.io, Node.JS, and express to create a real-time chat application that I could view by creating a local server. However, instead of using a local server, I would like to point my client to an existent heroku service. How do I go about doing this?
When I do the following,
var spot = io("https://spotim-demo-chat-server.herokuapp.com");
all functions relating to connecting, disconnecting, username registration, and messaging seem to fail. They do not function in the chat nor do their console.log messages appear in terminal.
I have also considered creating a HTTP server and having it listen to the port and IP address of the heroku service with .listen(). However for my assignment, I was not provided with either of these values, simply the heroku url.
I'm not sure where you're having trouble without more code from you. I've setup a basic socket.io client as follows and can connect without issue. You can run it with the following to see just the client's messages DEBUG=spot-client node client.js or if you wish to see all the debug info from the socket client itself as well DEBUG=* node client.js. The latter might help you diagnose the issue further. Also be sure to install the socket.io-client and debug packages. Hope this helps!
const io = require('socket.io-client');
const debug = require('debug')('spot-client');
var spot = io("https://spotim-demo-chat-server.herokuapp.com");
spot.on('connect', function(){
debug("connected");
});
spot.on('event', function(data){
debug("event",data);
});
spot.on('disconnect', function(){
debug("disconnect");
});
This must be an extremely common problem. I've seen various answers for this but none seem to work for me.
I have node installed on an apache server on Windows Azure. My app is built and ready to go (snippet below):
var express = require("express");
var app = express();
//example api call
app.get("/api/example", function(req, res){
//do some process
res.send(data);
});
app.listen(8080);
console.log("App listening on port 8080");
Now, when testing on my own computer, I could then go to localhost:8080, which works great. But now I've put it on the azure server I can't get an external domain to point to it properly. So for example, I have the domain:
framework.example.com
I've added this to my hosts file in Azure:
XXX.0.0.01 framework.example.com
Initially I tried also editing the http-vhosts.conf to point the domain to the correct directory. This worked for loading the frontend, but the app couldn't talk to the backend. API calls returned 400 not found errors.
I've also tried an Express vhost method but think I'm doing it wrong and don't fully understand it. What is the correct method?!
My app structure is like this:
- package.json
- server.js
- server
- files used by server.js
- public
- all frontend files
So to boot the server I run server.js which runs the code at the top. The server.js uses the below Express config to point to the public folder.
app.use(express.static(__dirname + "/public"));
Adding it to the hosts file in Azure won't help. You'll need to configure your domain's DNS to point to Azure. I'd recommend using the DNS Name of your Cloud Service instance. Your underlying VM IP address could change if you need to stop it for some reason, but your Cloud Service DNS name is configured to always route to your underlying VMs. That means you'll need to setup a CNAME with your DNS.
Read more about that here: Cloud Services Custom Domain Name
Next, you'll either need to host the node app on port 80, or put a proxy in front of it to handle that for you. Otherwise you'll be stuck typing framework.example.com:8080 which is not ideal. On linux, you'll likely need to be a privileged user to host on port 80, but you never want your node app to have root privileges. You can use authbind to work around this problem.
See an example of how to use it with node here: Using authbind with Node.js
All that being said, it seems like you're somewhat new with linux server management. If that's the case, I'd strongly recommend trying to use something like Azure Websites instead of a VM. You no longer have to manage the virtual machine OS. You simply tell it to host your application and it takes care of the rest. If you're using github, this is incredibly easy to test and iterate with. It does host on Windows under the hood, and that might problems for some applications, but I host all my node sites there (developed on Mac) without any issues.
Please be gentle with me. I'm new to async coding and have been thrown headfirst into an intensive project using node to develop and API server. I'm loving it but some things aren't coming naturally.
Our project is built using express js. We have a file, server.js where we instantiate an express server which in turn instantiates our router and so on. I need to integration test this now (partially) complete server. Normally what I do is from the command line run '%node server.js' and then using either python requests or curl make requests and check the responses.
Now I've been tasked with writing a unit and integration test suite so that we can automate our testing going forward. I've been using mocha and now am trying to use supertest for the integration testing. The problem is that supertest expects a server object which it then applies tests to however our file that builds our server object doesn't return anything. I don't want to modify that file so I am stumped as to how to access the server object to use for testing.
My server file looks (in part) like this:
var express = require('express')
var app = express();
// Express Configuration
app.use(express.favicon()); //handles favicon request, which keeps it out of the log when using a browser :)
app.use(express.bodyParser()); //slurps up the body in chunks the node.js way :)
// ...and so on
and my mocha test file looks like this
var request = require('supertest')
, app = require('../server.js')
, assert = require("assert");
describe('POST /', function(){
it('should fail bad img_uri', function(done){
request(app)
.post('/')
.send({
'img_uri' : 'foobar'
})
.expect(500)
.end(function(err, res){
console.dir(err)
console.dir(res)
done();
})
})
})
when I run this test I get a complaint about the app object not having a method named address. My question is, is there a way I can require/call the server.js file so that the app object will be in scope? Or am I going about this wrong. I also played around a little bit with using http.js to make calls directly to the server but didn't have luck that way either. Thanks!
You need to export the app object in server.js:
var app = express();
module.exports = app;
...
Is there a good way of using sessions with Socket.io in Express 3.0? A way of getting the clients' session id in a safe way? So that I can send notices to members specific to their account and make private chats from member to member?
I'm using MySQL store in Express 3.0
I wrote a tiny module to abstract it, here's how its usage looks like. It was written and tested using express 3, socket.io 0.9.10 and the (default) MemoryStore from connect 2.4.5. It should work fine with other compatible stores.
var SessionSockets = require('session.socket.io')
, sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
//your regular socket.io code goes here
});
For more details on how it works see https://github.com/wcamarao/session.socket.io
You might want to pay attention to the part of the README where it says how to use it with your own session store key (I'm assuming your mysql store uses a name other than the default 'connect.sid').
You should check out express.io, a very simple micro-framework for express and socket.io integration. It handles express and socket.io sessions automatically.
npm install express.io
Check out the session support example here:
https://github.com/techpines/express.io/tree/master/examples#sessions
I did something slightly different to get it working. I read through a lot of posts on nodester github and came with the following solution....
Replace:
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
with:
var server = http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
var io = require('socket.io').listen(server);
My plan is to continue with this workaround until issues around express3 and socket.io are resolved.