여기까지 서버는 값을 답했다. 이제 화면을 답한다.
화면은 파일이다
{ "type": "page", "title": "Desk",
"content": { "type": "center",
"child": { "type": "linear", "direction": "vertical", "spacing": 14, "alignment": "center", "children": [
{ "type": "text", "text": "WAITING", "style": { "fontSize": 16, "letterSpacing": 4, "color": "#6b7280" } },
{ "type": "text", "text": "{{waiting}}", "style": { "fontSize": 88, "fontWeight": "bold", "color": "#111827" } },
{ "type": "button", "label": "Admit one", "onTap": { "type": "tool", "tool": "desk.admit", "params": { "count": 1 } } } ] } } }
여섯 줄이다. {{waiting}} 자리에 값이 들어가고, 버튼이 3편에서 만든 도구를 부른다.
서버가 내준다
server.addResource(
uri: 'ui://desk',
name: 'Desk screen',
description: 'The desk screen, served as a document',
mimeType: 'application/json',
handler: (uri, params) async => ReadResourceResult(contents: [
ResourceContentInfo(
uri: 'ui://desk',
mimeType: 'application/json',
text: File(_screenPath).readAsStringSync(),
)
]),
);
ResourcesCapability 도 켜야 한다.
capabilities: ServerCapabilities(
tools: ToolsCapability(listChanged: true),
resources: ResourcesCapability(listChanged: true),
),
매 요청 읽는 것이 요점이다
readAsStringSync() 가 핸들러 안에 있다. 부팅할 때 한 번 읽어 변수에 담는 게 당연히 빠른데, 그렇게 안 했다.
담아 두면 화면을 고칠 때마다 서버를 재시작해야 한다. 그 순간 이 편이 주장하는 것 — 파일을 고치면 다른 앱이 된다 — 이 거짓이 된다.
/// Read fresh on every request, deliberately. A screen cached at boot is a
/// screen you have to restart the server to change, and then the claim above
/// stops being true.
성능이 문제가 되는 지점이 오면 그때 캐시하되, 파일 변경을 감지해서 무효화해야 한다. 그냥 담는 건 기능을 잃는 것이다.