Skip to content
 
 

Repository files navigation

websocket-drawboard

hagi4u/tldraw-webrtc-example 포크. 원본은 WebRTC·y-webrtc 기반; 본 저장소는 WebSocket·SQLite·단일 포트 서빙 등으로 갈아탐.

애플리케이션 설정 및 실행방법

패키지 설치 (Bun 필요)

bun install

개발환경 실행 (Vite + WebSocket/Yjs 서버 동시)

bun run dev

빌드 및 프로덕션 실행 (HTTP·WS 단일 프로세스)

bun run build
bun run serve

WebSocket/Yjs 서버만 별도로 실행

bun run ws:start

사용된 아키텍처 및 기술

  • TypeScript
    • 자바스크립트의 정적 타입을 명시하여 타입 기반으로 코드를 작성할 수 있게 함
  • React.js
    • 화면을 그리기 위한 라이브러리
  • tldraw
    • 화이트 보드 인터페이스 구현
  • yjs
    • 실시간 공동 작업 구현을 위해 사용
    • 내부 데이터 구조를 공유하여 CRDT(동시에 데이터를 수정할 때 발생되는 충돌 문제를 해결) 구현이 구현된 객체
    • Y.Doc 를 통해 document 개념을 만들어 연결된 클라이언트들에게 sync 할 수 있게 처리
    • 다양한 네트워크 프로바이더를 제공하며 (y-websocket 등) 별도의 추가기능 없이 적용만 하면 연결된 클라이언트 간 동일한 상태관리를 위해 데이터를 유지
  • y-utility (YKeyValue)
    • key-value pair 데이터를 저장하고 관리할 수 있게 해주는 역할
    • 단순하고 직관적인 key-value pair 데이터를 관리할 때 유용함
    • 데이터를 번갈아 반복작성 해야 하는 경우에 적합하여 사용
      • Y.Map 은 잠재적인 충돌 요소를 방어하기 위해 기록된 모든 키를 유지 해야함
      • 그리고 특정 키를 삭제 하더라도 데이터 용량에 변화가 없음
  • y-websocket
    • Yjs용 WebSocket 프로바이더, 중앙 서버와 SQLite로 방 단위 상태 동기화·저장
  • Tailwind
    • Utility Classname 기반의 스타일 라이브러리로 별도의 CSS Style 를 작성하지 않고 클래스 기반으로 간단한 UI 를 그리기 위해 사용
  • uuid
    • 피어가 방을 생성할 때 URL Path로 사용하기 위하여 사용

useYjs Hook

1. 상태

  • storeWithStatus: <TldrawEditor/> 컴포넌트의 store prop 에 들어갈 상태 조합
  • store
    • yDoc 와의 실시간 데이터 동기화를 위한 처리
    • 화이트 보드 내 record 정보 컬랙션
    • 원격으로 받아온 데이터를 화이트보드에 병합
    • 스키마 정보 관리
  • yDoc
    • 피어들간 상태 관리를 위한 Yjs 객체
  • yStore
    • key-value pair 의 데이터 관리를 위한 yjs store
  • provider
    • websocket provider
    • 이벤트 관리
  • meta
    • yjs의 데이터 스키마를 가져오고, 메타 데이터를 관찰하기 위함
    • 스키마 변경시 데이터를 일관성있게 유지하고, 맞지 않다면 페이지 새로고침을 통해 최신 스키마가 로딩될 수 있도록 관리 필요

2. 이벤트 처리 순서도

stateDiagram-v2
  useEffect(React.js) --> WebsocketProvider.on('status')
  WebsocketProvider.on('status')  --> handleStatus : connected/disconnected

  handleStatus --> WebsocketProvider.on('synced')
  WebsocketProvider.on('synced') --> handleSyncPeers
  handleSyncPeers


  state WhiteboardUpdate{
    handleSyncWhiteBoard
    YjsStore.on(handleYStoreChange)
  }

  state SchemaUpdate {
    handleSyncSchema
    meta.observe(handleSyncMeta)
  }

  handleSyncPeers --> WhiteboardUpdate
  handleSyncPeers --> SchemaUpdate
  handleSyncPeers --> handleSyncAwareness
Loading

운영 환경에 대한 필요한 배경 정보 또는 가정

  • 빌드 후 bun run serve 또는 Docker로 띄우면 동일 네트워크에서 http://<호스트>:3000 접근 (WebSocket도 동일 포트)

Docker 이미지 빌드는 컨테이너 내부에서 npm으로 설치·빌드함(Bun 대신: better-sqlite3 등 네이티브 스크립트 호환). 재현성 위해 루트에 package-lock.json 두고 docker compose build 전에 npm install로 갱신 가능.

iPhone 시연 (운영 환경과 동일한 네트워크에 있는 경우)

데스크탑 클라이언트에서 화이트 보드 변경 사항을 실시간으로 모바일 클라이언트에서 확인(1)

데스크탑 클라이언트에서 화이트 보드 변경 사항을 실시간으로 모바일 클라이언트에서 확인(2)

Desktop 시연

모바일 클라이언트에서 화이트 보드 변경 사항을 실시간으로 데스크탑 클라이언트에서 확인

About

tldraw websocket integration

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages