DEV Community

Cover image for Build Dynamic Location Tracking Systems in Django with Redis Pub/Sub and Pulsetracker
Walid LAGGOUNE
Walid LAGGOUNE

Posted on

1

Build Dynamic Location Tracking Systems in Django with Redis Pub/Sub and Pulsetracker

In this article, we’ll demonstrate how to integrate Pulsetracker's Redis Pub/Sub into a Django application to listen for real-time location updates. Additionally, we'll build a simple JavaScript WebSocket client to send location updates every second to Pulsetracker, showcasing how the service can be utilized in a real-world application.


Why Django?

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It’s known for its scalability, security, and a rich ecosystem of tools that make building robust web applications faster and easier.

Pulsetracker’s Redis Pub/Sub feature integrates seamlessly with Django, enabling developers to receive and process real-time location data efficiently.


Setting Up Redis Pub/Sub in Django

1. Install Necessary Packages

First, install Redis support for Django:

pip install django-redis
pip install redis
Enter fullscreen mode Exit fullscreen mode

2. Configure Redis in Django

Update your settings.py file to include the Pulsetracker Redis connection:

# settings.py

from decouple import config  # Recommended for managing environment variables

# Redis settings
PULSETRACKER_REDIS_URL = config('PULSETRACKER_REDIS_URL', default='redis://redis-sub.pulsestracker.com:6378')
Enter fullscreen mode Exit fullscreen mode

3. Create a Management Command for the Subscriber

Django management commands are an excellent way to handle long-running background tasks.

Create a new custom command in your Django app:

python manage.py startapp tracker
Enter fullscreen mode Exit fullscreen mode

Inside your app, create the following folder and file structure:

tracker/
    management/
        commands/
            subscribe_pulsetracker.py
Enter fullscreen mode Exit fullscreen mode

Here’s the code for subscribe_pulsetracker.py:

import redis
import hashlib
import hmac
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = "Subscribe to Pulsetracker Redis Pub/Sub server"

    def generate_signature(self, app_key, token):
        if "|" not in token:
            raise ValueError("Invalid token format")

        token_hash = hashlib.sha256(token.split("|")[1].encode()).hexdigest()
        return hmac.new(token_hash.encode(), app_key.encode(), hashlib.sha256).hexdigest()

    def handle(self, *args, **options):
        app_key = 'your_app_key_here'
        token = 'your_token_here'
        signature = self.generate_signature(app_key, token)

        channel = f"app:{app_key}.{signature}"
        redis_connection = redis.StrictRedis.from_url('redis://redis-sub.pulsestracker.com:6378')

        print(f"Subscribed to {channel}")
        pubsub = redis_connection.pubsub()
        pubsub.subscribe(channel)

        for message in pubsub.listen():
            if message['type'] == 'message':
                print(f"Received: {message['data'].decode('utf-8')}")
Enter fullscreen mode Exit fullscreen mode

Run the subscriber with:

python manage.py subscribe_pulsetracker
Enter fullscreen mode Exit fullscreen mode

To ensure the subscriber runs continuously in production, use a process manager like Supervisor or Django-Q.


Using Django-Q for Background Tasks

Install Django-Q:

pip install django-q
Enter fullscreen mode Exit fullscreen mode

Update settings.py:

# settings.py

Q_CLUSTER = {
    'name': 'Django-Q',
    'workers': 4,
    'recycle': 500,
    'timeout': 60,
    'redis': {
        'host': 'redis-sub.pulsestracker.com',
        'port': 6378,
        'db': 0,
    }
}
Enter fullscreen mode Exit fullscreen mode

Create a task to listen to Pulsetracker updates in tasks.py:

from django_q.tasks import async_task
import redis

def pulsetracker_subscribe():
    app_key = 'your_app_key_here'
    token = 'your_token_here'
    channel = f"app:{app_key}.{generate_signature(app_key, token)}"

    redis_connection = redis.StrictRedis.from_url('redis://redis-sub.pulsestracker.com:6378')
    pubsub = redis_connection.pubsub()
    pubsub.subscribe(channel)

    for message in pubsub.listen():
        if message['type'] == 'message':
            print(f"Received: {message['data'].decode('utf-8')}")
Enter fullscreen mode Exit fullscreen mode

Example WebSocket Client

Here’s a simple JavaScript client that simulates device location updates sent to Pulsetracker via WebSockets:

var wsServer = 'wss://ws-tracking.pulsestracker.com';
var websocket = new WebSocket(wsServer);
const appId = 'YOUR_APP_KEY';
const clientId = 'YOUR_CLIENT_KEY';

websocket.onopen = function(evt) {
    console.log("Connected to WebSocket server.");
    // Send location every 2 seconds
    setInterval(() => {
        if (websocket.readyState === WebSocket.OPEN) {
            navigator.geolocation.getCurrentPosition((position) => {
                console.log(position);
                const locationData = {
                    appId: appId,
                    clientId: clientId,
                    data: {
                        type: "Point",
                        coordinates: [position.coords.longitude, position.coords.latitude]
                    },
                    extra: {
                        key: "value"
                    }
                };


                // Send location data as JSON
                websocket.send(JSON.stringify(locationData));
                console.log('Location sent:', locationData);
            }, (error) => {
                console.error('Error getting location:', error);
            });
        }
    }, 3000); // Every 2 seconds
};

websocket.onclose = function(evt) {
    console.log("Disconnected");
};

websocket.onmessage = function(evt) {
    if (event.data === 'Pong') {
        console.log('Received Pong from server');
    } else {
        // Handle other messages
        console.log('Received:', event.data);
    }
};

websocket.onerror = function(evt, e) {
    console.log('Error occurred: ' + evt.data);
};
Enter fullscreen mode Exit fullscreen mode

Conclusion

Pulsetracker, combined with Django and Redis Pub/Sub, offers a robust solution for real-time location tracking. This integration allows developers to build scalable, production-ready systems that efficiently handle live location data. The addition of a WebSocket client demonstrates how easily Pulsetracker can integrate into front-end applications, enhancing the user experience.

Try implementing Pulsetracker in your Django project today and share your experience! For more information, visit the Pulsetracker documentation.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay