실시간 협업 중 저장하는 방법


10

여러 사용자가 동일한 문서를 편집하고 싶습니다. 내가 직면 한 문제는 새로운 사용자가 참여할 때 오래된 문서를 볼 수 있다는 것입니다. 신규 사용자에게 가장 최근의 변경 사항을 적용하려면 어떻게해야합니까?

내가 생각한 몇 가지 해결책 :

  • 모든 변경 사항을 저장하십시오. UI에서 속도가 느려지고 db에로드가 발생하기 때문에이 솔루션을 좋아하지 않습니다.

  • 새 사용자가 참여하면 다른 모든 클라이언트에서 저장을 트리거하십시오. 다른 클라이언트가 저장되면 문서를로드하십시오. 이로 인해 여전히 불일치가 발생할 수 있습니다.

다른 제안은 도움이 될 것입니다.

업데이트 : 제안 된 솔루션 인 Google Realtime API를 살펴본 결과 다음을 발견했습니다.

  1. 앱 사용자 는 Google 드라이브가 있어야하고 드라이브에 대한 액세스 권한을 부여해야합니다 . 이는 기묘한 UI 흐름을 제공하거나 Google 드라이브가없는 사용자가 실시간 기능을 사용하지 못하게 할 수 있습니다.

  2. 사용자 측에서 수행 한 모든 공유 설정 을 Google 문서에 복제해야합니다.

업데이트 2 : 목표를 달성하기 위해 Google의 Firebase 와 함께갔습니다.


새로운 사용자와 기존 사용자가 동일한 문서를 편집 / 보는 것과 왜 다른가?
Andy

@Andy 현재 내가하고있는 일은 사용자가 변경 한 모든 것을 소켓을 통해 방송하는 것입니다. 이러한 변경 사항은 브라우저가 열려 있지만 즉시 데이터베이스에 저장되지 않은 사용자를 위해 UI를 업데이트합니다. 새 사용자가 참여할 때 데이터베이스에서 문서를로드하고 아직 저장되지 않은 최근 변경 사항을 모두 볼 수없는 상황이 있습니다.
dev.e.loper

1
이미 변경 사항을 보내고 현재와 동일한 동작을 유지하려면 클라이언트 중 하나에 새 클라이언트에게 마지막보기를 보내도록 요청하거나 모든 변경 사항을 가져 오는 새 클라이언트가 서버에있을 수 있습니다. 그것을보십시오.
Dainius

답변:


14

구글 드라이브

나만의 Google 문서 도구 버전을 만들려는 경우 Google Realtime API를 살펴 보시기 바랍니다 . 구글은 최근 다른 개발자들이 실시간 협업을 위해했던 것과 동일한 툴을 사용할 수 있도록하기 위해이를 발표했다. 이를 통해 개발 시간을 절약하고 작동중인 제품을 더 빨리 얻을 수 있습니다.

문서에있는 데이터를 쉽게 가져 와서 정기적으로 데이터베이스에 푸시하거나 데이터베이스 자체를 교환의 '참가자'로하여 모든 변경 사항을 듣고 기록 할 수 있습니다. 또한 사용자가 실시간 API에서 사용할 수있는 자체 데이터 구조를 정의 할 수 있으므로 원하는대로 자유롭게 확장 할 수 있습니다.

Google 이외의 드라이브

귀하의 연구에 따르면 Google 드라이브는 옵션이 아닙니다. 괜찮습니다.하지만 얼마나 넣었는지에 따라 더 힘들어지고 작동하지 않을 수도 있습니다.

