Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django channels without redis

I have a django app based on this tutorial that works perfectly. It uses Redis in the Channel layers

 CHANNEL_LAYERS = {
    'default': {
       'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
     },
 },

}

The problem I have is that my web hosting provider will not allow Redis (unless I pay ££££).

Every example that I can find uses Redis in this role. Is there an alternative I could use?

like image 308
Psionman Avatar asked Mar 11 '26 08:03

Psionman


1 Answers

It turned out that channels is a non-starter on an affordable web-hosting platform. So I reverted to using Ajax and long polling. My application is based on this Django Tutorial.

models.py

class Message(models.Model):
    room_name = models.CharField(null=False, blank=False, max_length=50)
    sender = models.CharField(null=False, blank=False, max_length=50, default='Sender username')
    datetime = models.DateTimeField(null=True, auto_now_add=True)
    type = models.IntegerField(null=True, blank=True)
    text = models.CharField(null=False, blank=False, max_length=250, default='message text')
    context = models.TextField(null=True, blank=True)

urls.py

urlpatterns = [
    path('<str:partner_pk>/check-message', views.CheckMessage.as_view(), name="check-message"),
    path('<str:partner_pk>/send-message/<str:chat_text>', views.SendMessage.as_view(), name="send-message"),
]

views.py

class CheckMessage(View):
    """Duo check message."""

    def get(self, request, partner_pk):
        """Render the GET request."""
        pair, room_name = sort_pair(partner_pk, request.user.pk)
        partner = User.objects.get(pk=partner_pk)
        profile = get_object_or_404(Profile, user=request.user)
        message = Message.objects.filter(room_name=room_name, sender=partner.username).earliest('datetime')
        context = {'type': -1}
        context = json.loads(message.context)
        context['sender'] = message.sender
        context['datetime'] = message.datetime
        context['message_type'] = message.type
        context['text'] = message.text
        context['seat'] = profile.seat
        message.delete()
        return JsonResponse(context, safe=False)

class SendMessage(View):
    def get(self, request, partner_pk, chat_text):
        message_type = app.MESSAGE_TYPES['chat']
        send_message(request, partner_pk, message_type, text=chat_text, context={})
        return JsonResponse({}, safe=False)

chat.js

window.setInterval(checkMessage, 3000);

function checkMessage () {
    $.ajax(
        {
        type:"GET",
        url: "check-message",
        cache: false,
        success: function(message) {
            processMessage(message);
            }
        }
    )    
}

// Take action when a message is received
function processMessage(context) {
    switch (context.message_type) {
        case 0:
            sendMessage(context)
            functionOne()
            break;
        case 1:
            sendMessage(context)
            functionTwo()
            break;
        case 2:
            sendMessage(context)
            functionThree()
            break;
    }
}

// Send a message to chat   
function sendMessage (context) {
    if (context.sender != username) {
        var messageObject = {
                'username': context.sender,
                'text': context.text,
            };
        displayChat(context);

        }
}    

// Display a chat message in the chat box.
function displayChat(context) {
    if (context.text !== '') {
        var today = new Date();
        var hours = pad(today.getHours(), 2)
        var minutes = pad(today.getMinutes(), 2)
        var seconds = pad(today.getSeconds(), 2)
        var time = hours + ":" + minutes + ":" + seconds;
        var chat_log = document.getElementById("chat-log");
        chat_log.value += ('('+time+') '+context.sender + ': ' + context.text + '\n');
        chat_log.scrollTop = chat_log.scrollHeight;
    }
}

//pad string with leading zeros
function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
}

// Call submit chat message if the user presses <return>.
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function (e) {
    if (e.keyCode === 13) {  // enter, return
        document.querySelector('#chat-message-submit').click();
    }
};

// Submit the chat message if the user clicks on 'Send'.
document.querySelector('#chat-message-submit').onclick = function (e) {
    var messageField = document.querySelector('#chat-message-input'), text = messageField.value,        chat_log = document.getElementById("chat-log");
    context = {sender: username, text: messageField.value}
    displayChat(context)
    sendChat(messageField.value)
    chat_log.scrollTop = chat_log.scrollHeight;
    messageField.value = '';
};

// Call the send-chat view
function sendChat(chat_text) {
    $.ajax(
        {
        type:"GET",
        url: "send-message/"+chat_text,
        cache: false,
        }
    )    
}
like image 122
Psionman Avatar answered Mar 13 '26 03:03

Psionman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!