关注各种黑科技
B站UP主,编程教学,游戏玩家,挂B,金牛座

Django Channels初探 part3

本节进一步介绍自定义channel的方式   我们会创建多个channel来进行不同的任务。比如用thumbnails频道处理用户上传的照片,用welcome_email频道发送邮件给新用户。这里使用channel队列来实现一些后台任务,可以将一些业务逻辑独立出来异步的执行。   现实例子 使用braintree支付接口 https://www.braintreepayments.com/ 这个例子中,我们使用了在手机应用中使用braintree聚合支付平台来让用户同时使用多种支付方式。 工作流程,用户在手机发起支付,发送一个带nonce参数的请求到我们的API服务器,API服务器使用这个nonce初始化一个braintree交易。初始化会发送这个nonce到braintree服务器,它返回一个交易id。之后我们请求这个交易id来确定用户是否完成付款。我们仍然需要自己处理错误发生后重试的情况,   消费者代码
def braintree_process(message):
    order_data = message.content.get('order')
    order_id = message.content.get('order_id')
    order_instance = Order.objects.get(pk=order_id)
    if order_data:
        nonce = order_data.get("braintree_nonce")
        if nonce:
            # [snipped]
            TRANSACTION_SUCCESS_STATUSES = [
                braintree.Transaction.Status.Authorized,
                braintree.Transaction.Status.Authorizing,
                braintree.Transaction.Status.Settled,
                braintree.Transaction.Status.SettlementConfirmed,
                braintree.Transaction.Status.SettlementPending,
                braintree.Transaction.Status.Settling,
                braintree.Transaction.Status.SubmittedForSettlement
            ]
            result = braintree.Transaction.sale({
                'amount': str(order_data.get('total')),
                'payment_method_nonce': nonce,
                'options': {
                    "submit_for_settlement": True
                }
            })
            if result.is_success or result.transaction:
                transaction = braintree.Transaction.find(result.transaction.id)
                if transaction.status in TRANSACTION_SUCCESS_STATUSES:
                    # [snipped]
                else:
                    # [snipped]
            else:
                errors = []
                for x in result.errors.deep_errors:
                    errors.append(str(x.code))
                # [snipped]
路由
from channels.routing import route
from .channel_handlers import braintree_process
channel_routing = [
    route("braintree_process", braintree_process),
    # [snipped] ...
]
当我们API收到手机发来的请求后,发送message到braintree_process
Channel("braintree_process").send({
    "order": data,
    "order_id": order.id
})
  启动worker可以用--only-channels或--exclude-channels只包含某个或多个channel,这样就可以启动不同的worker来分开处理channel消息了。    
转载请注明出处
分享到: 更多 (0)

评论 0