2017-10-06 2 views
1

Ich versuche, ein Auktionstypsystem zu entwickeln, wo ein Kunde eine Bestellung macht, und dann können verschiedene Geschäfte einen Preis für diese Bestellung anbieten.Verwenden von Django-Signalen in Kanälen Verbraucherklassen

Ein interessanter Teil dieses Systems ist, dass wenn die Bestellung anfänglich erstellt wird, die verfügbaren Geschäfte 60 Sekunden haben, um ihr jeweiliges Angebot zu machen. Wenn ein erstes Geschäft sein Angebot macht, hat die "Auktion" nur noch die nächsten 20 Sekunden für andere Geschäfte, um ein eigenes Angebot zu machen. Wenn sie in dieser kleineren zugewiesenen Zeit ein anderes Angebot machen, wird diese 20 Sekunden aufgefrischt. Angebote können weiterhin empfangen werden, solange genügend Zeit zur Verfügung steht, die die angegebenen 60 Sekunden nicht überschreiten kann.

Neben diesen Anforderungen möchte ich auch den Client aktualisieren, wenn neue Angebote in Echtzeit eintreffen. Dafür verwende ich django-channels Implementierung von WebSockets.

Ich habe folgende consumers.py Datei:

from channels.generic.websockets import WebsocketConsumer 
from threading import Timer 
from api.models import Order, OrderOffer 
from django.db.models.signals import post_save 
from django.dispatch import receiver 

class OrderConsumer(WebsocketConsumer): 

    def connect(self, message, **kwargs): 
     """ 
     Initialize objects here. 
     """ 
     order_id = int(kwargs['order_id']) 
     self.order = Order.objects.get(id=order_id) 
     self.timer = Timer(60, self.sendDone) 
     self.timer.start() 
     self.message.reply_channel.send({"accept": True}) 

    def sendDone(self): 
     self.send(text="Done") 

    # How do I bind self to onOffer? 
    @receiver(post_save, sender=OrderOffer) 
    def onOffer(self, sender, **kwargs): 
     self.send(text="Offer received!") 
     if (len(self.offers) == 0): 
      self.offerTimer = Timer(20, self.sendDone) 
      self.offers = [kwargs['instance'],] 
     else: 
      self.offerTimer = Timer(20, self.sendDone) 

     self.offers.append(kwargs['instance']) 


    def receive(self, text=None, bytes=None, **kwargs): 
     # Echo 
     self.send(text=text, bytes=bytes) 

    def disconnect(self, message, **kwargs): 
     """ 
     Perform necessary disconnect operations. 
     """ 
     pass 

Ich habe einen WebSocket Kommunikationskanal zwischen meinem Client und dem Server erfolgreich in der Lage gewesen zu etablieren. Ich habe das Senden von Nachrichten getestet und alles scheint in Ordnung zu sein. Jetzt möchte ich die Erstellung von neuen OrderOffer erkennen und eine Benachrichtigung an den Client senden. Dazu benötige ich Zugriff auf die self Variable, um self.send zu verwenden, was unmöglich ist, da der Signaldekorator diesen Parameter nicht sendet. Ich habe versucht, es durch die Erklärung onOffer mit Selbst zwingen, aber ich bekomme die folgende Fehlermeldung:

TypeError: onOffer() missing 1 required positional argument: 'self'

Wenn ich irgendwie das Schlüsselwort Argument zugreifen konnte, dass Sätze signalisiert, könnte ich vielleicht so etwas wie: context = self .

Ich würde jede mögliche Hilfe oder sogar alternative Lösungen zu meinem ursprünglichen Problem schätzen.

Antwort

0

Wenn Sie von „außen“ an die Verbraucher sprechen - in diesem Fall aus einem Modellspeichermethode - Sie benötigen eine Kanalschicht verwenden, um sie zu sprechen: http://channels.readthedocs.io/en/latest/topics/channel_layers.html

Im Wesentlichen Sie‘ ll müssen:

  • den Verbraucher zu einer Gruppe beim Start hinzufügen (wahrscheinlich auf seiner Bestell-ID basiert)
  • eine Nachricht an die Gruppe senden, wann immer gibt es eine neue OrderOffer mit einem benutzerdefinierten type - zB {"type": "order.new_offer", "order_offer_id": 45}
  • auf der Consumer einen Handler definieren, dass diese Griffe - es die Typnamen übereinstimmt, so in diesem Fall ist es def order_new_offer(self, event):
  • In diesem Handler würden Sie dann self.send die Steckdose sprechen unten verwenden können (und die Datenbank abfragen, wenn Sie benötigen zusätzliche Informationen, die Sie an den Client senden, den Sie nicht in die Ereignisnachricht eingefügt haben.

Sie eine Variante dieses im MultiChat Beispielprojekt sehen: https://github.com/andrewgodwin/channels-examples/tree/master/multichat

Verwandte Themen