0604个人总结十(补)

总结十

近期工作

这周的原定计划是完成任务等待和任务训练的单元测试,但是由于我们之前对于websocket没有进行深入了解出现了一些问题,导致我们最后只完成了任务等待的测试;同时我们主要到对于等待过程的退出发布者和参与者是不同的,于是乎我们的返回功能也需要进行修改,对于发布者来说,返回意味着任务的取消,所以需要删除任务,同时提醒其他用户任务已取消;对于参与者来说,返回意味着自己将不再参与这次任务训练,所以需要将原本的数据修改。

接下来我将先说一下websocket的一些遇到的问题以及补救措施,同时说一下最后任务等待的实时刷新改为手动刷新的原因。

1.Websocket的问题

websocket建立连接之后,后端主动退出,前端可以通过onclose函数进行捕获处理,但是前端主动退出,后端没有相应的函数进行捕获,这就导致了我们想通过websocket的前端断开连接进行返回的想法破灭。

下面是websocket的一些源码

def close(self, code=None):
	"""
    Closes the WebSocket from the server end
    """
    if code is not None and code is not True:
    	super().send({"type": "websocket.close", "code": code})
    else:
        super().send({"type": "websocket.close"})

最初我们以为close方法和前端一样是处理对方断开连接的(当时没注意注释),但是通过实践发现不是,这个是服务器断开连接时调用。

def disconnect(self, code):
	"""
    Called when a WebSocket connection is closed.
    """
    pass

disconnect方法和close方法的情况类似

2.任务等待的手动刷新实现

实时刷新需要让任务等待的websocket的receive方法进行死循环持续反馈最新信息,本来的想法:返回功能的实现是通过前端主动断开连接,websocket的close方法或者disconnect方法能够捕获被调用,控制死循环终止,后面发现这两个函数的用法不是我们说想的那样。

后面又尝试点击返回按钮再次发送数据提示返回,发现后端的websocket在陷入死循环的时候,其他的响应就失效了。

最后只能选择手动断开连接,下面是代码展示:

class WaitingConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()
        print('WaitingConsumer connect!')

    def disconnect(self, code):
        print('WaitingConsumer disconnect!')

    def send(self, text_data=None, bytes_data=None, close=False):
        return super().send(text_data, bytes_data, close)

    def receive(self, text_data=None, bytes_data=None):
        # 前端需要发送的数据:个人账号(方便统计,字段名称:account)、任务id(进行确认,字段名称:task_id)
        returnValue = {
            'judge': False,
            'accounts': '',
            'message_state': True,
            'message': '',
            'refresh': False,
            'refreshMessage': '',
        }

        # TODO 获取前端的数据,更新当前任务的人数等待并进行确认
        text_data_json = json.loads(text_data)
        print(text_data_json)

        # 获取json数据
        account = text_data_json['account']
        task_id = text_data_json['task_id']
        label = text_data_json['label']

        if label == 0:
            # 等待
            # 更新数据库(已有人数加一,账号统计字符串追加(原先:a, -> 后来增加了b变成:a,b,))
            # 这里的','是英文字符
            # 这个时候前端展示之前,后端将最后一个','去掉

            mission = Mission.objects.get(mission_id=task_id)
            current_user = mission.current_user + 1
            user_accounts = mission.user_accounts + account + ','
            print(current_user)
            print(user_accounts)

            Mission.objects.filter(mission_id=task_id).update(
                current_user=current_user,
                user_accounts=user_accounts
            )
            # 如果查询不到,说明任务已经取消
            if mission is None:
                returnValue['message_state'] = False
                returnValue['message'] = '任务已取消'
                self.send(text_data=json.dumps(returnValue))
        elif label == 1:
            # 刷新
            returnValue['refresh'] = True
            # 进行查询
            mission = Mission.objects.get(mission_id=task_id)
            # 如果查询不到,说明任务已经取消
            if mission is None:
                returnValue['message_state'] = False
                returnValue['message'] = '任务已取消!'
                self.send(text_data=json.dumps(returnValue))
            current_user = mission.current_user
            user_accounts = mission.user_accounts
        need = mission.demand_user
        returnValue['need'] = need
        returnValue['have'] = current_user
        if returnValue['refresh']:
            returnValue['refreshMessage'] = '刷新成功'
        if need <= current_user:
            # 可以进行模型训练, 循环可以退出
            accounts = user_accounts.rstrip(',')
            returnValue['accounts'] = accounts
            returnValue['judge'] = True
            self.send(text_data=json.dumps(returnValue))
        else:
            # 反馈给前端账号信息
            accounts = user_accounts.rstrip(',')
            returnValue['accounts'] = accounts
            self.send(text_data=json.dumps(returnValue))

