如何在没有实验包的情况下使用 routerlicious?

How to consume routerlicious without experimental packages?

我的应用程序在 tinylicious 服务器上运行良好,但我想使用 routerlicious 服务器而不使用已弃用的实验包。

服务器 运行 在本地 docker 容器 alfred 运行 端口 3003)

我连接客户端的代码

  client = new AzureClient({
        connection: {
            tenantId: "local",
            tokenProvider: new InsecureTokenProvider("local", { id: "local" }),
            orderer: "http://localhost:3003",
            storage: "http://localhost:3003",
        }
    });

    containerSchema: ContainerSchema = {
        initialObjects: { diagram: SharedMap },
        dynamicObjectTypes: [SharedMap]
    };

以下代码出错(查看堆栈跟踪)

    const { container } = await this.client.createContainer(this.containerSchema);

    const json = JSON.parse(diagram.model.toJson());

    const map = container.initialObjects.diagram as SharedMap;

    map.set("json", json)

    const id = await container.attach();

堆栈跟踪

xhr.js:187 POST http://localhost:3003/documents/local 403 (Forbidden)
    dispatchXhrRequest @ xhr.js:187
    xhrAdapter @ xhr.js:13
    dispatchRequest @ dispatchRequest.js:53
    request @ Axios.js:108
    wrap @ bind.js:9
    (anonymous) @ restWrapper.ts:45
    schedule @ rateLimiter.ts:41
    async function (async)
    schedule @ rateLimiter.ts:40
    request @ restWrapper.ts:45
    post @ restWrapper.ts:51
    createContainer @ documentServiceFactory.ts:85
    async function (async)
    createContainer @ documentServiceFactory.ts:77
    (anonymous) @ container.ts:872
    runWithRetry @ runWithRetry.ts:28
    attach @ container.ts:872
    async function (async)
    attach @ container.ts:869
    attach @ AzureClient.ts:83
    attach @ fluidContainer.ts:59
    createDiagram @ FluidframeworkDiagram.tsx:96
    async function (async)
    createDiagram @ FluidframeworkDiagram.tsx:89
    initDiagram @ FluidframeworkDiagram.tsx:76
    ReactDiagram.componentDidMount @ gojsreact.js:31
    commitLifeCycles @ react-dom.development.js:20663
    commitLayoutEffects @ react-dom.development.js:23426
    callCallback @ react-dom.development.js:3945
    invokeGuardedCallbackDev @ react-dom.development.js:3994
    invokeGuardedCallback @ react-dom.development.js:4056
    commitRootImpl @ react-dom.development.js:23151
    unstable_runWithPriority @ scheduler.development.js:468
    runWithPriority @ react-dom.development.js:11276
    commitRoot @ react-dom.development.js:22990
    performSyncWorkOnRoot @ react-dom.development.js:22329
    (anonymous) @ react-dom.development.js:11327
    unstable_runWithPriority @ scheduler.development.js:468
    runWithPriority @ react-dom.development.js:11276
    flushSyncCallbackQueueImpl @ react-dom.development.js:11322
    flushSyncCallbackQueue @ react-dom.development.js:11309
    flushSync @ react-dom.development.js:22467
    scheduleRefresh @ react-dom.development.js:24429
    (anonymous) @ react-refresh-runtime.development.js:304
    performReactRefresh @ react-refresh-runtime.development.js:293
    (anonymous) @ RefreshUtils.js:62
    setTimeout (async)
    enqueueUpdate @ RefreshUtils.js:60
    (anonymous) @ FluidframeworkDiagram.tsx:190
    ./src/pages/FluidframeworkDiagram.tsx @ FluidframeworkDiagram.tsx:190
    __webpack_require__ @ bootstrap:856
    hotApplyInternal @ bootstrap:749
    hotApply @ bootstrap:411
    (anonymous) @ bootstrap:386
    Promise.then (async)
    hotUpdateDownloaded @ bootstrap:385
    hotAddUpdateChunk @ bootstrap:361
    webpackHotUpdateCallback @ bootstrap:57
    (anonymous) @ main.4bde7b0b05d944bfa188.hot-update.js:1
    index.js:1 fluid:telemetry:Container containerAttach {"retry":0,"duration":43,"category":"error","error":"Request failed with status code 403","errorType":"authorizationError","errorInstanceId":"ce2a437d-8e10-4107-b7fc-46b3fccb5e75","statusCode":403,"fluidErrorCode":"Request failed with status code 403","canRetry":false,"message":"Request failed with status code 403","clientType":"interactive","loaderVersion":"0.47.1","containerId":"5e715267-6c7a-4cd0-be23-944edbcc8c7d","docId":"","containerAttachState":"Attaching","containerLoaded":true,"dmInitialSeqNumber":0,"dmLastKnownSeqNumber":0,"loaderId":"92424f7f-11de-4644-97a7-e19696c11251"} tick=44612 Error    at createR11sNetworkError (http://localhost:3000/static/js/vendors~main.chunk.js:26300:14)    at throwR11sNetworkError (http://localhost:3000/static/js/vendors~main.chunk.js:26326:24)    at RouterliciousOrdererRestWrapper.request (http://localhost:3000/static/js/vendors~main.chunk.js:26543:80)    at async RouterliciousDocumentServiceFactory.createContainer (http://localhost:3000/static/js/vendors~main.chunk.js:25875:24)    at async runWithRetry (http://localhost:3000/static/js/vendors~main.chunk.js:21523:16)    at async Container.attach (http://localhost:3000/static/js/vendors~main.chunk.js:4915:24)    at async FluidContainer.attach [as attachCallback] (http://localhost:3000/static/js/vendors~main.chunk.js:2237:7)    at async FluidframeworkDiagram.createDiagram (http://localhost:3000/main.4bde7b0b05d944bfa188.hot-update.js:112:16) +0ms
    console.<computed> @ index.js:1
    debug @ common.js:113
    send @ debugLogger.ts:124
    send @ logger.ts:327
    sendTelemetryEventCore @ logger.ts:150
    sendErrorEvent @ logger.ts:160
    runWithRetry @ runWithRetry.ts:39
    async function (async)
    runWithRetry @ runWithRetry.ts:28
    attach @ container.ts:872
    async function (async)
    attach @ container.ts:869
    attach @ AzureClient.ts:83
    attach @ fluidContainer.ts:59
    createDiagram @ FluidframeworkDiagram.tsx:96
    async function (async)
    createDiagram @ FluidframeworkDiagram.tsx:89
    initDiagram @ FluidframeworkDiagram.tsx:76
    ReactDiagram.componentDidMount @ gojsreact.js:31
    commitLifeCycles @ react-dom.development.js:20663
    commitLayoutEffects @ react-dom.development.js:23426
    callCallback @ react-dom.development.js:3945
    invokeGuardedCallbackDev @ react-dom.development.js:3994
    invokeGuardedCallback @ react-dom.development.js:4056
    commitRootImpl @ react-dom.development.js:23151
    unstable_runWithPriority @ scheduler.development.js:468
    runWithPriority @ react-dom.development.js:11276
    commitRoot @ react-dom.development.js:22990
    performSyncWorkOnRoot @ react-dom.development.js:22329
    (anonymous) @ react-dom.development.js:11327
    unstable_runWithPriority @ scheduler.development.js:468
    runWithPriority @ react-dom.development.js:11276
    flushSyncCallbackQueueImpl @ react-dom.development.js:11322
    flushSyncCallbackQueue @ react-dom.development.js:11309
    flushSync @ react-dom.development.js:22467
    scheduleRefresh @ react-dom.development.js:24429
    (anonymous) @ react-refresh-runtime.development.js:304
    performReactRefresh @ react-refresh-runtime.development.js:293
    (anonymous) @ RefreshUtils.js:62
    setTimeout (async)
    enqueueUpdate @ RefreshUtils.js:60
    (anonymous) @ FluidframeworkDiagram.tsx:190
    ./src/pages/FluidframeworkDiagram.tsx @ FluidframeworkDiagram.tsx:190
    __webpack_require__ @ bootstrap:856
    hotApplyInternal @ bootstrap:749
    hotApply @ bootstrap:411
    (anonymous) @ bootstrap:386
    Promise.then (async)
    hotUpdateDownloaded @ bootstrap:385
    hotAddUpdateChunk @ bootstrap:361
    webpackHotUpdateCallback @ bootstrap:57
    (anonymous) @ main.4bde7b0b05d944bfa188.hot-update.js:1
    FluidframeworkDiagram.tsx:98 Uncaught (in promise) Error: Request failed with status code 403
        at createR11sNetworkError (errorUtils.ts:62)
        at throwR11sNetworkError (errorUtils.ts:82)
        at RouterliciousOrdererRestWrapper.request (restWrapper.ts:81)
        at async RouterliciousDocumentServiceFactory.createContainer (documentServiceFactory.ts:85)
        at async runWithRetry (runWithRetry.ts:28)
        at async Container.attach (container.ts:872)
        at async FluidContainer.attach [as attachCallback] (AzureClient.ts:83)
        at async FluidframeworkDiagram.createDiagram (FluidframeworkDiagram.tsx:96)

package.json

{
    "name": "my-app",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@fluidframework/azure-client": "^0.47.1",
        "@fluidframework/server-services-client": "^0.1030.0",
        "@fluidframework/tinylicious-client": "^0.47.0",
        "@teamwork/websocket-json-stream": "^2.0.0",
        "@testing-library/jest-dom": "^5.14.1",
        "@testing-library/react": "^11.2.7",
        "@testing-library/user-event": "^12.8.3",
        "@types/jest": "^26.0.24",
        "@types/node": "^12.20.24",
        "@types/react": "^17.0.20",
        "@types/react-dom": "^17.0.9",
        "@types/react-router-dom": "^5.1.8",
        "fluid-framework": "^0.47.0",
        "gojs": "^2.1.48",
        "gojs-react": "^1.1.0",
        "luxon": "^2.0.2",
        "react": "^17.0.2",
        "react-dom": "^17.0.2",
        "react-router": "^5.2.1",
        "react-router-dom": "^5.3.0",
        "react-scripts": "4.0.3",
        "typescript": "^4.4.2",
        "uuid": "^8.3.2",
        "web-vitals": "^1.1.2"
    },
    "scripts": {
        "start": "react-scripts start",
        "start-server-fluid": "npx tinylicious",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": [
            "react-app",
            "react-app/jest"
        ]
    },
    "browserslist": {
        "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
        ],
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
        ]
    }
}

