What's new
2024-10-20 - Python SDK v1.0.0 released 🚀
We are excited to announce the release of the Realtime Pub/Sub SDK for Python v1.0.0. This release stabilizes the SDK API in a more user-friendly way for Python developers. The SDK provides a high-level abstraction for interacting with the Realtime Pub/Sub API, making it easier to integrate Realtime Pub/Sub into your Python applications.
Check out more: https://pypi.org/project/realtime-pubsub-client/
2024-10-19 - Introducing SDK for Go 🚀
We are excited to announce the release of the Realtime Pub/Sub SDK for Go. This SDK provides a high-level abstraction for interacting with the Realtime Pub/Sub API, making it easier to integrate Realtime Pub/Sub into your Go applications.
server.go
package main
import (
"fmt"
"github.com/backendstack21/realtime-pubsub-client-go"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"os"
"time"
)
func main() {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.InfoLevel)
// Load environment variables from .env file
if err := godotenv.Load(); err != nil {
logger.Errorf("Error loading .env file")
}
appID := os.Getenv("APP_ID")
accessToken := os.Getenv("ACCESS_TOKEN")
// Create a URL provider function
urlProvider := func() (string, error) {
url := fmt.Sprintf("wss://genesis.r7.21no.de/apps/%s?access_token=%s", appID, accessToken)
return url, nil
}
// Initialize the client with configuration
client := realtime_pubsub.NewClient(realtime_pubsub.Config{
Logger: logger,
WebSocketOptions: realtime_pubsub.WebSocketOptions{
URLProvider: urlProvider,
},
})
client.On("secure/inbound.gettime", func(args ...interface{}) {
logger.Infof("Responding to gettime request...")
replyFunc := args[1].(realtime_pubsub.ReplyFunc)
go func() {
if err := replyFunc(map[string]interface{}{
"time": time.Now().Format(time.RFC3339),
}, "ok"); err != nil {
logger.Errorf("Failed to reply to message: %v", err)
}
}()
})
client.On("secure/inbound.presence", func(args ...interface{}) {
message := args[0].(realtime_pubsub.IncomingMessage)
presence := message.DataAsPresenceMessage()
if presence.Status() == "connected" {
logger.Infof("Client %v connected with %v permissions...", presence.ConnectionId(), presence.Permissions())
} else if presence.Status() == "disconnected" {
logger.Infof("Client %v disconnected...", presence.ConnectionId())
}
})
client.On("session.started", func(args ...interface{}) {
err := client.SubscribeRemoteTopic("secure/inbound")
if err != nil {
logger.Errorf("Error subscribing to remote topic: %v", err)
}
})
// Handle error events
client.Connect()
select {}
}
client.go
package main
import (
"fmt"
"github.com/backendstack21/realtime-pubsub-client-go"
"github.com/sirupsen/logrus"
"os"
"time"
"github.com/joho/godotenv"
)
func main() {
done := make(chan bool)
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.DebugLevel)
// Load environment variables from .env file
if err := godotenv.Load(); err != nil {
logger.Errorf("Error loading .env file")
}
appID := os.Getenv("APP_ID")
accessToken := os.Getenv("ACCESS_TOKEN")
// Create a URL provider function
urlProvider := func() (string, error) {
url := fmt.Sprintf("wss://genesis.r7.21no.de/apps/%s?access_token=%s", appID, accessToken)
return url, nil
}
// Initialize the client with configuration
client := realtime_pubsub.NewClient(realtime_pubsub.Config{
Logger: logger,
WebSocketOptions: realtime_pubsub.WebSocketOptions{
URLProvider: urlProvider,
},
})
client.On("session.started", func(args ...interface{}) {
go func() {
// Publish a message to the "chat" topic
waitFor, _ := client.Send("",
realtime_pubsub.WithSendMessageType("gettime"),
)
// Wait for acknowledgment
reply, err := waitFor.WaitForReply(500 * time.Millisecond)
if err != nil {
logger.Errorf("Error waiting for reply: %v", err)
}
// Print reply
logger.Infof("Received date: %v\n", reply.DataAsMap()["time"])
done <- true
}()
})
// Handle error events
client.Connect()
select {
case <-done:
}
}
2024-10-07 - Introducing SDK for Python 🚀
We are excited to announce the release of the Realtime Pub/Sub SDK for Python. This SDK provides a high-level abstraction for interacting with the Realtime Pub/Sub API, making it easier to integrate Realtime Pub/Sub into your Python applications.
server.py
import os
import time
import logging
import asyncio
from dotenv import load_dotenv
from realtime_pubsub_client import RealtimeClient
# Load variables from .env into os.environ
load_dotenv()
# Configure logging
logging.basicConfig(level=logging.DEBUG)
async def main():
async def get_url():
# replace with your access token retrieval strategy
access_token = os.environ.get('ACCESS_TOKEN')
app_id = os.environ.get('APP_ID')
# return the WebSocket URL with the access token
return f"wss://genesis.r7.21no.de/apps/{app_id}?access_token={access_token}"
config = {
'logger': logging.getLogger('RealtimeClient'),
'websocket_options': {
'url_provider': get_url,
}
}
client = RealtimeClient(config)
# Connect to the WebSocket server
await client.connect()
client.logger.info('Connected to WebSocket server')
# Define a message handler
async def handle_session_started(message):
await client.subscribe_remote_topic('secure/inbound')
client.on('session.started', handle_session_started)
async def handle_get_time(message, reply_fn):
client.logger.info('Responding to gettime request...')
await reply_fn({
'time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
}, status='ok')
client.on('secure/inbound.gettime', handle_get_time)
async def handle_presence(message, reply_fn):
client.logger.info(f"Presence event received: {message}")
if message['data']['payload']['status'] == 'connected':
client.logger.info(f"Client {message['data']['client']['connectionId']} connected...")
elif message['data']['payload']['status'] == 'disconnected':
client.logger.info(f"Client {message['data']['client']['connectionId']} disconnected...")
client.on('secure/inbound.presence', handle_presence)
while client.ws and not client.ws.closed:
await asyncio.sleep(1)
# Run the main coroutine
asyncio.run(main())
client.py
import os
import time
import logging
import asyncio
from dotenv import load_dotenv
from realtime_pubsub_client import RealtimeClient
# Load variables from .env into os.environ
load_dotenv()
# Configure logging
logging.basicConfig(level=logging.DEBUG)
async def main():
async def get_url():
# replace with your access token retrieval strategy
access_token = os.environ.get('ACCESS_TOKEN')
app_id = os.environ.get('APP_ID')
# return the WebSocket URL with the access token
return f"wss://genesis.r7.21no.de/apps/{app_id}?access_token={access_token}"
config = {
'logger': logging.getLogger('RealtimeClient'),
'websocket_options': {
'url_provider': get_url,
}
}
client = RealtimeClient(config)
# Connect to the WebSocket server
await client.connect()
# Define a message handler
async def handle_session_started(message):
client.logger.info('Requesting server time...')
waiter = await client.send('', {
'messageType': 'gettime'
})
response, = await waiter.wait_for_reply(timeout=5)
client.logger.info(f"Server time: {response['data']['time']}")
await client.disconnect()
client.on('session.started', handle_session_started)
while client.ws and not client.ws.closed:
await asyncio.sleep(1)
# Run the main coroutine
asyncio.run(main())
2024-09-21 - Introducing SDK for JavaScript/TypeScript 🚀
We are excited to announce the release of the Realtime Pub/Sub SDK for JavaScript/TypeScript. This SDK provides a high-level abstraction for interacting with the Realtime Pub/Sub API, making it easier to integrate Realtime Pub/Sub into your JavaScript/TypeScript applications.
server.ts
import {
ConnectionInfo,
IncomingMessage,
ReplyFunction,
RealtimeClient
} from 'realtime-pubsub-client'
const client = new RealtimeClient({
websocketOptions: {
maxRetries: 10,
urlProvider: async () => {
return `wss://${CLUSTER_HOSTNAME}/apps/${APP_ID}?access_token=${ACCESS_TOKEN}`
},
},
})
client.on('session.started', async (info: ConnectionInfo) => {
client.subscribeRemoteTopic('secure/inbound')
})
client.on('secure/inbound.gettime', async (_, reply: ReplyFunction) => {
console.log('Responding to gettime request...')
await reply({
time: new Date().toISOString()
}, 'ok').waitForAck()
})
client.on('secure/inbound.presence', async (message: IncomingMessage) => {
if (message.data.payload.status === 'connected') {
console.log(`Client ${message.data.client.connectionId} connected...`)
} else if (message.data.payload.status === 'disconnected') {
console.log(`Client ${message.data.client.connectionId} disconnected...`)
}
})
client.connect()
client.ts
import {
ConnectionInfo,
IncomingMessage,
ReplyFunction,
RealtimeClient
} from 'realtime-pubsub-client'
const client = new RealtimeClient({
websocketOptions: {
maxRetries: 10,
urlProvider: async () => {
return `wss://${CLUSTER_HOSTNAME}/apps/${APP_ID}?access_token=${ACCESS_TOKEN}`
},
},
})
client.on('session.started', async (info: ConnectionInfo) => {
// request time to server
const [res] = await client
.send('', {
messageType: 'gettime',
})
.waitForReply()
console.log('Server Time:', res as ResponseMessage)
})
client.connect()
2024-09-13 - Enabling apps icon costumization 🎨
We are excited to announce the latest enhancement to the Realtime Pub/Sub Console UI: the ability to customize your app icons. This new feature not only makes your apps more visually appealing but also improves usability and enhances the overall user experience.
2024-08-09 - Console UI enhancements and Max Age JWT Claim verification 🎨🔒
We are excited to announce the latest enhancements to the Realtime Pub/Sub Console UI. The new features include a more intuitive reporting navigation experience and connections by country map visualization.
Additionally, we have added a new feature to the JWT verification process. The max_age
claim can now be used to verify the maximum age of the token. This feature allows you to set a maximum age for the token and reject tokens that are older than the specified time.
2024-07-20 - Historical Egress Traffic chart added to Account page 📊📈
We are excited to announce the addition of the Historical Egress Traffic chart to the Account page. This new feature displays account-level egress traffic usage over a one-year period.
2024-07-14 - General Availability with Free Plan 🚀💚🌟
We are thrilled to announce the general availability of Realtime Pub/Sub as a SaaS product. With this release we are also increasing the benefits of our free plan with up to 100KB/s per WebSocket client (inbound), allowing developers to build big from the beginning and without any cost.
Find out more about our Free plan in our pricing page.
With our Free
plan, developers can build true realtime applications effortlessly.
Key Highlights
- 🆓 Free Plan: Begin building realtime applications at no cost.
- 📚 Enhanced Documentation: Comprehensive guides and tutorials to help you get started.
- 📊 Administration Console: Monitor and manage your applications with ease.
- 🔗 WebSocket and HTTP APIs: Simple and robust APIs for seamless integration. No libraries needed, no bullsh*t.
Further explore our documentation and demos to learn more about the features and capabilities of Realtime Pub/Sub.