This showcase demonstrates how to build a realtime Presence Sync Service of Metaverse Workplace - Virtual Headquarters with Geo-distributed Cloud Architecture by YoMo and Socket.IO.
Nowadays, users care about low-latency event transfermation, but backend services usually deployed to a dedicated cloud region, CDN is used for static resources, we need a CDN-like architecture but for upstream data and realtime computing. This showcase introduce a easy way to reach the goal.
There are 3 parts in this Realtime Presence Sync Service:
- Websocket Server: accepts WebSocket connections from Web Browsers
- Presence Sender Service: a YoMo Server responsible for dispatch presence to other nodes
- Presence Receiver Service: a YoMo Server responsible for recieving presence from Senders
By YoMo, we create an event stream from Bob to Alice, sync all presence from Bob to Alice. Assume Bob and Alice are all in Europe, they connect to same mesh node:
But When Bob is in Italy 🇮🇹 while Alice is in US 🇺🇸, the presence flow will be like below, it's done automatically by YoMo:
In this showcase, we separate presence sync flow to 2 parts, one is Sender
, responsible for Dispatching presence
, another is for Receiving presence
. Every Sender
will dispatching presence to every Receivers
:
YoMo care about security, presence in Sender
and Receiver
are encrypt by TLS v1.3 by default on every datagram:
$ go install github.com/yomorun/cli/yomo@latest
See YoMo CLI for details.
- Next.js version: yomo-vhq-nextjs
$ npm run dev
> yomo-vhq-nextjs@0.0.1 dev
> next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info - Loaded env from /Users/fanweixiao/tmp/yomo-vhq-nextjs/.env
info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
event - compiled successfully
event - build page: /next/dist/pages/_error
wait - compiling...
event - compiled successfully
event - build page: /
wait - compiling...
event - compiled successfully
[Index] isDEV= true
$ yomo serve -v -c example/receiver-9000.yaml
Using config file: example/receiver-9000.yaml
ℹ️ Found 0 flows in zipper config
ℹ️ Found 1 sinks in zipper config
ℹ️ Sink 1: PresenceHandler
ℹ️ Running YoMo Serverless...
2021/07/13 16:44:28 ✅ Listening on localhost:9000
$ yomo serve -v -c example/sender-8000.yaml -m http://localhost:3000/dev.json
Using config file: example/sender-8000.yaml
ℹ️ Found 0 flows in zipper config
ℹ️ Found 0 sinks in zipper config
ℹ️ Running YoMo Serverless...
2021/07/13 16:45:10 ✅ Listening on localhost:8000
2021/07/13 16:45:10 Downloading Mesh config...
2021/07/13 16:45:10 ✅ Successfully downloaded the Mesh config. [{Receiver-A localhost 9000}]
$ MESH_ID=Local SENDER=localhost:8000 RECEIVER=localhost:9000 go run cmd/main.go
2021/07/13 16:48:37 MESH_ID: Local
2021/07/13 16:48:37 Starting socket.io server...
2021/07/13 16:48:37 Connecting to zipper localhost:8000...
2021/07/13 16:48:37 ✅ Connected to zipper localhost:8000.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /socket.io/*any --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
------------Receiver init------------ host=localhost, port=9000
2021/07/13 16:48:37 Connecting to zipper localhost:9000...
[GIN-debug] POST /socket.io/*any --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
[GIN-debug] Listening and serving HTTP on 0.0.0.0:19001
2021/07/13 16:48:37 ✅ Connected to zipper localhost:9000.