웹 기반 파일 편집기로 사용되는 응용 프로그램을 빌드하고 있습니다. 사용자는 편집하려는 파일을 선택할 수 있으며 그 파일은 서버에서 검색되어 필드에 표시됩니다. 그러면 사용자는 파일을 편집하고 결국 저장할 수 있습니다.여러 세션 인스턴스 감지
이것은 내가 해결하려고하는 경쟁 조건을 소개합니다.
클라이언트 쪽 파일이 서버 쪽 파일과 항상 동기화되지는 않습니다. 사용자가 이미 열고 다른 장소에서 편집 한 파일을 열면 저장하면 다른 클라이언트가 수행 한 편집을 덮어 씁니다. 이것은 병합의 일부 형식을 사용하여 수정할 수 있지만, 이것은이 프로젝트의 범위를 벗어납니다.
사용자가 두 개의 다른 PC 또는 두 개의 서로 다른 브라우저에서 로그인하고 동일한 파일을 두 번 열려고 시도하면 세션 키를 사용하여이를 감지 할 수 있습니다. 그러나 사용자가 두 번째 탭을 열면 세션 키가 동일하게됩니다.
현재 주기적으로 파일을 핑 (예 : 2 초마다)하고 이전 핑이 약 2 초 전인지 확인합니다. 그것이 (지연을 설명하는 어떤 가치를 뺀) 그보다 작 으면 일 수도 있고 두 명의 고객이 그 파일을 보게 될 수도 있습니다. 그러나 사용자가 파일과 파일 사이를 빠르게 전환하면 이는 단절되며 단순한 추악합니다.
이렇게하는 것이 더 깔끔하고 깨끗한 방법이 있습니까?
저는 장고 백엔드와 jQuery에 크게 의존하는 프론트 엔드를 사용하고 있습니다. 따라서이 둘을 기반으로하는 모든 기능이 선호됩니다.
일부 관련 코드는 다음과 같습니다 : 클라이언트 측에서
, 주기적으로 파일 서버 측 dinging : 서버 측에서
setInterval(function(){
opened = $('input[name=file]:checked', '#files').val();
if(opened){
$.post('./' + opened + '/ding').error(function(){
alert('Something is awry.');
});
}
}, 2000);
을,이 꼴 처리 :
def ding(request, user_id, project_id, file_id):
user = User.objects.get(pk=user_id)
project = Project.objects.get(pk=project_id)
file = File.objects.get(pk=file_id)
session_key = request.session.session_key
can_claim = file.last_seen_open == None or timezone.now() - file.last_seen_open > datetime.timedelta(seconds=4)
is_mine = file.last_opened_by == session_key
is_iffy = file.last_seen_open != None and timezone.now() - file.last_seen_open < datetime.timedelta(seconds=1)
if is_iffy:
return HttpResponse(status=409, content="File is iffy")
if can_claim or is_mine:
file.last_opened_by = session_key
file.last_seen_open = timezone.now()
file.save()
return HttpResponse(status=200, content="File ding'd")
else:
return HttpResponse(status=409, content="File claimed by someone else")
을
파일이 동일한 키에서 두 번 열리는 것처럼 보이는 경우 "409 : File is iffy"응답이 반환됩니다.