Station
@sphinx-software/station
Abstraction Layer for realtime messaging & push notification
yarn
yarn add @sphinx-software/station
npm
npm i -S @sphinx-software/station
This package is server implementation.
For client-side implementation, please check @sphinx-software/antenna
Contents
Getting Started
Realtime Messaging
Minimal example
We support realtime messaging via Messenger
service.
import { Messenger, transports } from '@sphinx-software/station'
const messenger = new Messenger(transports.log(console))
messenger.broadcast(
{
type: 'greeting',
payload: {
hello: 'world',
},
},
'the-world',
)
Run the above script, you should see the bellow output in your console
{
message: { type: 'greeting', payload: { hello: 'world' } },
channels: [ 'the-world' ]
} Messenger.Transport.Log#send
That's it! You've broadcast a greeting message to the-world
channel.
💡 A message must have 2 fields:
type
accepts a string describing the message type andpayload
which is data the message carrying.The
send()
method is returning aPromise<void>
value.The example above is using the log transport. It will do nothing but log the message to the console output, which will become handy for testing / debugging. For the real world application, please check the
firestore
transport.
Message
interface
The We can model our message by implementing the Message
interface.
import { Message } from '@sphinx-software/station'
//
class GreetingMessage implements Message<{ hello: string }> {
constructor(private readonly destination: string) {}
get type() {
return 'Greeting'
}
get payload() {
return {
hello: this.destination,
}
}
}
Then send the message as usual
//
messenger.send(new GreetingMessage('world'), 'the-world')
Topic
interface
The In real world application, we rarely use the string only for a channel name.
Instead, we usually tie a channel to a logical model, that model can be considered as a Topic
.
import { Topic, Channel } from '@sphinx-software/station'
// A post now is a topic.
// So subscribers can listen for new comment for this post.
class Post implements Topic {
//...
channel() {
return new Channel(`post-${this.id}`)
}
}
// When a new comment was made for this post
// we can broadcast the message to the post topic
// so subscribers can get updated
messenger.broadcast(
{
type: 'comment.added',
payload: {
commentId: comment.id,
},
},
post,
)
💡 The
Channel
class is just a helper for generating the fully qualified name string with the format:channel_{your_channel_name}
.Combining the
{type}-{id}
as the name will help you avoid name collision.
Private topic
todo docs
Sending a message to a subscriber
In many cases, we use one special channel for the client with a single purpose: Sending various messages to that client and that client only.
We call that channel as an inbound channel, and that client can be so-called as a Subscriber
.
For example:
class User {
// ... your code here
}
We can instruct the messenger that User
is a Subscriber
, that can receive a message via an inbound channel.
import { Subscriber, PrivateChannel } from '@sphinx-software/station'
//
class User implements Subscriber {
inbound(): string {
return new PrivateChannel(`user-${this.id}`)
}
}
Now we can send a message to the user:
/// Your code to get the user entity
const joe = new User()
///
messenger.send(
{
type: 'greeting',
payload: {
content: 'Hello',
},
},
joe,
)
💡 A
Subscriber
can subscribe to manyTopic
, but have one inbound channel.Certainly you can use
Channel
instead ofPrivateChannel
as an inbound channel. But hey! if you are doing everyone can subscribe to it!. Not so private right?
firestore
transport
Using Instead of using log
transport, we can use the firestore
transport which can
send messages to the browsers / devices and authorize their subscriptions to private topics.
First let's install firebase-admin
library
yarn
yarn add firebase-admin
npm
npm i -S firebase-admin
Now, let's initialize the firebase admin application:
import * as admin from 'firebase-admin'
const app = admin.initializeApp({
credential: admin.credential.applicationDefault(),
})
Then replace the messenger
initialization script
// const messenger = new Messenger(transports.log(console))
const messenger = new Messenger(transports.firestore(app))
💡 Please refer to the Firebase Documentation for more details about how to initialize
firebase-admin
Push Notification
todo docs
Advance topics
todo docs
How it works
todo docs
Supported services
todo docs
Framework integrations
todo docs