【问题标题】:Django channels without redis没有 redis 的 Django 频道
【发布时间】:2020-11-28 13:27:41
【问题描述】:

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

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

}

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

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

【问题讨论】:

    标签: redis django-channels


    【解决方案1】:

    事实证明,在一个负担得起的网络托管平台上,频道是行不通的。所以我恢复使用 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,
            }
        )    
    }
    

    【讨论】:

    • 我知道已经快一年了,但是您是否有机会探索Memcached 来替换 Redis,因为它已经是 Django 核心缓存框架的一部分?很想得到这方面的任何指导。
    • 我一直在投票;现在我正在使用Django Eventstream 关注 SSE。看起来很有希望
    【解决方案2】:

    有几个选项。

    1. 您可以在不同的服务上运行您的通道层,以便主实例运行。 AWS ElastiCache 或许多其他 redis 主机。

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

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 2018-06-09
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-21
      • 2021-05-14
      相关资源
      最近更新 更多