如何在没有实验包的情况下使用 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 文件中配置:
如果您使用的是 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 一起使用,但这只是历史的偶然,不会永远如此。
我的应用程序在 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 文件中配置:
如果您使用的是 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 一起使用,但这只是历史的偶然,不会永远如此。