How to send notifications from node.js server to android client. - node.js

What technologies do I need to use to send notification from the node.js server to the android client.For example, user A adds user B to friends, at this time user B should receive a notification to his android device that user A wants to add it to friends. I'm new to node.js, could you help me what exactly should I use to implement sending such notifications.

You could use MQTT or AMQP messaging, these are very flexible technologies, well suited to push messages to clients.
https://en.wikipedia.org/wiki/MQTT
https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol
Node.js has very good support for both.
Android has an MQTT client available with an example here: http://androidkt.com/android-mqtt/.
Essentially you can push messages to clients with something like:
client.publish (topic, message).
And clients would subscribe like:
client.on('message', function (topic, message) {
// Messages are Buffer objects.
console.log(message.toString())
client.end()
})
Clients would received this using either a callback or by polling.
Both technologies use a Broker that acts as a go between for the messages.
There are free online Brokers you can use to test messaging, e.g. mqtt://test.mosquitto.org
In Express, once you have your messaging client initialised, you can message on new events, POSTS, PUTS, etc.
app.post("/addFriend", function(req, res, next){
console.log("Friend request added");
// Write to db.
// Send a message
mqttClient.publish('friends-topic', JSON.stringify({event: 'newfriend', id: '10122', name: 'Mark' }))
res.end('ok', 200);
});

On the server side you need something to work with Google's Cloud Messaging service, for instance the node-gcm module
https://github.com/ToothlessGear/node-gcm

Related

Is there a better solution than socket.io for slow-speed in-game chat?

I am creating a browser game with node.js (backend api) and angular (frontend). My goal is to implement an in-game chat to allow communication between players on the same map. The chat is not an essential part of the game, so messages don't need to be instant (few seconds of latency should be ok). It is just a cool feature to talk some times together.
A good solution should be to implement socket.io to have real-time communication. But as chat is not an essential component and is the only thing which will require websockets, i'm wondering if there is not an alternative to avoid server overload with sockets handling.
I thinked about polling every 2 or 3 seconds my REST API to ask for new messages, but it may overload server the same way... What are your recommandations?
Thank you for your advices
There's a pretty cool package called signalhub. It has a nodejs server component and stuff you can use in your users' browsers. It uses a not-so-well-known application of the http (https) protocol called EventSource. EventSource basically opens persistent http (https) connections to a web server.
It's a reliable and lightweight setup. (The README talks about WebRTC signalling, but it's useful for much more than that.)
On the server side, a simple but effective server setup might look like this:
module.exports = function makeHubServer (port) {
const signalhubServer = require('signalhub/server')
const hub = signalhubServer({ maxBroadcasts: 0 })
hub.on('subscribe', function (channel) {
/* you can, but don't have to, keep track of subscriptions here. */
})
hub.on('publish', function (channel, message) {
/* you can, but don't have to, keep track of messages here. */
})
hub.listen(port, null, function () {
const addr = hub.address()
})
return hub
}
In a browser you can do this sort of thing. It user GET to open a persistent EventSource to receive messages. And, when it's time to send a message, it POSTs it.
And, Chromium's devtools Network tab knows all about EventSource connections.
const hub = signalhub('appname', [hubUrl])
...
/* to receive */
hub.subscribe('a-channel-name')
.on('data', message => {
/* Here's a payload */
console.log (message)
})
...
/* to send */
hub.broadcast('a-channel-name', message)

how do i send a message to a specific client in Socket io?

I'm using nodeJs ,express, mongodb & socket.io for real time notifications and messaging. I have successfully broadcasted notification to all clients but i'm having trouble sending a notification to a specific client.
I want to use clients object Id, is it possible??
To send an event to a specific socket use io.to with the socket.id of the receiver.
io.on('connection', socket => {
io.to(socket.id).emit('private', 'Just for you bud');
});

Receive GCM push notification in node.js app

