from django.shortcuts import render
from django.views.generic.base import View
from datetime import datetime
from django.http import HttpResponse
from .models import Cschat
from tools.cschat_aliyun import AliyunCschat
from django.views.decorators.csrf import csrf_exempt
import json,time
class CschatView(View):
def get(self,request):
return render(request,'cschat.html')
def post(self,request):
content = request.POST.get("content","")
result = AliyunCschat(content).hash_result()
time.sleep(2)
with open('aliyun.json','rb') as f:
d = json.loads(f.read())
return render(request,'cschat_result.html',{
"contents":d
})
class AliyunCallbackView(View):
@csrf_exempt
def post(self,request):
postbody = request.body
with open('aliyun.json','wb') as f:
f.write(postbody)
return HttpResponse(str(postbody))
def get(self,request):
return render(request,'aliyun_callback.html',{
"text":"没有结果"
})
应用场景:给阿里云的接口发送POST请求后 阿里云不会直接返回数据 而是把数据返回到另外一个接口(class AliyunCallbackView(View)这个对应的url),我需要在给阿里云发送POST请求后从另一个接口读取阿里云返回的POST数据。
代码中
result = AliyunCschat(content).hash_result()
这一行执行是给阿里云的接口发送POST请求 我现在的写法很有问题,因为没有好的解决办法。 我的做法是把AliyunCallbackView接收到的阿里云POST返回的数据写到aliyun.json这个文件里面,然后等待2秒钟后读取aliyun.json里面的内容,再把结果返回给前端。这样写的问题很多,如果AliyunCallbackView在一秒内接收到多个返回数据,那后面的执行内容就全变了。可以把阿里云POST返回的数据写入数据库,然后使用时间戳查询数据库返回对应的值。这种办法虽然可行但是感觉太麻烦了,请问有什么更好的解决办法?
遇到了同样的问题,在CSDN看到了,希望阿里云团队能够给出正确、标准的答案~请查看
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在您的场景中,确实存在并发写入文件可能导致数据混乱的问题,而频繁查询数据库也并非最优解。一个更高效且线程安全的方案是使用消息队列(如阿里云的MQ服务)来处理异步回调和结果传递。这样可以确保请求与响应之间的解耦,提高系统的可扩展性和稳定性。
以下是基于此思路的一个简化示例流程:
发送请求到阿里云接口:保持不变,但不再直接等待结果。
设置消息队列:在发送请求前,生成一个唯一的标识符(如UUID),将这个标识符连同请求内容一起发送给阿里云,并将该标识符作为消息ID保存至消息队列中。此时,消息队列中存储的是待处理的请求信息及用于关联的唯一ID。
阿里云回调处理:当阿里云通过AliyunCallbackView
接收到数据时,根据之前生成的唯一标识符从消息队列中查找对应的消息。然后更新这条消息的内容为阿里云返回的数据。这里利用消息队列的幂等性处理机制,确保即使多次回调也不会导致数据重复或错乱。
前端轮询或长轮询:前端可以通过AJAX定期查询(或者使用WebSocket实现长连接)后端接口,提供之前生成的唯一标识符。后端根据这个标识符从消息队列中检查是否有对应的结果,如果有,则返回给前端;如果没有,则返回“正在处理”状态,直到超时或有结果。
后端查询逻辑:创建一个新的视图函数,接收前端传来的唯一标识符,查询消息队列中对应的消息状态。如果消息已包含阿里云的响应数据,则直接返回给前端;否则,可以设计合理的重试逻辑或让前端继续轮询。
采用这种方式,您不仅解决了并发问题,还使得系统更加健壮、可扩展。阿里云提供了多种消息队列服务,如RocketMQ、Kafka等,可以根据实际需求选择适合的服务进行集成。
请注意,上述方案需要您对现有代码结构做较大调整,并引入新的组件(消息队列服务)。此外,还需考虑如何管理消息的有效期、失败处理策略等细节。