没有redis的Django频道

Django channels without redis

我有一个基于 this tutorial 的 Django 应用程序,运行良好。它在 Channel 层使用 Redis

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

}

我遇到的问题是我的网络托管服务提供商不允许使用 Redis(除非我支付 ££££)。

我能找到的每个示例都在这个角色中使用了 Redis。我可以使用替代方案吗?

有几个选项。

  1. 您可以 运行 您的频道层位于与主实例 运行 不同的服务上。 AWS ElastiCache 或其他许多 redis 主机。

  2. 还有一个 RabbitMQ 通道层,但如果您的托管服务提供商对 reddis 收费很高,我预计他们也会为此收取很多费用... https://github.com/CJWorkbench/channels_rabbitmq/

事实证明,渠道是一个 non-starter 在负担得起的 web-hosting 平台上。所以我恢复使用 Ajax 和长轮询。我的申请基于 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,
        }
    )    
}