A strange feature of node.js - javascript

Noticed a strange feature of node.js.
For example:
Let's say, I've got some variable on node.js server: var user_id = '1';, in which the stored user id which is connected to the server.
user1 have var user = 1;
user2 have var user = 2;
...
user99 have var user = 99;
But if at some point I will demand from the server variable user - I will return the id of the last user who rewrote her.
Is that right? So it should be?
I thought, node.js for each user creates a flow/process ...
Thanks for your answer!
index.js
dNode({
connect: function(data, callback) {
IM.iUserId = data.user_id;
IM.start();
}
});
im.js
var IM = {
iUserId: false,
start: function() {
console.log(this.iUserId);
}
};

It seems like you have one global IM objects that all of your connections are sharing.
You can set/get a value for each socket by using socket.set and socket.get

Node.js is single thread one context, it does not create any isolated context for users like in PHP.
Everything inside is shared and cross-acessible.

Related

about local storage.getItem()

I'm a new learner for API, and I have a quesion about local storage. This is a code example from my javascript book:
if (Modernizr.localstorage) {
var txtUsername = document.getElementById('username');
var txtAnswer = document.getElementById('answer');
txtUsername.value = localStorage.getItem('username');
txtAnswer.value = localStorage.getItem('answer');
txtUsername.addEventListener('input', function () {
localStorage.setItem('username', txtUsername.value);
}, false);
txtAnswer.addEventListener('input', function () {
localStorage.setItem('answer', txtAnswer.value); }, false);
}
}
I want to ask why should we "localStorage.getItem()" part? Cause I think if user type their username, then we can get their names just from the variable "txtUsername" cause I thought it should be setItem first and then getItem. Thank you!
Local storage is used to store small amounts of data on the client side. What does your code ?!
For example: A user visited the site for the first time and complete the inputs, , the data stored in the local store. The user closed the browser. The next day he again went to the site to fill out the form again, and its data is already filled. Conveniently!
Also we can use local storage as js object
txtUsername.value = localStorage.getItem('username');
txtUsername.value = localStorage.username;
txtUsername.value = localStorage['username'];
The thing is, it works just as you said.
It's just, when person types data in the textbox he uses setItem - that what 'input' eventListener used for
Think of LocalStorage as of really light database that keeps data even when user closes the page
But since it can store data when page is closed, you want to show the content of it in the textbox - and that's why author uses 'getItem' on start

socket.io query parameter not working

I have this code:
var ss = io('/secure', { query: 'token='+string });
It used to pass the query parameter to the server that was accessible as socket.handshake.query with this code:
io.of('/secure').use(function(socket, next){
// ***
console.log( socket.handshake.query );
// validate token
next();
});
but now it is not working and the output of the console.log does not include the token property:
{ EIO: '3', transport: 'polling', t: '1410465157747-0' }
I also tried changing my syntax to syntax that I have seen elsewhere online...
var ss = io('/secure', { query: { 'token': string } });
and this does not add the query property to socket.handshake.query either...
Please help!
btw I am using socket.io 1.1.0
I am on socket.io latest version (v 1.3.6) and found the same issue - for second connection, the query is not being sent.
I use socket.io for two purposes, chat and notification. Both were running on same port. Since these were two separate services, I started two separate servers on different ports - one for each service. Since then the issue has not been seen.
Try this: So if you have more than one service, try separating them into different ports.
var http_nfy = require('http').Server(app).listen(6001);
var io_nfy = require('socket.io')(http_nfy);
var http_cht = require('http').Server(app).listen(6002);
var io_cht = require('socket.io')(http_cht);
Then I used these two io differently:
io_nfy.emit(channel + ':' + message.event, message.data);
var chatNsp = io_cht.of('/chat');
I am not sure if this is a bug or intended behaviour, hence did not open an issue. If someone can confirm that this is a bug, I would be happy to report and keep track of that bug.

Using Multiple Mongodb Databases with Meteor.js

