How to use same DB for two ddp connected applications - javascript

I have connected two meteor applications via DDP. I expected to get the DB data also on the second service application, but I don't get any data.
As both is running on server side I didn't do any subscription - which I think I don't have to in this example.
What am I doing wrong?
Starting main web application: meteor (which should load mongodb on port 3001)
Starting service application: MONGO_URL=mongodb://localhost:3001/mydb meteor --port 3100
Web (main)
/server/main.js
Examples = new Mongo.Collection('examples');
var serviceConn = DDP.connect("http://localhost:3100");
console.log(Examples.find().count()); // Returns 21
Service 1
/server/main.js
Examples = new Mongo.Collection('examples');
console.log(Examples.find().count()); // Returns 0 !
So why can't I get the collection data on the service application as it gives me 0 results?

Try this in your service application:
const con = DDP.connect('http://localhost:3000');
Examples = new Mongo.Collection('examples', {
connection: con,
});
console.log(Examples.find().count());
Remember to start your main application first

Related

Cannot connect to CosmosDb from Azure Bot using Node

Can someone please take a look at this code and tell me why I am getting the below error message. I have looked at this every which way and can't understand why or where it's breaking.
The below code shows hard values for docDbClient, but I have also used the "process.env.Document..." system variables to no effect. This is largely taken from the Node Botbuilder samples found online. It is supposed to connect to a CosmosDb database. This should just power up. Using the Bot Framework Emulator, produces the error message at the command prompt where the server is running. Trying via published web page, it just breaks with no error message.
Thank you, in advance!
var restify = require('restify');
var builder = require('botbuilder');
var botbuilder_azure = require("botbuilder-azure");
var builder_cognitiveservices = require('botbuilder-cognitiveservices');
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword,
openIdMetadata: process.env.BotOpenIdMetadata
});
// Listen for messages from users
server.post('/api/messages', connector.listen());
var docDbClient = new botbuilder_azure.DocumentDbClient({
host: 'https://xxxxx.table.cosmosdb.azure.com:443',
masterKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
database: 'TablesDB',
collection: 'botdata'
});
var tableStorage = new botbuilder_azure.AzureBotStorage({ gzipData: false }, docDbClient);
// Create your bot with a function to receive messages from the user
var bot = new builder.UniversalBot(connector, function(session) {
session.send('You said: %s', session.message.text);
session.endDialog();
}).set('storage', tableStorage); // Register in Azure Storage
Error:
Error: Failed to initialize azure table client. Error: Error: Error Code:
400 Error Body: {"odata.error":{"code":"BadRequest","message":{"lang":"en-
us","value":"One of the input values is invalid.\r\nActivityId: 676a8f3c-
f287-490c-9062-021cb29ff78a, documentdb-dotnet-sdk/1.20.0 Host/64-bit
MicrosoftWindowsNT/6.2.9200.0\nRequestID:676a8f3c-f287-490c-9062-
021cb29ff78a\n"}}}
at C:\...\Coffee-Bot\node_modules\botbuilder-azure\lib\AzureBotStorage.js:177:32
at C:\...\Coffee-Bot\node_modules\botbuilder-azure\lib\DocumentDbClient.js:15:17
at C:\...\Coffee-Bot\node_modules\botbuilder-azure\lib\DocumentDbClient.js:76:17
at C:\...\Coffee-Bot\node_modules\documentdb\lib\queryIterator.js:141:28
at C:\...\Coffee-Bot\node_modules\documentdb\lib\queryExecutionContext\proxyQueryExecutionContext.js:71:32
at C:\...\Coffee-Bot\node_modules\documentdb\lib\queryExecutionContext\defaultQueryExecutionContext.js:62:17
at C:\...\Coffee-Bot\node_modules\documentdb\lib\queryExecutionContext\defaultQueryExecutionContext.js:81:32
at C:\...\Coffee-Bot\node_modules\documentdb\lib\queryExecutionContext\defaultQueryExecutionContext.js:136:28
at successCallback (C:\...\Coffee-Bot\node_modules\documentdb\lib\documentclient.js:2360:33)
at C:\...\Coffee-Bot\node_modules\documentdb\lib\documentclient.js:2410:25
You seem to be mixing a Cosmos DB Table endpoint and a DocumentDB client instance, which explains the 400 Bad Request.
For DocumentDB API (note host has .documents. not .table.):
var docDbClient = new botbuilder_azure.DocumentDbClient({
host: 'https://xxxxx.documents.cosmosdb.azure.com:443',
masterKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
database: 'botdocs',
collection: 'botdata'
});
var tableStorage = new botbuilder_azure.AzureBotStorage({ gzipData: false }, docDbClient);
To use Azure Table storage for bot state (this is regular Table storage, as in storage account, not Cosmos DB Table API):
var azureTableClient = new azure.AzureTableClient(tableName, storageName, storageKey);
var tableStorage = new azure.AzureBotStorage({gzipData: false}, azureTableClient);
In theory, if you pass a Cosmos DB Table endpoint to azure.AzureTableClient() you can use Cosmos as Table storage, the Table APIs are compatible between Azure Storage and Cosmos. I don't see any immediate benefit over standard DocumentDB type.
Ref:
https://learn.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state-azure-cosmosdb
https://learn.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state-azure-table-storage

Real time notifications node.js

I'm developing a calendar application with Node.js, express.js and Sequelize.
The application is simple, you can create tasks in your calendar, but you can also assign some tasks to others users of the system
I need to create a notification system with socket.io, but I don't have experience with websockets. My big doubt is how can I make my server send a notification to the user that you assign the task?
My ports configurations is on a folder called bin/www, my express routes are defined on a file called server.js
Any Idea?
I want to introduce you to ready to use backend system that enables you to easily build modern web applications with cool functionalities:
Persisted data: store your data and perform advanced searches on it.
Real-time notifications: subscribe to fine-grained subsets of data.
User Management: login, logout and security rules are no more a burden.
With this, you can focus to your main application development.
You can look at Kuzzle, wich is one project I working on:
First, start the service:
http://docs.kuzzle.io/guide/getting-started/#running-kuzzle-automagically
Then in your calendar application you can the javascript sdk
At this point you can create a document:
const
Kuzzle = require('kuzzle-sdk'),
kuzzle = new Kuzzle('http://localhost:7512');
const filter = {
equals: {
user: 'username'
}
}
// Subscribe every changes in calendar collection containing a field `user` equals to `username`
kuzzle
.collection('calendar', 'myproject')
.subscribe(filter, function(error, result) {
// triggered each time a document is updated/created !
// Here you can display a message in your application for instance
console.log('message received from kuzzle:', result)
})
// Each time you have to create a new task in your calendar, you can create a document that represent your task and persist it with kuzzle
const task = {
date: '2017-07-19T16:07:21.520Z',
title: 'my new task',
user: 'username'
}
// Creating a document from another app will notify all subscribers
kuzzle
.collection('calendar', 'myproject')
.createDocument(task)
I think this can help you :)
Documents are served though socket.io or native websockets when available
Don't hesitate to ask question ;)
As far as I can understand you need to pass your socket.io instance to other files, right ?
var sio = require('socket.io');
var io = sio();
app.io = io;
And you simply attach it to your server in your bin/www file
var io = app.io
io.attach(server);
Or what else I like to do, is adding socket.io middleware for express
// Socket.io middleware
app.use((req, res, next) => {
req.io = io;
next();
});
So you can access it in some of your router files
req.io.emit('newMsg', {
success: true
});

Emit an event with node.js socket client to sails.js (0.11.x) [duplicate]

This question already has an answer here:
Emitting a message in sails v0.11 (client-side)
(1 answer)
Closed 6 years ago.
The server: sails.js (0.11.x) is the server
The client: A node.js script with sails.io#0.11.5 and socket.io-client#1.3.5
Big picture: I have, or will have, a farm of node.js scripts that connect to the sails.js server and will perform various tasks.
Immediate Goal: I want to emit an event during a socket connection from client->server such as:
socket.emit('got_job', job.id);
Why? If this is possible I can create various event handlers on the server side in one controller (or controller + service) and keep my code clean while managing a set of stateful transactions between client/server endpoints for supporting this script farm.
The documentation: This is how one goes about using socket.io-client for sails.js this per sails docs: https://github.com/balderdashy/sails.io.js?files=1#for-nodejs
I haven't much code to share other than what's in that link, but I'll paste it here just in case:
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
// Instantiate the socket client (`io`)
// (for now, you must explicitly pass in the socket.io client when using this library from Node.js)
var io = sailsIOClient(socketIOClient);
// Set some options:
// (you have to specify the host and port of the Sails backend when using this library from Node.js)
io.sails.url = 'http://localhost:1337';
// ...
// Send a GET request to `http://localhost:1337/hello`:
io.socket.get('/hello', function serverResponded (body, JWR) {
// body === JWR.body
console.log('Sails responded with: ', body);
console.log('with headers: ', JWR.headers);
console.log('and with status code: ', JWR.statusCode);
// When you are finished with `io.socket`, or any other sockets you connect manually,
// you should make sure and disconnect them, e.g.:
io.socket.disconnect();
// (note that there is no callback argument to the `.disconnect` method)
});
What I have looked into: I've drilled into various levels of these objects and I can't seem to find anything exposed to use. And simply trying io.socket.emit() as it doesn't exist. But io.socket.get() and io.socket.post(), etc work fine.
console.log(socketIOClient);
console.log(sailsIOClient);
console.log(io);
console.log(io.socket._raw);
console.log(io.sails);
Thanks, and I'll try to update this as needed for clarification.
UPDATE:
Misc Server Info.:
I'm using nginx on port 443, with SSL termination, pointing to 4 (and
soon more) sails.js instances on separate ports (3000-3003).
I'm also using Redis for sessions and sockets.
You're close:
Your io.socket.get call is kind of like a rest api call. You'd need a sails controller bound to a get request on the url '/hello',
//client
io.socket.get('/hello', function serverResponded (body, JWR) {
//this is the response from the server, not a socket event handler
console.dir(body);//{message:"hello"}
});
in
config/routes.js:
{
'get /hello':'MyController.hello'
}
//controllers/MyController
{
hello:function(req,res){
res.json({message:"hello"});
}
}
The method you're looking for is, io.socket.on('eventName');
Here's an example:
//client
io.socket.get('/hello', function serverResponded (body, JWR) {
//all we're doing now is subscribing to a room
console.dir(body);
});
io.socket.on('anevent',function(message){
console.dir(message);
});
in
config/routes.js:
{
'get /hello':'MyController.hello'
}
//controllers/MyController
{
hello:function(req,res){
sails.sockets.join(req.socket,'myroom');
res.json({message:'youve subscribed to a room'});
}
}
What we've effectively done is, setup our socket to be part of a "room", which is basically an event namespace. Then, some other controller only has to do this:
sails.sockets.broadcast('myroom','anevent',{message:'socket event!'});
After this call is made, you would receive the message in the callback of io.socket.on('anevent').

Firebase push notifications - node worker

I need to send iOS push notifications to user whenever a certain child is added to a Firebase path.
I was thinking, that the best way to do that, would be to make a Node.js worker on Heroku, that would listen for changes and send a notification using Urban Airship.
I'm not sure what the best way is to listen for changes on Firebase from a Node.js worker on Heroku is. I'm not that familiar with heroku workers and Node.js.
Can anyone give me some pointers? Examples?
Sending push notifications with Firebase and node-apn is easy:
var apn = require("apn");
var Firebase = require("firebase");
// true for production pipeline
var service = new apn.connection({ production: false });
// Create a reference to the push notification queue
var pushRef = new Firebase("<your-firebase>.firebaseio.com/notificationQueue");
// listen for items added to the queue
pushRef.on("child_added", function(snapshot) {
// This location expects a JSON object of:
// {
// "token": String - A user's device token
// "message": String - The message to send to the user
// }
var notificationData = snapshot.val();
sendNotification(notificationData);
snapshot.ref().remove();
});
function sendNotification(notificationData) {
var notification = new apn.notification();
// The default ping sound
notification.sound = "ping.aiff";
// Your custom message
notification.alert = notificationData.message;
// Send the notification to the specific device token
service.pushNotification(notification, [notificationData.token]);
// Clean up the connection
service.shutdown();
}
For hosting this script, you won't be able to use a PaaS like Heroku. They tend to kill idle sockets. Instead you'll have to use a virtual machine.
Google Cloud Platform has a Node.js launcher that works well.

Meteor SmartCollection giving inconsistent results

On the browser JS console, News.insert({name: 'Test'}) caused {{count}} to increase from 0 to 1.
In mongo console mrt mongo, db.news.find().count() returns 1. However after adding a record via the mongo console db.news.insert({name: 'TestAgain'}), {{count}} remains at 1 while in mongo, there are 2 records now.
Question: What is causing minimongo and the mongodb console to give inconsistent results?
If I replace Meteor.SmartCollection with Meteor.Collection and reload the page, {{count} is now 2. But if I were to change it back to Meteor.SmartCollection, {{count}} goes back to 1!!
collections/news.js
News = new Meteor.SmartCollection('news');
client/views/main.html
<template name="news">
{{ count }}
</template>
client/views/main.js
Template.news.count = function() {
return News.find().count();
}
Using Meteor v6.6.3 with SmartCollection v0.3.2.2
Update
By Cuberto's suggestion, I have enabled Oplog on my Mongodb server.
export MONGO_URL=mongodb://192.168.1.111:27017/myDb
export OPLOG_URL=mongodb://192.168.1.111:27017/local
mrt
mongod runs with --replSet meteor and mongodb was configured with
var config = {_id: "meteor", members: [{_id: 0, host: "127.0.0.1:27017"}]}
rs.initiate(config)
The prompt in mongo also becomes meteor:PRIMARY> and db.local. does contain the collection oplog.rs.
Starting meteor, we see in the console SmartCollection charged with MongoDB Oplog.
Problem: However, nothing is retrieved when we try to do News.find() in the browser JS console. Doing the same query in mongo client returns the correct result. Switching from Meteor.SmartCollection back to Meteor.Collection allows the site to work again.
How can we troubleshoot the problem with SmartCollection?
Make sure you configure your MongoDB to use oplog and set the environment variables, as explained here:
http://meteorhacks.com/lets-scale-meteor.html
Since smart collections removes the periodic database poll, you need to use an oplog-enabled mongodb instance to make it recognize DB changes from outside meteor.

Categories