여기의 일반적인 전략 나는 이 문제를 달성하기 위해 사용하는 것은 :

  1. 서버를 통신 멀티플렉서로 사용하십시오. 각 사람은 서버와 대화하고 서버는 해당 정보를 다른 사람에게 보냅니다. 이런 식으로 서버는 항상 문서를 가장 최신으로 볼 수 있습니다.

  2. 충돌 해결을위한 타사 알고리즘 / 모듈을 찾으십시오. 충돌 해결은 어렵고 여전히 완벽하지 않습니다. 이를 단독으로 수행하면 프로젝트의 범위가 너무 커질 수 있습니다. 타사 알고리즘을 사용할 수없는 경우 한 사용자 만 시간 영역을 편집하도록 허용하여 사용자가 영역을 편집하기 전에 잠금을 얻어야합니다. 그렇지 않으면 다른 사용자의 작업이 손상 될 수 있습니다. 아주 오래된, 아주 빨리 얻을 것입니다.

  3. 새로운 사용자가 참여하면 가장 최근의 문서를 제공하고 자동으로 명령을 스트리밍하기 시작합니다. 서버는 가장 최근의 관점을 가지고 있으므로 자동으로 정리할 수 있습니다.

  4. 특정 간격으로 데이터베이스에 백업합니다. 백업 빈도를 결정하십시오 (5 분마다 또는 50 번 변경 될 때마다). 그러면 원하는 백업을 유지할 수 있습니다.

문제 : 이것은 완벽한 솔루션이 아니므로 다음과 같은 몇 가지 문제가 있습니다.

  1. 서버 처리량이 성능 병목 현상을 일으킬 수 있음

  2. 읽기 / 쓰기가 너무 많은 사람이 서버에 과부하를 일으킬 수 있음

  3. 메시지가 손실되면 사람들이 동기화되지 않을 수 있으므로 정기적으로 동기화해야합니다. 이것은 전체 메시지를 다시 전송하는 것을 의미합니다. 비용이 많이들 수 있지만 그렇지 않으면 사람들이 동일한 문서를 가지고 있지 않거나 모를 수도 있습니다.


예, 변경 사항은 모든 클라이언트에게 브로드 캐스트되며 브라우저에서 버전이 동일합니다. 모든 작업에 대한 문서를 업데이트하는 방법은 무엇입니까?
dev.e.loper

또는 문서의 현재 상태가 백그라운드에서 전송되어 모든 사람이 같은 페이지에 있는지 확인하는 규칙적인 '동기화'기간이 적어도 있어야합니다. 사람들이 문서를 얼마나 빨리 변경하는지에 따라 얼마나 자주 달라질 수 있습니다. 그렇게하면 이미 새로운 사람들에게 보내는 방법뿐만 아니라 너무 많이 발산되지 않도록 할 수있는 능력이 있습니다.
Ampt

1
+1. 인생을 어렵게 만들지 마십시오. 구글은 바퀴를 재발 명할 필요없이 이것을 잘합니다.
Neil

Google Realtime은 Google 드라이브에 저장됩니까? Google 드라이브가 아닌 데이터베이스에 저장하고 싶습니다.
dev.e.loper

@ dev.e.loper는 이에 대한 정보를 답변에 추가했습니다.
Ampt

3

서버에 1 개의 영구 문서 사본을 권장합니다. 클라이언트가 서버에 연결되면 UPDATE모든 변경 사항이있는 해당 클라이언트에 명령 을 발행합니다 .

WorkFlow 업데이트

사용자가 변경을 트리거하는 원인-> 클라이언트가 UPDATE서버로 전송-> 서버 UPDATE가 클라이언트로 전송

실행 가능한 트리거

  1. 사용자가 저장을 클릭합니다
  2. 사용자가 특정 작업을 완료
    • 셀 편집 완료
    • 문장 / 문단 / 줄 편집 완료
  3. 사용자가 실행 취소를 클릭합니다
  4. 사용자가 Return 키를 누름
  5. 사용자가 키를 입력합니다 (모든 변경에 저장)

업데이트 구현

UPDATE서버가 각 UPDATE를 저장하고 새 클라이언트가 연결되면 클라이언트에게 일련의 업데이트를 보낼 수 있으며 문서 자체를 다시 작성하여 표시 할 수 있도록 일련의 명령으로 문서를 다시 만들 수 있다고 제안 합니다. 사용자. 또한 SAVE별도 의 명령을 사용하여 UNDO요청에 사용할 수있는 임시 변경 사항 인 UPDATE가있을 수 있으며 서버가 닫히거나 모든 클라이언트의 연결이 끊어 질 경우 SAVE가 실제로 다시 열도록 저장하도록 할 수 있습니다.