您收到 403 是因为您的请求未经过身份验证(即使用 Routerlicious 服务接受的令牌签名)。 Tinylicious 没有授权,但 Routerlicious 有。 R11s 身份验证模型与 Azure Fluid Relay 中使用的模型非常相似,因此此处的文档是有用的背景:

https://docs.microsoft.com/azure/azure-fluid-relay/concepts/authentication-authorization

TL;auth 模型的 DR 总结是它是基于租户的;每个租户都有一个密钥,必须使用该密钥来签署不记名令牌,以便 R11s 服务接受请求。

R11s 租户在此处的 server/routerlicious/packages/routerlicious/config/config.json 文件中配置:

https://github.com/microsoft/FluidFramework/blob/release/0.50/server/routerlicious/packages/routerlicious/config/config.json#L77-L90

如果您使用的是 R11s docker 图像,那么您可以使用默认的 fluid 租户 ID 和配置文件中的租户密码,以及 InsecureTokenProvider。例如:

// IMPORTANT: RouterliciousClient does not exist!
const client = new RouterliciousClient({
    connection: {
        tenantId: "fluid", // This is a default tenant that exists in the default R11s config.
        tokenProvider: new InsecureTokenProvider("create-new-tenants-if-going-to-production", {
            id: "userId",
            name: "Test User",
        }),
        orderer: "http://localhost:3005",
        storage: "http://localhost:3001",
    }
});

如果您想添加更多租户,您可以将它们放入该文件并重新启动 service/rebuild docker 映像。

最后,注意没有RouterliciousClient。您可以将 AzureClient 与 R11s 一起使用,但这只是历史的偶然,不会永远如此。