使用 django 频道时如何使用频道而不是组?

Posted

技术标签:

【中文标题】使用 django 频道时如何使用频道而不是组?【英文标题】:How to use Channel instead of Group when using django channels? 【发布时间】:2016-05-08 08:16:39 【问题描述】:

我正在尝试使用 django 上的频道项目 (http://channels.readthedocs.org/en/latest/index.html)。

虽然在文档中有一个很好的教程用于构建基于组的 websocket 应用程序(聊天),但我找不到与客户端特定的简单推送机制相关的内容(因此无需使用组)

假设我想与各种新闻提供商建立一个提要聚合器,当用户访问主页并等待所有提要被解析时,我想向他发送有关服务器正在解析哪个提要的信息消息,在他等待的时候。

我现在得到的是: 消费者.py

from channels import Group, Channel
from .views import sort_articles_by_date
from .soup import ProviderParser
from .models import Provider


# Connected to websocket.connect and websocket.keepalive
def ws_add(message):
    Group("news_providers_loading").add(message.reply_channel)

def ws_message(message):
    providers = Provider.objects.all()

    articles = []
    for provider in providers:
        Group("news_providers_loading").send('content': str(provider))
        parser = ProviderParser(provider)
        articles.extend(parser.parse_articles())

     sort_articles_by_date(articles)


 # Connected to websocket.disconnect
 def ws_disconnect(message):
     Group("news_providers_loading").discard(message.reply_channel)

路由.py

channel_routing = 
    "websocket.connect": "news_providers.consumers.ws_add",
    "websocket.keepalive": "news_providers.consumers.ws_add",
    "websocket.receive": "news_providers.consumers.ws_message",
    "websocket.disconnect": "news_providers.consumers.ws_disconnect",

虽然它工作正常,但我忍不住觉得这有点矫枉过正(?) 有没有办法只使用 Channel 构造函数,而不是 Group?

谢谢:)

【问题讨论】:

【参考方案1】:

更新:

频道版本 = 0.9

频道现在是 0.9,因此客户端需要进行一些更改才能从服务器接收消息:

class Content:
    def __init__(self, reply_channel):
        self.reply_channel = reply_channel

    def send(self, json):
        self.reply_channel.send(
            'reply_channel': str(self.reply_channel),
            'text': dumps(json)
        )


def ws_message(message):
    content = Content(message.reply_channel)
    content.send('hello': 'world')

routing.py 保持不变...


频道版本

呸,这有点棘手,但找到了。

您必须使用消息的 reply_channel 属性。 所以这个:

Group("news_providers_loading").send('content': str(provider))

变成这样:

Channel(message.reply_channel).send('content': str(provider))

我现在得到的是:

from channels import Channel
from .soup import ProviderParser, sort_articles_by_date
from .models import Provider
from django.template.loader import render_to_string
from json import dumps


class Content:
    def __init__(self, reply_channel):
        self.reply_channel = reply_channel

    def send(self, json):
        Channel(self.reply_channel).send('content': dumps(json))


def ws_message(message):
    providers = Provider.objects.all()
    content = Content(message.reply_channel)

    content.send('providers_length': len(providers))

    articles = []
    for provider in providers:

        content.send('provider': str(provider))

        parser = ProviderParser(provider)
        articles.extend(parser.parse_articles())

    sort_articles_by_date(articles)
    html = render_to_string('news_providers/article.html', 'articles': articles)

    content.send('html': html)

路由.py

channel_routing = 
     "websocket.receive": "news_providers.consumers.ws_message",

看起来更轻松,尽管您可能希望保持连接、保持连接和断开连接方法(作为简单的 foo 方法)-对此并不完全确定-!

# connect, keepalive and disconnect
def ws_foo(message):
    pass

路由.py

channel_routing = 
    "websocket.connect": "news_providers.consumers.ws_foo",
    "websocket.keepalive": "news_providers.consumers.ws_foo",
    "websocket.receive": "news_providers.consumers.ws_message",
    "websocket.disconnect": "news_providers.consumers.ws_foo",

【讨论】:

以上是关于使用 django 频道时如何使用频道而不是组?的主要内容,如果未能解决你的问题,请参考以下文章

django 频道在组用户之间共享实例变量

使用 django 频道发生 onmessage 事件时如何触发通知声音?

如何将 Django 频道会话分配给 ORM 中的对象?

django 频道如何知道客户端已断开连接?

Django Channels - 当组成员时无法直接向频道发送消息

如何检测用户是不是因网络断开而离开凤凰频道?