2
충돌 해결은 어떻습니까? 두 사람이 같은 텍스트 영역을 동시에 편집하면 어떻게됩니까? 또한 이것은 OP가 피하려고하는 DB에 부하를주는 것으로 보입니다. 그래도 그가 필요한 것에 대해 가능할 수도 있습니다.
Ampt

@Ampt이 모델을 사용하여 스프레드 시트를 만들었으며 충돌을 위해 업데이트되는 각 특정 작업이 최신 버전으로 완전히 대체되었습니다. 따라서 셀 편집을 마친 마지막 사람은 이전에 업데이트 된 셀을 병합하지 않고 완전히 바꿉니다.
Korey Hinton

1
예를 들어 단어 문서라면 한 문장이 다른 문장을 덮어 쓰겠습니까?
Ampt

@Ampt 예, 대안으로 작업중 인 것을 잠그는 방법을 구현할 수는 있지만 쉬운 길을갔습니다.
Korey Hinton

3

1) Knockout.js를 살펴보십시오.

MVVM 패턴을 따르며 모델 변경에 따라 알림을 자동으로 뷰에 푸시합니다. 예를 들어, 관찰 가능한 배열 을 조사하여 어떻게 수행하는지에 대한 정보를 조금 더 제공하십시오.

2) SignalR 과 함께 사용하면 문서 작업을하는 다른 사용자에게 알림을 보낼 수 있습니다. 그들의 사이트에서 :

SignalR은 또한 ASP.NET 애플리케이션에서 서버-클라이언트 RPC (서버 측 .NET 코드에서 클라이언트의 브라우저에서 JavaScript 함수 호출)를 수행하고 연결 관리를위한 유용한 후크를 추가 할 수있는 매우 간단한 고급 API를 제공합니다. 예를 들어, 연결 / 연결 끊기 이벤트, 그룹 연결, 권한 부여.

따라서 변경이 발생할 때마다 SignalR을 호출하려면 Knockout.js 내에 모델 수준의 후크가 있어야합니다. 다른 클라이언트는 SignalR에서 통지를 받고 다음에 해당하는 변화 트리거 자신의 자신의보기까지 다시 밀어 버린다 모델의 사본을.

이 두 프레임 워크의 흥미로운 조합이며 특정 정보를 처리하기 위해 더 많은 정보를 검색하고 수집 할 수 있어야합니다.

예를 들어,이 CodeProject의 예는 특별히 주소 Co Working UIs and Continuous Clients것 같다 당신이 뭘하려는 건지 정확히 일치합니다.

새로운 시대의 웹 응용 프로그램은 새로운 시대의 사용자 경험을 제공해야 할 수 있으며 공동 작업 및 지속적인 클라이언트 시나리오를 올바르게 처리해야합니다. 여기에는 사용자 인터페이스가 장치 및 사용자간에 올바르게 동기화되어 응용 프로그램 및 사용자 인터페이스의 상태가 "있는 그대로"유지되도록하는 것이 포함됩니다.

블로그 게시물 은 두 패키지의 사용에 대해 설명하는 일련의 블로그 게시물의 시작점으로 보이며 기존 ASP.NET 방식과 대조됩니다. 사이트를 디자인 할 때 고려해야 할 사항이있을 수 있습니다.

블로그 게시물 은 조금 더 기본적인 것으로 보이며 두 패키지를 결합하는 기초를 제공합니다.

공개 : 나는 위의 링크 중 하나와 관련이 없으며 그 내용이 얼마나 소리 나 올바른지 확인하기 위해 실제로 파고 들지 않았습니다.


2

