02 — 브라우저¶
연결과 codec¶
package root에서 connector를 가져오고 필요한 payload codec을 생성 option에 넘긴다. inbound observer는 연결을 시작하기 전에 등록해야 한다.
import {
zlinkStreamConnectorFactory,
ZlinkStreamDispatchMode
} from '@zlink-systems/stream-connector';
import { zlinkStreamMessagePackCodec } from '@zlink-systems/framework-codec-msgpack';
const client = zlinkStreamConnectorFactory.create({
endpoint: 'wss://game.example.com/stream', // 운영 연결은 브라우저가 인증서를 검증하는 wss를 사용한다.
codec: zlinkStreamMessagePackCodec, // 업무 payload의 encode와 decode를 이 codec이 담당한다.
dispatchMode: ZlinkStreamDispatchMode.Immediate
});
client.observeInbound((message) => {
console.log(message.name); // observer는 connect 전에 등록해야 첫 frame부터 관찰한다.
});
await client.connect(); // 플랫폼 WebSocket 연결이 준비될 때까지 기다린다.
개발 환경에서 암호화가 필요하지 않으면 ws://를 사용할 수 있다. wss://의 인증서 검증은
브라우저가 소유하며 connector에서 검증을 건너뛸 수 없다.
dispatch¶
Immediate는 수신 callback을 connector가 바로 처리한다. 게임 main loop에서 처리 시점을 정해야 하면
Manual을 선택하고 해당 loop에서 dispatch()를 호출한다.
async function updateFrame(): Promise<void> {
await client.dispatch(); // Manual mode에서는 main loop가 수신 handler 실행 시점을 결정한다.
}
관련 outbound의 flow 전달¶
브라우저에는 비동기 작업별 현재 값을 격리하는 표준 기능이 없다. inbound handler에서 시작한 관련
outbound만 flowFrom(message)로 표시한다. 표시하지 않은 timer나 UI callback의 outbound는 새
application flow를 시작하므로 동시에 실행되어도 inbound flow가 누출되지 않는다.
client.on('MatchAssigned', async (message) => {
await refreshView(message.payload);
client.send({ accepted: true })
.packetName('MatchAccepted')
.flowFrom(message) // await 뒤에도 이 outbound가 inbound flow에 속한다는 뜻을 명시한다.
.submit();
});
application이 flow id를 전역 변수에 저장하거나 Promise와 timer 동작을 수정해서는 안 된다. 관련 없는
outbound에는 flowFrom(...)을 호출하지 않는다.