今天主要展開Redis的連結和使用,目標是完成一個簡單leaderboard功能。雖然之前寫過javascript,不過太久沒有用了,這次就花點時間試用typescript,但除了變得比較多class的語法外,大概一時之間也很難擺拖很像javascript的typescript寫法。不過寫成什麼樣,最重要的是功能達到就可以了。
整個規劃是利用websocket進行client和server的連線。而這個連線並不是一直開啓的,而當leaderboard資訊被要求時,也就是對應該UI開啓時,才會進行連線,而UI關閉時,則會關閉連線。而使用websocket的原因是leaderboard的資訊是即時的,server端更新時client理當會看到改變,而不是持續連線的想法是整個遊戲只有在gameplay scene時才需要一直連線,其餘時間都是非必要不進行連線的。
其它部份其實是使用Graphql,它也是有subscription的概念,而多數的連線機制都是用websocket,不過,在Unity的環境中不確定Graphql的subscription是否可行。故多數時候用Graphql的query, mutation,至於需要用到雙向連線更新的機制時,就另外用websocket處理。
說到websocket,server端的選擇最方便的就是nodejs,雖然目前的想法多數的service都用golang,但還是配合語言和框架的適性比較好,而這裡也不完全是用websocket,而是包裝過的socketio。說到soocketio,server端的首選非nodejs莫屬,Unity端,雖然有幾個開源的方案,但都沒有Best Http來的好,所以前後端就選定其語言和library。
大致上連線的部份
this.server = new http.Server();
const io: socketIO.Server = socketIO(this.server)
//
io.on('connection', (socket: socketIO.Socket) => {
console.log(`a user connected: ${socket.id}`)
//
socket.emit("message", { name: "ABC", age: 12})
//
socket.on('disconnect', () => {
console.log(`the user disconnected: ${socket.id}`)
})
})
Socketio在leaderboard的規劃裡,最主要的還是用
io.emit("event", {})
一次可以將訊息傳給所有連接的人,像是分數的調整,需要即時的更新給所有連接的client端,也就是所有正開啓leaderboard的玩家,都會收到資訊的更新。而
socket.emit("event")
則是可以在一開連接時將現有的資訊直接的傳給玩家,對於多數的使用情況下,這已是相當足夠的。然而,一次給的分數如果是數百筆,不知道傳資料是否會造成流量的問題。而且,傳的資料在nodejs端直覺的是用json,但到了C#端,就成了Dictonary<string, object>
,當然在確定資料結的情況下,直接用json net等方式,轉成class,保證型別引用。這裡或許會用protobuf的格式,還沒有試過,但應該可行。
回到Unity端,要開始製作能夠接收server端回傳資料的顯示。找回了之前用的Optimized ScrollView Adapter,但有陣子沒有用了,還找回之前寫的程式碼,試著喚醒記憶。
有之前的Code對照沒有花太多時間在再次的將功能加回來,但用現有的UI的問題就是它雖然看起來美美的,但完全不符合使用需求,光是調整這部份就著實花去不少時間。今天看樣子也只能將Client端完成,和server接合要等到明天了。