使用Django频道向所有连接的客户端发送信息

时间:2017-07-14 16:49:20

标签: python django websocket django-channels

我正在创建一个系统,其中Twitter Live Streaming API通过给定的关键字获得推文数据的实时流。每当推文发出时,我想通过WebSockets(使用Django频道)将新数据发送到所有连接的客户端。这是我目前的程序:

  1. Twitter实时流媒体代码在consumer.py获取新数据时调用initiateHandshake()函数
  2. Django频道将文本“握手”发送给所有客户
  3. 客户收到握手消息并发回消息
  4. websocket.recieve函数接收此消息,并根据存储在客户端连接会话中的过滤器信息,发回所需数据(这就是需要握手的原因 - 因为每个客户端都有自己的过滤器,在其连接会话中)
  5. 现在,问题是initiateHandshake()中的“握手”消息没有发送。为什么会这样,我该如何解决?非常感谢!我的代码如下。

    WebSockets运行正常(如果客户端发送消息,我可以使用reply_channel来回复它 - 一切正常)

    routing.py

    from channels.routing import route
    from tweetrunner.consumers import *
    
    channel_routing = [
        route("websocket.connect", ws_connect),
        route("websocket.receive", ws_message),
        route("websocket.disconnect", ws_disconnect),
    ]
    

    consumers.py

    # In consumers.py
    from channels import Group, Channel
    from channels.sessions import channel_session
    from .models import InputTweet
    from django.shortcuts import render
    
    # Outside world connection
    def initiateHandshake():
        Group("table").send({"text": "handshake"})
    
    
    # Connected to websocket.connect
    @channel_session
    def ws_connect(message):
        # Accept connection
        message.reply_channel.send({"accept": True})
        message.channel_session["sort"] = "none"
        # Add to group
        Group("table").add(message.reply_channel)
    
    
    # Connected to websocket.receive
    @channel_session
    def ws_message(message):
        definition = message.content['text'][:1]
    
        if definition == "1":
            emotion = message.content['text'][1:]
            message.channel_session["sort"] = message.content['text'][1:]
    
            sendback = ""
    
            if emotion == 'none':
                given_tweets = InputTweet.objects.all()
                given_tweets = given_tweets[(len(given_tweets) - 1250):]
                print("before render")
                sendback = render(None, 'tweetrunner/get_table_update.html', {'given_tweets': given_tweets})
                print("rendered")
            else:
                given_tweets = InputTweet.objects.filter(emotion__startswith=emotion).order_by('score')
                given_tweets = given_tweets[(len(given_tweets) - 1250):]
                sendback = render(None, 'tweetrunner/get_table_update.html', {'given_tweets': given_tweets})
    
            print("about to send")
            message.reply_channel.send({
                "text": sendback.content.decode('utf-8'),
            })
            print("sent -- END CONNECTION LOGS")
    
        elif definition == "3":
            print("Keep alive!")
    
        else:
    
            emotion = message.channel_session["sort"]
    
            sendback = ""
    
            print("entered 2")
    
            if emotion == 'none':
                given_tweets = InputTweet.objects.all()
                given_tweets = given_tweets[(len(given_tweets) - 1250):]
                print("before render")
                sendback = render(None, 'tweetrunner/get_table_update.html', {'given_tweets': given_tweets})
                print("rendered")
            else:
                given_tweets = InputTweet.objects.filter(emotion__startswith=emotion).order_by('score')     
                given_tweets = given_tweets[(len(given_tweets) - 1250):]
                sendback = render(None, 'tweetrunner/get_table_update.html', {'given_tweets': given_tweets})
    
            print("about to send")
    
            #content = sendback.read()
    
            message.reply_channel.send({
                "text": sendback.content.decode('utf-8'),
            })
    
            print("sent -- END CONNECTION LOGS")
    
    
    # Connected to websocket.disconnect
    @channel_session
    def ws_disconnect(message):
        Group("table").discard(message.reply_channel)
    

    我的代码,不在任何django应用程序中,正在初始化django这样(我可以访问数据库并使用django调用,所以它正在工作):

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "analyticsui.settings")
    
    import django
    django.setup()
    

    客户端上的JavaScript:

    socket = new WebSocket("ws://" + window.location.host + "/");
    
    socket.onmessage = function(e) {
    alert("Got message: " + e.data)
        if (e.data == "handshake") {
            socket.send("2handshake");
            alert("sent");
        } else {
            document.getElementById("tweetTable").innerHTML = e.data;
            $('.tooltiphere').tooltip('remove');
            $('.tooltiphere').tooltip({delay: 10});
        }
    }
    

1 个答案:

答案 0 :(得分:1)

使用内存通道层时,

initiateHandshake()不会发送任何消息。

  

来自doc:In-Memory层不支持跨进程通信

请使用其他频道图层类型,尤其是Redis channel layer。一切都会按预期工作。