2016-12-06 4 views
1

Djangoチャンネルでの作業を開始します。私のモデルのデバイスのバインドデータが必要です。私がやる。管理インタフェースでDeviceオブジェクトを変更すると、クライアント(Webブラウザ)で変更に関するメッセージが表示されますが、カスタムdjango管理コマンドを使用して簡単なWebsocketServerも実行します。また、カスタムコマンド処理でDevice-objectが変更された場合、私はクライアントにメッセージを受け取らない。どのように私はそれを修正することができます?カスタムコマンドのDjangoチャンネルによるデータバインド

デバイス/ models.py

OFFLINE = 0 
ONLINE = 1 
REGISTRATION = 2 
REMOVED = 3 
ERROR = 4 


STATUS_CHOICES = (
    (OFFLINE, _("Offline")), 
    (ONLINE, _("Online")), 
    (REGISTRATION, _("Registration")), 
    (REMOVED, _("Removed")), 
    (ERROR, _("Error")), 
) 


class Device(models.Model): 
    name = models.CharField(max_length=128, 
          null=True, blank=True, default=None, verbose_name=_("Name")) 
    created = models.DateTimeField(verbose_name=_("Creation date time"), editable=False) 
    modified = models.DateTimeField(verbose_name=_("Last change date time"), blank=True) 

    removed = models.BooleanField(verbose_name=_("Device has been removed"), default=False) 
    remove_date = models.DateTimeField(verbose_name=_("Date of Device removing"), 
             null=True, blank=True, 
             default=None) 

    joined = models.BooleanField(verbose_name=_("Registration status"), default=False) 
    date_joined = models.DateTimeField(verbose_name=_("Registration date time"), blank=True, null=True, default=None) 
    owner = models.ForeignKey("accounts.User", 
           null=True, blank=True, default=None, 
           verbose_name=_("Who registered"), on_delete=models.SET(None)) 

    status = models.SmallIntegerField(choices=STATUS_CHOICES, blank=True, default=REGISTRATION, verbose_name=_("Status")) 
    frozen = models.BooleanField(default=False, verbose_name=_("Device is frozen")) 

デバイス/ databinding.py

from channels.binding.websockets import WebsocketBinding 

from .models import Device 


class DeviceBinding(WebsocketBinding): 

    model = Device 
    stream = "device" 
    fields = ['status', 'joined', 'frozen'] 

    @classmethod 
    def group_names(cls, *args, **kwargs): 
     return ["binding.devices"] 

    def has_permission(self, user, action, pk): 
     return True # FIXME: check permission for user 

プロジェクト/ routing.py

from channels import route_class, route 
from devices.consumers import Demultiplexer 
from devices.databinding import DeviceBinding 

channel_routing = [ 
    route_class(Demultiplexer, path='^/stream/?$'), 
    route("binding.device", DeviceBinding.consumer), 
] 

デバイス/ consumers.py

from channels.generic.websockets import WebsocketDemultiplexer 


class Demultiplexer(WebsocketDemultiplexer): 

    mapping = { 
     "device": "binding.device", 
    } 

    def connection_groups(self): 
     return ["binding.devices"] 

My autobahn WebSockerServerを実行する簡単なカスタムコマンドです。

プロジェクト/管理/コマンド/ runcustomcommand.py

from django.core.management import BaseCommand 
from project.websocketserver.autobahn_server import WebSocketServer 

class Command(BaseCommand): 
    help = "Run WebSocket Server" 

    # A command must define handle() 
    def handle(self, *args, **options): 
     wss = WebSocketServer() 
     wss.start() 

プロジェクト/ websocketserver/autobahn_server.py

クラスWebSocketServer(オブジェクト):

def __init__(self): 
    import sys 

    from twisted.python import log 

    log.startLogging(sys.stdout) 

    self.factory = WebSocketServerFactory(
      "ws://{host}:{port}".format(
        host=settings.WSS_HOST, port=settings.WSS_PORT), 
      # debug=False 
    ) 
    self.factory.protocol = MyServerProtocol 
    self.factory.setProtocolOptions(
      autoPingInterval=settings.WSS_AUTO_PING_INTERVAL, 
      autoPingTimeout=settings.WSS_AUTO_PING_TIMEOUT 
    ) 

def start(self): 
    from twisted.internet import reactor 

    try: 
     logger.info("\tSTART SERVER") 
     reactor.listenTCP(settings.WSS_PORT, self.factory) 
     reactor.run() 
    except KeyboardInterrupt: 
     pass 
    finally: 
     self.stop() 

def stop(self): 
    from twisted.internet import reactor 
    reactor.stop() 
    logger.info("\tSTOP SERVER") 

クライアント上のconnetion(JSコード):

var ws_path = "ws://127.0.0.1:8001/stream/"; 
console.log("Connecting to " + ws_path); 
var webSocket = new WebSocket(ws_path); 

webSocket.onopen = function() { 
alert("Connected!."); 
}; 

webSocket.onmessage = function(message) { 
var data = JSON.parse(message.data); 
alert(data); 
}; 

webSocket.onerror = function(error) { 
alert("Error: " + error.message); 
}; 

私が実行します。

redis-server 
daphne project.asgi:channel_layer --port 8001 
python manage.py runworker -v2 
python manage.py runserver 0.0.0.0:8000 -v2 

python manage.py runcustomcommand 

UPDATE

私が誤って自分の管理コマンドの開始でこのコードを追加した場合、オブジェクトへの後続の変更がクライアントに来ることを発見:

from channels import Channel 
Channel("binding.devices").send({}) 

初期化のようなものです。しかし、それは不思議です。

答えて

0

私はまったく同じことをしましたが、あなたのDeviceBinding.group_namesDemultiplexer.connection_groupsメソッドがリストを返さないことが確かであるとは言えません。末尾にカンマ["binding.device", ]["binding.devices", ]があることを確認してください。それ以外は、私が見ることができる唯一の違いは、私は複数のモデルをバインドしているので、私は別のグループ名を使用しています。

希望すると、 Stu

関連する問題