The Simple Notification Service (SNS) is a scalable, queryable, realtime notification micro service that is designed to provide the realtime infrastructure to allow you to integrate realtime notifications, events and sharing of data within your existing apps.
- Users have descriptive properties, allowing for targeted routing of notifications
- Send targeted notifications using our simple query model
- Use the same query model to detect other users, regardless of whether they are already connected, just connecting, or disconnecting
- Retrieve old notifications via the REST API
The SNS is built withNode.JSandRethinkDBin order to be highly scalable.
EventEmitterfor the browser is also used to help handle events on the client side.
You can deploy this service directly toIBM Bluemixby clicking the button below.
Note:This will provision a RethinkDB instance within Bluemix which may incur costs, please seeherefor more information
You will need Node4.4.x
or higher and a running instance of RethinkDB. You can download and run RethinkDB locally if you wish - or you can spin up a managed cluster atComposefor free, for 30 days.
Clone this repository and do the standardnpm install
to get all of the depndencies.
By default, SNS will assume a local instance of RethinkDB is running, but you can use environment variables to define where a remote instance of RethinkDB is running if you wish.
export RETHINKDB_URL='rethinkdb://username:password@hostname:28015'
If your RethinkDB instance requires an SSL Certificate in order to get access (for instance, if you are using a Compose instance), then you will need to specify the location of your certificate via another environment variable like so:
export RETHINKDB_CERT='/path/to/my/cert'
To run the SNS app, simply donpm start
.On first run of the app, all necessary DB tables will be created.
You can install SNS and run it from your own Node.js application by installing the module:
npm install --save simple-notification-service
And then "require" it into your app:
constsns=require('simple-notification-service')()
It will pick up any environment variables for configuration as mentioned above, and you can provide some other options as shown below:
constpath=require('path');
constrouter=require('express').Router();
router.get('/my/route',function(req,res){
res.send({foo:"bar"})
})
varopts={
production:true,
static:path.join(__dirname,'./public'),
authentication:[
{hostname:'localhost',key:'my-api-key'}
],
router:router
}
constsns=require('simple-notification-service')(opts);
production
- when set to true, disables all of the SNS demo apps (defaultfalse
)static
- provide a static directory for Express (defaultnull
- this will put out the SNS admin)authentication
- an array ofhostname
/key
pairs to create API keys to allow SNS access (default is empty array)router
- custom Express routes for your application (default no custom routes)
Finally, once the service is running, you will need to include the client library into your HTML. You can do so very easily as so, making sure you change the hostname to match your particular instance of the SNS app:
<scriptsrc= "http://sns-hostname /sns-client.js"></script>
And now your app is SNS enabled! Keep on reading to find out how to use the SNS in your app.
To connect to the SNS you will need an authentication key. For the JavaScript API these keys are tied to specific hostnames.
To enable the SNS demos to work you will need to create an authentication key for the hostname that is associated with your instance of the SNS. You can do this via the/admin
page.
Create a new key where hostname is the hostname of your SNS instance (e.g.localhost
) and the key isdemokey
.To check whether this is working or not, visit the/status
endpoint - if there is at least 1 user connected, everything is working!
You can create and remove as many keys as you wish on this page.
When connecting to the SNS, you should supply serveral different pieces of information:
- An authentication key
- Some
userData
- A
userQuery
Your authentication key is tied to a particular hostname, and must be created as described above. You only need to provide the key when connecting.
userData
anduserQuery
are provided as part of an options object.
userData
is a JSON object that describesthisuser (ie. the user that is connecting). This JSON object should only contain simple key/value pairs on one level (i.e. no nested objects, no arrays). ThisuserData
is what other users of the SNS will query against to send notifications to this user.
userQuery
is also a JSON object (again, only simple key/value pairs), and is used to determine what other users we care about. We will then receive connection and disconnection events for any other user that matches thisuserQuery
.
Connect to SNS, and define youruserData
anduserQuery
like so:
varSNS=newSNSClient("your-authentication-key",{
userData:{
name:"Matt",
age:32,
country:"USA",
user_type:"chat"
},
userQuery:{
country:"USA",
user_type:"chat"
}
});
Here we have defined this user with the following attributes:
- name = Matt
- age = 32
- country = USA
- user_type = chat
And we have asked to be informed about the connection/disconnections of any other users where:
- country = USA
- user_type = chat
note:a user must haveALLof the attributes defined in the
userQuery
in order to match, however it is not required that a user matchesEXACTLY,and can have attributes defined that are not in theuserQuery
TheuserQuery
is used to identify recipients of the notification.
The below example will send a JSON object with achat_msg
property to any connected user who has auser_type
ofchat
.
SNS.send({user_type:"chat"},{chat_msg:"Hello, world!"})
TheuserQuery
used to send a notification can be different to theuserQuery
defined at connection time.
Once connected there are a number of events that can be triggered and acted upon.
The connected event is very simple, and just alerts the user to the fact they have successfully connected to the SNS.
SNS.on('connected',function(){
console.log("connected event")
})
On connection, the supplieduserQuery
is used to find any other currently connected users that this user is interested in (i.e. Match theuserQuery
). This will trigger thecurrentUsers
event.
SNS.on('currentUsers',function(users){
console.log("currentUsers event",users)
})
An array of users is passed along with this event, where each element of the array is a JSON object containing theuserData
of each matched user.
When a new user connects that matches the supplieduserQuery
,it will trigger theconnectedUser
event.
SNS.on('connectedUser',function(user){
console.log("connectedUser event",user)
})
A JSON object containing theuserData
of the connecting user is passed in theuser
parameter.
When a new user disconnects that matches the supplieduserQuery
,it will trigger thedisconnectedUser
event.
SNS.on('disconnectedUser',function(user){
console.log("disconnectedUser event",user)
})
A JSON object containing theuserData
of the disconnecting user is passed in theuser
parameter.
When a new notification is received, it will trigger thenotification
event.
SNS.on('notification',function(notification){
console.log("notification event",notification)
})
Thenotification
parameter will contain the notification information.
The SNS also provides a simple HTTP API for some operations.
Notifications can also be sent by using thePOST /authentication-key/notification
HTTP endpoint, whereauthentication-key
is your authentication key. For making HTTP requests, this key is not tied to a hostname.
Requests to thePOST /authentication-key/notification
require that a JSON body is sent as shown below:
curl -H"Content-Type: application/json"-X POST -d'{ "notification": {... }, "userQuery": {... } }'/authentication-key/notification
And the response would look something like:
{
"success":true
}
Historical notifications can be retrieved by using theGET /authentication-key/historical
HTTP endpoint, whereauthentication-key
is your authentication key. For making HTTP requests, this key is not tied to a hostname.
Requests to theGET /authentication-key/historical
endpoint will parse the query string to create auserQuery
.For example, the following request will return historical notifications where theuserQuery
for this notification containsuser_type: chat
.
curl /authentication-key/historical?user_type=chat
And the response would look something like:
{
"success":true,
"notifications":[
{
"msg":"Hello, Dave!",
"name":"Matt"
},
{
"msg":"Hello, world",
"name":"Dave"
}
]
}
The Simple Notification Service comes with two demos built in, accessible from the homepage.
The first demo is a chat room. This demo showcases all of the features of the SNS - send/receive messages, detect and handle connections/disconnections, and using historical data to preserve chat history.
There is also a copy & paste widget to add chat to any website.
The second demo showcases the ability of the SNS to direct notifications to specific users.
Here you can use an adin panel to update the scores of two soccer matches. End users will either see all updates, or match specific updates, depending on the page they are visiting.
The projected is released under the Apache-2.0 license so forks, issues and pull requests are very welcome.
Sample web applications that include this package may be configured to track deployments to IBM Bluemix and other Cloud Foundry platforms. The following information is sent to a Deployment Tracker service on each deployment:
- Node.js package version
- Node.js repository URL
- Application Name (application_name)
- Space ID (space_id)
- Application Version (application_version)
- Application URIs (application_uris)
- Labels of bound services
- Number of instances for each bound service and associated plan information
This data is collected from the package.json file in the sample application and the VCAP_APPLICATION and VCAP_SERVICES environment variables in IBM Bluemix and other Cloud Foundry platforms. This data is used by IBM to track metrics around deployments of sample applications to IBM Bluemix to measure the usefulness of our examples, so that we can continuously improve the content we offer to you. Only deployments of sample applications that include code to ping the Deployment Tracker service will be tracked.
To disable deployment tracking, please remove or comment out the following line fromapp.js
:
require("cf-deployment-tracker-client").track();