Django渠道取消协程消息

时间:2020-03-22 10:25:45

标签: django websocket django-channels channels

您好,我正在使用django开发应用程序。我阅读了所有官方Django Channels文档的文档,但找不到。当用户连接到消费者时,我要将用户添加到组。当更改模型实例时,我将消费者中的信号发送给组中的每个客户端实例,但是我一直都发送信号,所以问题从这里开始,我希望在发送信号时取消前面的消息。我只希望发送给该群组的最新消息消失。我找不到解决方法

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from channels.exceptions import DenyConnection
from main.consumers import AsyncWebsocketConsumer

from auctions.models import Auction, Lot, AuctionBid, AuctionReport, AuctionSaloon, LandLot, HouseLot, Deposit, UserFlag, Participant
from liveauction.serializers import ROAuctionBidSerializer, ROAuctionSerializer, ROHouseLotSerializer, ROLandLotSerializer, ROLotSerializer, ROParticipantSerializer, ROFlagCoverageRangeSerializer, RONormalAuctionSerializer

from django.core.exceptions import ObjectDoesNotExist
import json
import asyncio


class AuctionConsumer(AsyncWebsocketConsumer):

    active_auction = None
    active_lot = None
    permissions = []
    channel_groups = []
    flag_coverage_ranges = []

    async def connect(self):
        if self.scope['user']:
            user = self.scope['user']
            print(self.scope['user'])
            if user.is_anonymous:
                await self.close()
            else:
                self.active_auction = await self._get_active_auction()
                print(self.active_auction)
                if self.active_auction is not None:
                    print(self.active_auction.get_channel_name())
                    self.channel_groups.append(self.channel_layer.group_add(
                        self.active_auction.get_channel_name(), self.channel_name))
                    asyncio.gather(*self.channel_groups)
                    self.permissions = await self._get_user_permission(self.scope['user'])
                    self.flag_coverage_ranges = self.active_auction.flag_coverage_ranges.all()
                    await self.accept()
                else:
                    await self.close()

    async def disconnect(self, code):
        asyncio.gather(*self.channel_groups)
        await super().disconnect(code)

    async def receive(self, text_data):
        content = json.loads(text_data)
        message_type = content.get('command')
        print(message_type)
        if await self.has_permission(message_type):
            if message_type == 'create.bid':
                await self.create_bid(content, True if self.has_permission('create.bid') else False)
            elif message_type == 'delete.bid':
                await self.delete_bid(content)
            elif message_type == 'update.bid':
                await self.update_bid(content)
            elif message_type == 'change.lot':
                await self.change_lot(content)
            elif message_type == 'update.auction':
                await self.update_auction(content)
            elif message_type == 'update.approve':
                await self.update_approve(content)
            else:
                await self.raise_error('Command not found.')
        else:
            raise DenyConnection('User is not authorized.')

    async def create_bid(self, event, auto_next_bid=True):
        print('create_bid called')
        if self.active_auction.approve_mode:
            print("teklif vermek kilitli şuan ?")
            return
        user_flag = event.get('data').get('flag') if event.get('data').get('flag', False) else await self.get_first_flag()
        participant = int(event.get('data').get('participant')) if event.get(
            'data').get('participant', False) else int(self.scope['user'].participant.id) if hasattr(self.scope['user'], 'participant') else ''
        bid_amount = event.get('data').get('bid') if event.get('data').get(
            'bid', False) else self.active_auction.current_lot.next_bid_amount
        auto_next_bid = False
        if not user_flag or float(bid_amount) < float(self.active_auction.current_lot.next_bid_amount):
            print("bura")
            pass

        if 'admin' not in self.permissions:
            getted_current_participant = await self._get_participant(participant)
            participant_deposit = getted_current_participant.deposit.filter(
                auction__id=self.active_auction.id)
            print("teminatı arıyoruz")
            if participant_deposit.exists():
                if (participant_deposit.deposit - participant_deposit.get_used_flag_deposit_amount()) < self.active_auction.current_lot.minimum_deposit:
                    print("teminatı yetersiz")
                    return
            else:
                print("teminatı yok")
                return
            last_flag_participant = None
            try:
                tenor_bids = self.active_auction.current_lot.tenor_bids
                bid = tenor_bids
                if bid.exists():
                    bid = bid.last()
                    last_flag_participant = bid.participant
                    print(bid)
                if last_flag_participant is not None:
                    print(last_flag_participant)
                    if getted_current_participant is not None:
                        print(getted_current_participant)
                        if getted_current_participant.id == last_flag_participant.id:
                            print("veremez teklif")
                            return

            except Exception as e:
                print(e)

        bid_template = {
            "flag": user_flag if not isinstance(user_flag, UserFlag) else user_flag.pk,
            "bid":  bid_amount if auto_next_bid is not True else self.active_auction.current_lot.next_bid_amount,
            "user": self.scope['user'].id,
            "lot": self.active_auction.current_lot.id,
            "participant": participant
        }
        await self._create_bid(bid_template)
        await self.send_everyone_updated_auction()

    async def delete_bid(self, event):
        ...

        await self.send_everyone_updated_auction()

    async def update_bid(self, event):
        ...

        await self.send_everyone_updated_auction()

    async def change_lot(self, event):
        ...

        await self.send_everyone_updated_auction()

    async def add_bid_to_lot(self, bid):
        ...

        await self.send_everyone_updated_auction()

    async def update_auction(self, event):
        print('update_auction called')
        auction_data = event.get('data', None)

        if auction_data is None:
            auction = await self._update_auction(self.active_auction)

            if self.has_permission('watch') and not self.has_permission('admin'):
                auction_data = RONormalAuctionSerializer(auction).data
            else:
                auction_data = ROAuctionSerializer(auction).data

        await self.send(text_data=json.dumps({
            'type': 'update.auction',
            'data': auction_data,
            'permissions': self.permissions,
            'flag_coverage_ranges': [ROFlagCoverageRangeSerializer(i).data for i in self.flag_coverage_ranges],
        }))

    async def update_approve(self, event):
        ...

        await self.send_everyone_updated_auction()

    async def send_everyone_updated_auction(self):
        auction = await self._update_auction(self.active_auction)
        serialized_data = {
            "id": auction.id,
            "slug": auction.slug,
            "current_lot": {
                "slug": auction.current_lot.slug,
                "last_bid": None if auction.current_lot.last_bid is None else {
                    "id": auction.current_lot.last_bid.id,
                    "slug": auction.current_lot.last_bid.slug,
                    "flag": auction.current_lot.last_bid.flag if auction.current_lot.last_bid.flag is None else {
                        "id": auction.current_lot.last_bid.flag if auction.current_lot.last_bid.flag is None else auction.current_lot.last_bid.flag.id,
                        "slug": auction.current_lot.last_bid.flag.slug,
                        "flag_number": auction.current_lot.last_bid.flag.flag_number,
                    },
                    "participant": auction.current_lot.last_bid.participant if auction.current_lot.last_bid.flag is None else {
                        "id": auction.current_lot.last_bid.participant.id,
                        "slug": auction.current_lot.last_bid.participant.slug,
                        "participant_type": auction.current_lot.last_bid.participant.participant_type,
                    },
                },
                "current_bid_amount": auction.current_lot.current_bid_amount,
                "next_bid_amount": auction.current_lot.next_bid_amount,
                "tenor_status": auction.current_lot.tenor_status,
                "type": auction.current_lot.type,
                "lot_number": auction.current_lot.lot_number,
                "title": auction.current_lot.title,
                "description": auction.current_lot.description,
                "minimum_deposit": auction.current_lot.minimum_deposit,
                "appraised_price": auction.current_lot.appraised_price,
                "status": auction.current_lot.status,
                "increament_amount": auction.current_lot.increament_amount,
                "tenor": auction.current_lot.tenor,
            },
            "saloons": [],
            "title": auction.title,
            "description": auction.description,
            "status": auction.status,
            "approve_mode": auction.approve_mode,
            "participants": []
        }

        await self.channel_layer.group_send(group=self.active_auction.get_channel_name(), message={
            'type': 'update.auction',
            'data': serialized_data
        })

    @database_sync_to_async
    def _open_approve(self):
        ...

    @database_sync_to_async
    def _close_approve(self):
        ...

    @database_sync_to_async
    def get_first_flag(self):
        ...

    @database_sync_to_async
    def _update_auction(self, auction):
        if auction is not None:
            serializer = None
            try:
                auction = Auction.objects.prefetch_related('lots__bids').get(pk=auction.pk)
                return auction
            except ObjectDoesNotExist:
                return None
        else:
            raise Exception('Have not yet active auction')

    @database_sync_to_async
    def _delete_bid(self, content):
        ...

    @database_sync_to_async
    def _update_bid(self, content):
        ...

    @database_sync_to_async
    def _create_bid(self, content):
        ...


    @database_sync_to_async
    def _get_participant(self, participant_id):
        ...

    @database_sync_to_async
    def _add_bid_to_lot(self, content):
        ...

    @database_sync_to_async
    def _get_user_permission(self, user):
        ...

    @database_sync_to_async
    def _get_active_auction(self):
        ...

    # TODO: Müzayededeki en son aktif Lot getirelecek
    @database_sync_to_async
    def _get_active_lot(self):
        ...

    @database_sync_to_async
    def _change_lot(self, content):
        ...

    @database_sync_to_async
    def has_permission(self, permission):
        ...

0 个答案:

没有答案