Is it possible for 2 Meteor.Collections to be retrieving data from 2 different mongdb database servers?
Dogs = Meteor.Collection('dogs') // mongodb://192.168.1.123:27017/dogs
Cats = Meteor.Collection('cats') // mongodb://192.168.1.124:27017/cats
Update
It is now possible to connect to remote/multiple databases:
var database = new MongoInternals.RemoteCollectionDriver("<mongo url>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });
Where <mongo_url> is a mongodb url such as mongodb://127.0.0.1:27017/meteor (with the database name)
There is one disadvantage with this at the moment: No Oplog
Old Answer
At the moment this is not possible. Each meteor app is bound to one database.
There are a few ways you can get around this but it may be more complicated that its worth:
One option - Use a separate Meteor App
In your other meteor app (example running at port 6000 on same machine). You can still have reactivity but you need to proxy inserts, removes and updates through a method call
Server:
Cats = Meteor.Collection('cats')
Meteor.publish("cats", function() {
return Cats.find();
});
Meteor.methods('updateCat, function(id, changes) {
Cats.update({_id: id}, {$set:changes});
});
Your current Meteor app:
var connection = DDP.connect("http://localhost:6000");
connection.subscribe("cats");
Cats = Meteor.Collection('cats', {connection: connection});
//To update a collection
Cats.call("updateCat", <cat_id>, <changes);
Another option - custom mongodb connection
This uses the node js mongodb native driver.
This is connecting to the database as if you would do in any other node js app.
There is no reactivity available and you can't use the new Meteor.Collection type collections.
var mongodb = Npm.require("mongodb"); //or var mongodb = Meteor.require("mongodb") //if you use npm package on atmosphere
var db = mongodb.Db;
var mongoclient = mongodb.MongoClient;
var Server = mongodb.Server;
var db_connection = new Db('cats', new Server("127.0.0.1", 27017, {auto_reconnect: false, poolSize: 4}), {w:0, native_parser: false});
db.open(function(err, db) {
//Connected to db 'cats'
db.authenticate('<db username>', '<db password>', function(err, result) {
//Can do queries here
db.close();
});
});
The answer is YES: it is possible set up multiple Meteor.Collections to be retrieving data from different mongdb database servers.
As the answer from #Akshat, you can initialize your own MongoInternals.RemoteCollectionDriver instance, through which Mongo.Collections can be created.
But here's something more to talk about. Being contrary to #Akshat answer, I find that Oplog support is still available under such circumstance.
When initializing the custom MongoInternals.RemoteCollectionDriver, DO NOT forget to specify the Oplog url:
var driver = new MongoInternals.RemoteCollectionDriver(
"mongodb://localhost:27017/db",
{
oplogUrl: "mongodb://localhost:27017/local"
});
var collection = new Mongo.Collection("Coll", {_driver: driver});
Under the hood
As described above, it is fairly simple to activate Oplog support. If you do want to know what happened beneath those two lines of code, you can continue reading the rest of the post.
In the constructor of RemoteCollectionDriver, an underlying MongoConnection will be created:
MongoInternals.RemoteCollectionDriver = function (
mongo_url, options) {
var self = this;
self.mongo = new MongoConnection(mongo_url, options);
};
The tricky part is: if MongoConnection is created with oplogUrl provided, an OplogHandle will be initialized, and starts to tail the Oplog (source code):
if (options.oplogUrl && ! Package['disable-oplog']) {
self._oplogHandle = new OplogHandle(options.oplogUrl, self.db.databaseName);
self._docFetcher = new DocFetcher(self);
}
As this blog has described: Meteor.publish internally calls Cursor.observeChanges to create an ObserveHandle instance, which automatically tracks any future changes occurred in the database.
Currently there are two kinds of observer drivers: the legacy PollingObserveDriver which takes a poll-and-diff strategy, and the OplogObseveDriver, which effectively use Oplog-tailing to monitor data changes. To decide which one to apply, observeChanges takes the following procedure (source code):
var driverClass = canUseOplog ? OplogObserveDriver : PollingObserveDriver;
observeDriver = new driverClass({
cursorDescription: cursorDescription,
mongoHandle: self,
multiplexer: multiplexer,
ordered: ordered,
matcher: matcher, // ignored by polling
sorter: sorter, // ignored by polling
_testOnlyPollCallback: callbacks._testOnlyPollCallback
});
In order to make canUseOplog true, several requirements should be met. A bare minimal one is: the underlying MongoConnection instance should have a valid OplogHandle. This is the exact reason why we need to specify oplogUrl while creating MongoConnection
This is actually possible, using an internal interface:
var d = new MongoInternals.RemoteCollectionDriver("<mongo url>");
C = new Mongo.Collection("<collection name>", { _driver: d });

Best Method to persist data locally in Windows 8 app

I'm creating a Windows 8 App (using HTML 5 and JavaScript) for someone and they've changed up the requirements on me as far as data storage and I could use some guidance. What I need is a data source that will persist only for the local user and not be online in a database or in the cloud. The users will be assigned a tablet with the app installed and they will enter data via forms to customize their local copy.
Here's my requirements:
-Data MUST persist through the lifetime that the app is installed on the device.
-I need to be able to query the data to some degree. I've basically got about 15-20 forms that will accept input data and then a main form that will feed off those 15-20 "sub" forms to populate drop-down and selection options.
-Size should not be an issue, it's all text data and not much of it will be entered. Can't see this going more than a couple hundred MBs over the lifetime of the app.
I've looked into XML, indexedDB (sounds good on the outside, but haven't found any kind of guarantee this will persist), and Application Data (local) which seems extremely limited in my reading capabilities.
What do you think my best bet is? Any advice would be greatly appreciated.
Thanks.
This should help
(function () {
"use strict";
var page = WinJS.UI.Pages.define("/html/index.html", {
ready: function (element, options) {
//do your things
}
});
var roamingFolder = Windows.Storage.ApplicationData.current.roamingFolder;
var afile = "FileToStoreStuff.txt";
function makefile() {
roamingFolder.createFileAsync(afile, Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (file) {
return Windows.Storage.FileIO.writeTextAsync(file);
})
}
function fileRead() {
roamingFolder.getFileAsync(filename)
.then(function (file) {
return Windows.Storage.FileIO.readTextAsync(file);
}).done(function (text) {
//do stuff
);
}
})();
This kind of assumes that your data may change. If it doesn't you can adapt a different approach, for instance replacing the roamingFolder variable with something like:
var localSettings = applicationData.localSettings;
var localFolder = applicationData.localFolder;
Take a look at the dev docs if you need to access data from within the app elsewhere.

node.js - how to switch a database in mongodb driver?

I'm new to this stuff and just stuck in the middle of nowhere. Am using node-mongodb-native and am in need to switch to another database (after authentication against admin db). I googled and found this topic where the creator of library recommends to keep a connection for each db in a hash. So my question is - how do I accomplish it?
Just create different database connections and store them in an object.
var dbConnections = {};
var dbConnections.authDb = new Db('adminDb', server, {});
dbConnections.authDb.authenticate(username, password);
var dbConnections.otherDb = new Db('otherDb', server, {});
Does that make sense?
There's an example hidden in the MongoDB driver docs under Db:
[...]
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
[...]
// Reference a different database sharing the same connections
// for the data transfer
var secondDb = db.db("integration_tests_2");
// Fetch the collections
var multipleColl1 = db.collection("multiple_db_instances");
var multipleColl2 = secondDb.collection("multiple_db_instances");
[...]
});

Categories