主要是receive方法的实现。首先获取前端发送过来的数据:account、task_id(等同于mission_id)和label,account是为了更新数据库的参与人员名单,task_id是为了定位到具体任务,label是为了判断是更新数据还是刷新数据,剩下的就是对数据库的操作,最后判断一下需求人数和参与人数,如果足够就可以给前端提示可以开始训练。

3.返回功能的分解(针对发布者和参与者)

首先是url的路由设置,区分发布者和参与者。发布者取消任务,参与者停止等待退出任务。

# 参与者在任务等待过程中退出
path('quitWaiting', views.quitWaiting),
# 发起者在任务训练开始之前进行任务取消
path('cancelMission', views.cancelMission),

首先是参与者的代码:

@require_http_methods(["POST"])
def quitWaiting(request):
    response = {'result': False,'message': ''}
    print('正在退出循环等待...')
    jsonData = json.loads(request.body)
    task_id = jsonData['task_id']
    account = jsonData['account']
    try:
        # 更改数据库的值,人数减一,字符串减少(需要先读取,再更新)
        mission = Mission.objects.get(mission_id=task_id)
        if mission.mission_state != 'waiting':
            response['message'] = '训练已开始,请开始训练'
            return JsonResponse(response)
        # 人数更新
        current_user = mission.current_user - 1
        # 读取账号字符串,减去个人账号,更新数据库中账号字符串的值
        temp = account + ','
        user_accounts = mission.user_accounts.replace(temp, '')
        Mission.objects.filter(mission_id=task_id).update(
            current_user=current_user,
            user_accounts=user_accounts
        )
        # 最后更改循环的条件,退出循环
        print('退出成功')
        # True表示退出成功
        response['result'] = True
        response['message'] = '返回成功'
    except:
        response['message'] = '返回失败'
    return JsonResponse(response)

本质上就是和进行任务等待更新操作相反的操作,唯一值得注意的就是对于参与人员名单的修改,这里用的是python字符串的replace方法,mission.user_accounts.replace(temp, '')

接下来是发布者的取消任务(这个部分不是我写的,这里简单介绍一下即可)

# 取消任务,条件,需要任务id以及发起人账号,以及任务状态为未开始
# 发现为非发起人则返回仅任务发起人有取消权限
# 发现任务状态不对返回该任务状态下不可取消
# 取消后删除对应任务表项
@require_http_methods(["POST"])
def cancelMission(request):
    jsonData = json.loads(request.body)
    mission_id = jsonData['mission_id']
    response = {}
    try:
        print(mission_id)
        res = Mission.objects.get(mission_id=mission_id)
    except:
        response = {"results": "该任务不存在"}
        return JsonResponse(response)
    else:
        if res.mission_state != 'waiting':
            response["results"] = "任务仅可在waiting状态下取消"
            return JsonResponse(response)
        else:
            # 删除对应项
            Mission.objects.get(mission_id=mission_id).delete()
            response["results"] = "任务取消成功"
            return JsonResponse(response)

先判断任务是否存在,再判断任务是否处于waiting状态,最后即可删除。这里解释一下有关任务状态的设定,任务状态主要有三种,分别为waiting、training和finish,这里判断是否处于waiting状态的依据就在于,任务是否已经开始训练,如果任务开始训练了,这时候删除会对其他人造成影响,故不可删除。

下步计划

1.完成任务训练的单元测试

2.进行集成测试和系统测试

3.部署进行发布前的验收测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值