From 5ca4f5bbf426229aa065f7d527c28d51bf1b7b89 Mon Sep 17 00:00:00 2001 From: Milos Vetesnik Date: Sun, 6 Mar 2022 22:43:02 +0100 Subject: [PATCH] feat: rewrite collab server connecting (#4881) Co-authored-by: dwelle --- .env.development | 2 +- .env.production | 2 +- public/index.html | 6 ------ src/excalidraw-app/collab/CollabWrapper.tsx | 23 +++++++++++++++------ src/excalidraw-app/data/index.ts | 20 +++++++++++++++++- src/global.d.ts | 2 +- src/locales/en.json | 3 ++- src/tests/collab.test.tsx | 8 +++++++ 8 files changed, 49 insertions(+), 17 deletions(-) diff --git a/.env.development b/.env.development index 08257282..d37b83ac 100644 --- a/.env.development +++ b/.env.development @@ -4,5 +4,5 @@ REACT_APP_BACKEND_V2_POST_URL=https://json-dev.excalidraw.com/api/v2/post/ REACT_APP_LIBRARY_URL=https://libraries.excalidraw.com REACT_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries -REACT_APP_SOCKET_SERVER_URL=http://localhost:3002 +REACT_APP_PORTAL_URL=http://localhost:3002 REACT_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8","authDomain":"excalidraw-oss-dev.firebaseapp.com","projectId":"excalidraw-oss-dev","storageBucket":"excalidraw-oss-dev.appspot.com","messagingSenderId":"664559512677","appId":"1:664559512677:web:a385181f2928d328a7aa8c"}' diff --git a/.env.production b/.env.production index 08022700..842ce2b0 100644 --- a/.env.production +++ b/.env.production @@ -4,7 +4,7 @@ REACT_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/ REACT_APP_LIBRARY_URL=https://libraries.excalidraw.com REACT_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries -REACT_APP_SOCKET_SERVER_URL=https://oss-collab-us1.excalidraw.com +REACT_APP_PORTAL_URL=https://portal.excalidraw.com REACT_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}' # production-only vars diff --git a/public/index.html b/public/index.html index 0df8b246..0d8ce3b9 100644 --- a/public/index.html +++ b/public/index.html @@ -72,12 +72,6 @@ crossorigin="anonymous" /> - - { /* webpackChunkName: "socketIoClient" */ "socket.io-client" ); - this.portal.socket = this.portal.open( - socketIOClient(SOCKET_SERVER), - roomId, - roomKey, - ); + try { + const socketServerData = await getCollabServer(); + this.portal.socket = this.portal.open( + socketIOClient(socketServerData.url, { + transports: socketServerData.polling + ? ["websocket", "polling"] + : ["websocket"], + }), + roomId, + roomKey, + ); + } catch (error: any) { + console.error(error); + this.setState({ errorMessage: error.message }); + return null; + } if (!existingRoomLinkData) { const elements = this.excalidrawAPI.getSceneElements().map((element) => { diff --git a/src/excalidraw-app/data/index.ts b/src/excalidraw-app/data/index.ts index 11b59b82..64049c70 100644 --- a/src/excalidraw-app/data/index.ts +++ b/src/excalidraw-app/data/index.ts @@ -30,7 +30,25 @@ const generateRoomId = async () => { return bytesToHexString(buffer); }; -export const SOCKET_SERVER = process.env.REACT_APP_SOCKET_SERVER_URL; +/** + * Right now the reason why we resolve connection params (url, polling...) + * from upstream is to allow changing the params immediately when needed without + * having to wait for clients to update the SW. + */ +export const getCollabServer = async (): Promise<{ + url: string; + polling: boolean; +}> => { + try { + const resp = await fetch( + `${process.env.REACT_APP_PORTAL_URL}/collab-server`, + ); + return await resp.json(); + } catch (error) { + console.error(error); + throw new Error(t("errors.cannotResolveCollabServer")); + } +}; export type EncryptedData = { data: ArrayBuffer; diff --git a/src/global.d.ts b/src/global.d.ts index ef24cb5a..337a5f0d 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -21,7 +21,7 @@ declare namespace NodeJS { interface ProcessEnv { readonly REACT_APP_BACKEND_V2_GET_URL: string; readonly REACT_APP_BACKEND_V2_POST_URL: string; - readonly REACT_APP_SOCKET_SERVER_URL: string; + readonly REACT_APP_PORTAL_URL: string; readonly REACT_APP_FIREBASE_CONFIG: string; } } diff --git a/src/locales/en.json b/src/locales/en.json index b5595c2d..e7b2e572 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -180,7 +180,8 @@ "imageInsertError": "Couldn't insert image. Try again later...", "fileTooBig": "File is too big. Maximum allowed size is {{maxSize}}.", "svgImageInsertError": "Couldn't insert SVG image. The SVG markup looks invalid.", - "invalidSVGString": "Invalid SVG." + "invalidSVGString": "Invalid SVG.", + "cannotResolveCollabServer": "Couldn't connect to the collab server. Please reload the page and try again." }, "toolBar": { "selection": "Selection", diff --git a/src/tests/collab.test.tsx b/src/tests/collab.test.tsx index d80b06dc..84fd9e3a 100644 --- a/src/tests/collab.test.tsx +++ b/src/tests/collab.test.tsx @@ -15,6 +15,14 @@ Object.defineProperty(window, "crypto", { }, }); +jest.mock("../excalidraw-app/data/index.ts", () => ({ + __esmodule: true, + ...jest.requireActual("../excalidraw-app/data/index.ts"), + getCollabServer: jest.fn(() => ({ + url: /* doesn't really matter */ "http://localhost:3002", + })), +})); + jest.mock("../excalidraw-app/data/firebase.ts", () => { const loadFromFirebase = async () => null; const saveToFirebase = () => {};