해결책은 OT (Operational Transformation)입니다. 들어 보지 못한 경우 OT는 다중 사이트 실시간 동시성을 수행하는 알고리즘 클래스입니다. OT는 실시간 자식과 같습니다. 지연 시간에 관계없이 작동합니다 (0에서 연장 된 휴일까지). 사용자는 낮은 대역폭으로 실시간 동시 편집을 할 수 있습니다. OT는 재시도없이, 오류없이, 데이터를 덮어 쓰지 않고 여러 사용자간에 최종 일관성을 제공합니다.

그러나 OT를 구현하는 것은 어려운 작업과 시간이 소요됩니다. 따라서 http://sharejs.org/ 와 같은 외부 라이브러리를 사용할 수 있습니다 .


1
Google Realtime API에서 OT youtu.be/hv14PTbkIs0?t=14m20s 를 수행하고 있습니다. 클라이언트와 서버에서 모두 수행합니다. ShareJS 문서를 읽음으로써 명확한 대답을 얻을 수는 없지만 ShareJS가 클라이언트와 서버 모두에서 OT를 수행한다고 가정합니다.
dev.e.loper

1

주로 문서 유형과 사용자의 협업 방식에 따라 다릅니다.

그러나 나는 :

  1. 모든 클라이언트가 저장되지 않은 변경 사항을 서버에 가끔씩 한 번에 보내도록 허용합니다 (사용자가 문서를 사용하는 방법에 따라 다름).
  2. 서버는 델타를 사용자 세션에 저장합니다 (뚱뚱한 클라이언트의 경우에도 세션과 같은 것이 필요합니다)
  3. 같은 문서를 편집 / 보는 다른 클라이언트는 일시적인 변경 사항이나 적어도 힌트가있을 수 있습니다.

장점 :

  • 누군가가 '저장'을 클릭하지 않으면 DB 업데이트가 없습니다.
  • 클라이언트가 충돌 한 경우 백업 (세션 기간 동안)
  • 서버는 어떤 클라이언트에게 어떤 데이터를 전달할 방법과 데이터를 결정합니다.

단점 :

  • '실시간'이 아닙니다. 예를 들어 30 초마다 전송하지만 누군가는 그 시간에 3 문장을 입력합니다.
  • 더 많은 네트워크 트래픽-문서 및 공동 작업에 따라 다름
  • 아마도 큰 세션
  • 많은 사용자가 협업하고 많은 변경을 수행하는 경우 높은 계산 노력

1

본질적으로, 당신이 요구하는 것은 공유 가능한 변경 가능한 상태를 다루는 방법입니다. 절약은 쉬운 부분입니다. 그러나 동시에 여러 사람이 같은 것을 편집하는 것을 어떻게 처리합니까? 동시 편집 내용을 실시간으로 동기화하면서 모든 사용자가 동일한 문서를 보길 원합니다.

아마 모아서 어려운 문제입니다! 몇 가지 실용적인 솔루션이 있습니다.

  1. 실제 동시 편집을 허용하지 않도록 응용 프로그램 요구 사항을 수정하십시오. 소스 컨트롤 시스템과 마찬가지로 편집 내용을 병합하여 각 클라이언트에 결과를 브로드 캐스트 할 수 있습니다. 직접 만들 수는 있지만 사용자 경험이 좋지 않습니다.
  2. 상태 변이 동기화를 기존 기술과 통합되는 오픈 소스 솔루션으로 아웃소싱하십시오. ShareDB 는이 분야의 현재 리더입니다. 운영 변환을 기반으로하며 하나 이상의 프로덕션 시스템에서 사용됩니다. 이것은 당신이 관심있어 구원의 문제를 돌봐하지만 것입니다 추가 UX의하지 도움말 기능을 의무적으로 모든 협업 응용 프로그램.
  3. Convergence (면책 조항 : 저는 설립자입니다) 와 같은 상용 플랫폼 을 사용하여 어려운 부분을 모두 처리하십시오. 또한 커서 / 마우스 추적, 선택 및 채팅과 같은 실시간 협업을위한 추가 도구를 통해 우수한 협업 환경을 신속하게 구축 할 수 있습니다. 기존의 모든 도구가 잘 정리되어 있는지이 질문 을 참조하십시오 .
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.