I'm building a command-line application in node.js and would like to receive GCM push notifications (the command-line app will be interacting with the same set of services that iOS/Android apps use, hence wanted to use the same notification service).
Given that GCM can be used on iOS (and thus is not Android-specific) I am hoping it can be used from node.js as well.
I've seen many articles about sending push notifications from node.js, but haven't been able to find anything about using node.js on the receiving end.
i think if you have to send push notification ,to ios and andriod then fcm is better then gcm use this
router.post('/pushmessage', function (req, res) {
var serverKey = '';//put server key here
var fcm = new FCM(serverKey);
var token = "";// put token here which user you have to send push notification
var message = {
to: token,
collapse_key: 'your_collapse_key',
notification: {title: 'hello', body: 'test'},
data: {my_key: 'my value', contents: "abcv/"}
};
fcm.send(message, function (err, response) {
if (err) {
res.json({status: 0, message: err});
} else {
res.json({status: 1, message: response});
}
});
});
I believe you can using service workers.
Push is based on service workers because service workers operate in the background. This means the only time code is run for a push notification (in other words, the only time the battery is used) is when the user interacts with a notification by clicking it or closing it. If you're not familiar with them, check out the service worker introduction. We will use service worker code in later sections when we show you how to implement pushes and notifications.
So basically there is a background service that waits for push and thats what you are going to build.
Two technologies
Push and notification use different, but complementary, APIs: push is invoked when a server supplies information to a service worker; a notification is the action of a service worker or web page script showing information to a user.
self.addEventListener('push', function(event) {
const promiseChain = getData(event.data)
.then(data => {
return self.registration.getNotifications({tag: data.tag});
})
.then(notifications => {
//Do something with the notifications.
});
event.waitUntil(promiseChain);
});
https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/handling-messages
I don't think it possible (in a simple way)...
Android/iOS has an OS behind with a service that communicates with GCM...
If you are trying to run a CLI tool, you'll need to implement a service on top of the OS (Linux, Windows Mac) so it can receive notifications.
GCM sends the notifications against the device tokens which are generated from iOS/Android devices when they are registered with push notification servers. If you are thinking of receiving the notifications without devices tokens it is fundamentally incorrect.
It's not mandatory to depend only on GCM, today there are many packages are available for sending pushNotification.
Two node packages are listed below.
fcm-call - you can find documentation from https://www.npmjs.com/package/fcm-call
fcm-node
fcm-call is used - you can find documentation from https://www.npmjs.com/package/fcm-node/
let FCM = require('fcm-call');
const serverKey = '<Your Server Key>';
const referenceKey = '<Your reference key>'; //Device Key
let title = '<Your notification title here.>';
let message = '<Your message here>';
FCM.FCM(serverKey, referenceKey, title, message);
And Your notification will be sent within 2-3 seconds.
Happy Notification.

Google Cloud Pub/Sub API - Push E-mail

I'm using node.js to create an app that gets a PUSH from Gmail each time an email is received, checks it against a third party database in a CRM and creates a new field in the CRM if the e-mail is contained there. I'm having trouble using Google's new Cloud Pub/Sub, which seems to be the only way to get push from Gmail without constant polling.
I've gone through the instructions here: https://cloud.google.com/pubsub/prereqs but I don't understand how exactly this is supposed to work from an app on my desktop. It seems that pub/sub can connect to a verified domain, but I can't get it to connect directly toto the .js script that I have on my computer. I've saved the api key in a json file and use the following:
var gcloud = require('gcloud');
var pubsub;
// From Google Compute Engine:
pubsub = gcloud.pubsub({
projectId: 'my-project',
});
// Or from elsewhere:
pubsub = gcloud.pubsub({
projectId: 'my-project',
keyFilename: '/path/to/keyfile.json'
});
// Create a new topic.
pubsub.createTopic('my-new-topic', function(err, topic) {});
// Reference an existing topic.
var topic = pubsub.topic('my-existing-topic');
// Publish a message to the topic.
topic.publish('New message!', function(err) {});
// Subscribe to the topic.
topic.subscribe('new-subscription', function(err, subscription) {
// Register listeners to start pulling for messages.
function onError(err) {}
function onMessage(message) {}
subscription.on('error', onError);
subscription.on('message', onMessage);
// Remove listeners to stop pulling for messages.
subscription.removeListener('message', onMessage);
subscription.removeListener('error', onError);
});
However, I get errors as if it isn't connecting to server and on the API list I see only errors, no actual successes. I'm clearly doing something wrong, any idea what it might be?
Thank you in advance!
TL;DR
Your cannot subscribe to push notifications from the client side.
Set up an HTTPS server to handle the messages. Messages will be sent
to the URL endpoint that you configure, representing that server's
location. Your server must be reachable via a DNS name and must
present a signed SSL certificate. (App Engine applications are
preconfigured with SSL certificates.)
Just subscribe to the push notifications on your server, and when you get the notification, you can figure out who it concerns. The data you will get from the notifications is what user that it concerns, and the relevant historyId, like so:
// This is all the data the notifications will give you.
{"emailAddress": "user#example.com", "historyId": "9876543210"}
Then you could e.g. emit an event through Socket.io to the relevant user if he is online, and have him do a sync with the supplied historyId on the client side.

Socket.IO messaging to multiple rooms

I'm using Socket.IO in my Node Express app, and using the methods described in this excellent post to relate my socket connections and sessions. In a comment the author describes a way to send messages to a particular user (session) like this:
sio.on('connection', function (socket) {
// do all the session stuff
socket.join(socket.handshake.sessionID);
// socket.io will leave the room upon disconnect
});
app.get('/', function (req, res) {
sio.sockets.in(req.sessionID).send('Man, good to see you back!');
});
Seems like a good idea. However, in my app I will often by sending messages to multiple users at once. I'm wondering about the best way to do this in Socket.IO - essentially I need to send messages to multiple rooms with the best performance possible. Any suggestions?
Two options: use socket.io channels or socket.io namespaces. Both are documented on the socket.io website, but in short:
Using channels:
// all on the server
// on connect or message received
socket.join("channel-name");
socket.broadcast.to("channel-name").emit("message to all other users in channel");
// OR independently
io.sockets.in("channel-name").emit("message to all users in channel");
Using namespaces:
// on the client connect to namespace
io.connect("/chat/channel-name")
// on the server receive connections to namespace as normal
// broadcast to namespace
io.of("/chat/channel-name").emit("message to all users in namespace")
Because socket.io is smart enough to not actually open a second socket for additional namespaces, both methods should be comparable in efficiency.

Resources