Skip to main content

An SSE Relay Service: Perfect for Adding Real-Time Features to Your Django Project Without Introducing ASGI or Async Code.

Project description

sse-relay-server

Docker pypi Code style: black MIT License GitHub Container Registry

For some background information, read https://github.com/Tobi-De/sse_server_postgres_listen_notify.

Originally designed for Django, now a simple, standalone Server-Sent Events relay service, ideal for Django projects seeking straightforward real-time capabilities without the need for Daphne and async Django setup.

SSE relay message transmission diagram

Explanation
  1. The browser establishes an SSE connection to the running relay service (this project).
  2. The relay service listens on the channel specified in the user request via the path parameter channel.
  3. When a user action occurs on your Django server, you run the notify function, sending an event to either PostgreSQL or Redis based on your configuration.
  4. The relay service receives the message from the broker (Redis/PostgreSQL).
  5. Subsequently, the relay sends the message via SSE to all web browsers subscribed to the specified channel.

Installation

You can install sse-relay-server as a package using pip:

pip install "sse-relay-server[postgres,redis]"

Alternatively, you can use a container by pulling the Docker image:

docker pull ghcr.io/tobi-de/sse_relay_server:latest

Supported Protocols

Environment Variables

To configure sse-relay-server, you can use the following environment variables:

  • ALLOWED_ORIGINS: Comma-separated URLs allowed to request SSE connections.
  • DATABASE_URL: PostgreSQL database URL.
  • REDIS_URL: Redis URL (if you prefer to use Redis instead of PostgreSQL).
  • RELAY_USE_PG: Force the use of PostgreSQL if you have both REDIS_URL and DATABASE_URL set, but prefer to use PostgreSQL.
  • RELAY_SERVER_DEBUG: Boolean for enabling debug mode (default to False).
  • LOG_LEVEL: CRITICAL | ERROR | WARNING | INFO | DEBUG | TRACE (default to INFO)

If the REDIS_URL environment variable is set, the redis pubsub protocol will be used instead of the PostgreSQL listen/notify.

Running the Relay Service

If installed via pip, simply execute the following command, adjusting the options as needed:

sse-relay-server --port 8001 --host 0.0.0.0 --workers 4

For Docker users, override the running command as follows:

docker run -it sse_relay_server sse-relay-server --port 8001:8001 --workers 4

Establishing an SSE Connection with the Relay Service

const channelName = "NOTIFICATIONS"
const severURL = "http://<server_host>:<relay_port>"

const eventSource = new EventSource(`${serverURL}/channel=${channelName}`);

eventSource.addEventListener('NEW_NOTIFICATION', (e) => {
    console.log(e.data)
})

Sending Messages from Your Django App

Once you've installed this package in your Django project, you can use a simple notify function to send messages. This function works for both Redis and PostgreSQL.

from sse_relay_server import notify

notify(
    channel="Notifications",
    sse_payload={
        "event": "NEW_NOTIFICATION",
        "id": 1,
        "data": json.dumps({"message": "A new notification"}),
    },
)
  • channel: The PostgreSQL/Redis channel for sending the message.
  • sse_payload: A Python dictionary containing all the details of the SSE event. For a complete list of available options, refer to this class definition.

To ensure smooth operation, avoid using excessively lengthy channel names, overly large payloads for PostgreSQL NOTIFY messages, and bulky data for SSE event payloads, as there are size limitations for each of these aspects. If you need to retrieve a large database object, consider sending just the key and fetching the full data on the frontend using another request (such as an htmx request). While this extra request may not be the most ideal solution, for simplicity's sake, it's often a worthwhile trade-off.

At my workplace, we successfully implemented a straightforward real-time notification system using this approach, transmitting all the necessary notification data without any issues. However, be aware of the potential risk of sending overly large data. For more in-depth information, you can refer to the following links:

If for some reason you don't want or cannot install this package, the code for sending events for both PostgreSQL and Redis is quite simple, and you can easily copy and paste it from below.

Postgres

import json
from django.db import connection


def notify(channel: str, sse_payload: dict) -> None:
    with connection.cursor() as cursor:
        cursor.execute(f"NOTIFY {channel}, '{json.dumps(sse_payload)}'")

Redis

import json
import redis

REDIS_URL = "redis://localhost:6379/0"


def notify(channel: str, sse_payload: dict) -> None:
    r = redis.from_url(REDIS_URL)
    r.publish(channel=channel, message=json.dumps(sse_payload))

Stopping the SSE Connection

As far as I know, there is no standard method for stopping an established SSE connection. The most straightforward solution is to send a specific event, such as one named STOP, and handle it on the frontend.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sse_relay_server-1.0.14.tar.gz (105.4 kB view details)

Uploaded Source

Built Distribution

sse_relay_server-1.0.14-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file sse_relay_server-1.0.14.tar.gz.

File metadata

  • Download URL: sse_relay_server-1.0.14.tar.gz
  • Upload date:
  • Size: 105.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for sse_relay_server-1.0.14.tar.gz
Algorithm Hash digest
SHA256 0cd2af9e1f32539101c53f21e8d195b863b28f45d0e1dfd568a352528335bd2c
MD5 ca2c650fd008965d691f045e2f99b407
BLAKE2b-256 30023785e716bd767b4166dcb00ee8c8ee568de9c62e11b26c027c64f7c7c004

See more details on using hashes here.

File details

Details for the file sse_relay_server-1.0.14-py3-none-any.whl.

File metadata

File hashes

Hashes for sse_relay_server-1.0.14-py3-none-any.whl
Algorithm Hash digest
SHA256 319eb5d5c79c3d5f275d9fa0b8ce324130bb16398633eefba9ba635c8e1dc3bb
MD5 67c915dc50ec5287bfae338637025812
BLAKE2b-256 ac02f5db2007b8e1a433fd37909d62b866f2ab9f2354c1e16d9e42afe124dd16

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page