Structure of Express application with Redis - node.js

I am unsure about where would be the best place to define the redis client in a Express application I am building. I am using skeleton as the framework.
It seems like the connection to redis should go in either boot.coffee or app.coffee, but then I can't easily get a reference to it in application_controller.coffee, which is where I need it.
If I put client = redis.createClient in application_controller.coffee, will that mean a new client is created on each request?

I would define the Redis client in app.coffee (after configuration, before the routes) and set the Redis client as a property on the App object:
app.client = redis.createClient
Then in application_controller.coffee you can access the Redis client by app.client.

Related

Get Websocket URL from Node js

I am trying to build a simple WebSockets app with node.js as a server. In order to create a WebSocket connection I write:
const url = 'ws://localhost:8080'
const connection = new WebSocket(url)
But I do not want to hardcode the URL. Can I receive it from my server?
Available options:
Using of Webpack/Rollup/Snowpack - https://dev.to/sanfra1407/how-to-use-env-file-in-javascript-applications-with-webpack-18df:
You can define a some .env and define address of server
Use dotenv or something another library on backend side to receive variable
Use Webpack/Rollup/Snowpack on frontend side to build frontend with defined address of server
It will allow to change address of server in one place
SSR (server-side rendering) - https://medium.com/jspoint/a-beginners-guide-to-react-server-side-rendering-ssr-bf3853841d55
You can provide address of server from backend to frontend

expressJS exporting other things in addition to app

In my web application (I'm using expressJS), there are many services (such as mongoDB connection, MQTT connection, etc.) that need to be executed once the whole application is executed (using npm start command). Therefore, I can make use of these services in my entire application. For example, I want to use my MQTT connection in different files.
My idea is to export the MQTT connection, MongoDB connection, etc. in addition to the app this way:
//app.js
module.exports = {
app: app,
mqttConnection: myMQTTConnection,
db: myMongoDB
};
However, we know that this approach doesn't work (I tested it and got an error saying: TypeError: app.set is not a function).
How can I export other things in addition to app from app.js file?
If my approach is not possible, what other approaches can I use? (considering the fact that many services (such as connecting to a server, etc.) are asynchronous)

node-amqp — proper way to handle connection in Express app?

I'm using Express with node-amqp. My goal is to create amqpConnection and save it to global object before server starts and in Express routes use previously created globals.amqp_connection.
### server.coffee
app.use( ... )
...
# create RabbitMQ connection before server starts
connection = require("amqp").createConnection
host: "localhost"
connection.on "ready", ->
console.log "Got connection.on(\"ready\") event from node-amqp..."
# make amqp_connection accessible from any point of application
globals.amqp_connection = connection
server = globals.http.createServer(app).listen(8082)
console.log "Express server is listening 8082..."
The problem is connection.on "ready"-event is fired eveytime I call a route. I may suppose that's because of Express way of serving http-requests — executing server.js for every route called. So, for every request, a new instance of connection is created and on it's "ready" app tries to create one more instance of Express server.
How to make amqp_connection accessible from any point of my app, but no doubling require("amqp").createConnection() in every point where I need to push something to RabbitMQ?
UPD: or maybe there is no problem with Express. node-amqp seems to fire ready event every second after creation. Don't know if it's correct behavior
Thank you.
Ready event fired multiple 'cause of connection error:
https://github.com/postwait/node-amqp/issues/255

access base http server of sails.js

Hi is there a way to access the base http server context of sails? I want to use binaryJS in my app and In the gettig started guide they are talking about creating the server at your own, it you have an existing express app with the following line:
var server = http.createServer(app).listen(9000);
than I could use the following binaryJS command:
// Create a BinaryServer attached to our existing server
var binaryserver = new BinaryServer({server: server, path: '/binary-endpoint'});
thank you
In Sails v0.10.x, you can access the underlying Express server with:
sails.hooks.http.server
in v0.9.x, it's
sails.express.server

Socket.io: Updating Chat Room when a new message is added to MongoDB database

I am creating a real time chat room. However unlike many other examples available, a single chatroom is only accessible to authenticated users, with whom the room is shared with using invitational based authentication.
Here are the steps:
1) Add User on invitation:
app.post('/shared', function(req, res){
Room.findOne({_id: req.body._id}. function(err,room){
new_shared = new Shared({room_id: req.body._id, user_id, req.body.user_id});
new_shared.save();
room.shared.push(new_shared);
room.save();
res.send(new_shared);
});
});
2) Once added to Shared, the user can realtime add messages to only the authenticated users in to room. How can we achieve that?
I am trying this:
app.post('/message', function(req,res,next){
// Save Message in Mongodb
//Emit a socket function - How do we initialize it within API?
}
3) On Client side, I am using Backbone JS. So once a new message is added, should I call .fetch() method on backbone to retrieve all messages.
I am relatively new to Socket.IO, so some of them might sound stupid.
From my point of view, mongodb and express have not great purpose in your chat application, socket.io instead carries all the burden.
first you should consider reconstructing the entire approach, you should try the following, for getting a clean result.
use a simple single route to login users such as /login so you can authenticate users using mongodb
to establish a connection to backend socket.io, try to serve the script which handles the connection
Since you use Backbone, try using a sync override, which uses socket.io instead of http requests Backbone.iobind
now finally the socket.io server which is attached to your expressjs server, should handle the rest
it should authenticate using expressjs sessions
it should handle connections and messages
there is a .room functionality built-in socket.io so there is no reason in using mongoDB and expressjs.
to sum it up, you could skip expressjs and make use of socket.io, http server, and mongodb if you store use credentials in database

Resources