Photon Cloud 與 Latency , 網路的延遲
在網路架構的世界中, 尤其是有包含 Server 的網路線上活動, 一定會碰到很多資料傳輸的相關問題, 這裡我們來看看常見的網路延遲 Latency, 以及它們對於我們的網路遊戲有什麼影響與可以有什麼樣的改善的方向。
什麼是延遲 Latency
定義上, 當一個封包從某一端(來源端)送出, 直到另一端(目的端)接收到這個封包為止, 中間所經過的時間, 我們稱之為延遲 Latency. 一般會以 msec 為計算單位.
網路的延遲即是訊息或封包從來源端傳送到目的端所花上的時間, 但這個定義簡化了很多複雜的原因, 裡面還有不少跟網路硬體有關的技術層面的問題, 在網路上每個各別運作的系統裡, 多少也都會產生影響網路延遲的原因.
在開發任何應用程式時, 要讓使用者有好的使用體驗並且可以專注在自己要處理的事情上,就必須要設法將延遲控制在很短的時間內(小於 100ms 最好),尤其是在牽涉到網路的多人遊戲上更容易顯現這個問題的嚴重性,所以如果想要設計出好的多人線上遊戲, 在程式發展與設計的各個階段都要小心控制好網路的延遲.
當然, 這些網路相關問題 Photon Server 都在底層做了最佳化的處理, 我們只要知道怎麼使用 Photon Server/Cloud , 並且專注在遊戲設計就好了~ 😃
為什麼會有 Latency
網路延遲(Latency)的因素
在網路上有各種的路由器, 雖然是專門用來傳送轉運網路上的封包, 但也通常會有一些因素造成網路延遲, 類型如下:
- Transmission Delay:送信延遲
網路卡將資料傳送到網路線 (或從網路線接收過來) 所花的時間, 它與網路設備的傳送速度有關 (如 EtherNet 傳送速度為 100Mbps).
假設頻寬為 L (bits), 數據傳輸速率為 R (bits/sec), 送信延遲 = L/R - Propagation Delay:傳播延遲
封包在網路線的傳輸所須花費的時間值與網路線本身的電子訊號傳送的速度有關, 傳送距離除以訊號傳送速度所得到的數值就是傳播延遲時間.
假設傳送距離為 d, 傳輸的速率為 s, 那麼傳播延遲 = d/s - Nodal Processing Delay:交會點處理延遲
路由器本身的工作, 就是在處理封包表頭 (packet header)、檢查位元資料錯誤以及尋找適合的配送路徑等, 而這些工作所消耗的時間即是指這個節點的處理延遲時間. - Queuing Delay:佇列延遲
路由器因為某些原因無法立刻將封包傳送轉運到網路上, 會把封包暫時存在佇列 (queue), 等待之後再傳送, 這樣的等待時間會是佇列延遲.
網路延遲(Latency) 的組成
- Transmission Delay, 送信延遲是由網路設備的資料傳送速度來決定的, 這個部份跟 Server-Client 之間的距離沒有關係. 所以, 當我們用二條網路, 其中一條網路的速度是 10 Mbps,另外一條則是 100 Mbps, 使用這兩條網路各傳送 10 Mb 的檔案資料, 則將資料放進第一條 1 Mbps 的網路中傳送需要 1 秒, 另一條 100 Mbps 的網路則只要 0.1 秒; 所以二者的送信延遲也會差了10倍.
- Propagation Delay, 傳播延遲的時間是取決於訊號傳輸的距離以及傳送的媒介而決定, 但網路訊號傳遞速度幾乎是次於光速, 所以通常是非常小的值, 相比其它的延遲時間之下有時可以不太計算.
- 再來是路由器 Router, 交會點處理延遲, 當一個網路封包傳送到路由器時, 路由器就會檢查封包的表頭, 來決定之後該把封包往哪裡傳送, 除了封包的表頭之外, 有時也會檢查封包內部的一些資料, 而這些動作多多少少都會需要一點點時間,雖然這些動作大多直接由硬體處理, 耗費的時間非常小, 但是還是存在佔用一點點的時間。
- 另外,如果封包傳送給路由器時的速度太快, 路由器會來不及處理, 所以這些封包就會暫時放進緩衝區的佇列中等候, 而這個等候期間, 所花費的時間稱為 Queuing Delay 佇列延遲.
每一個封包在網路上傳送時, 都一定會有這四類的延遲, 來源與目的的傳送距離越遠,所造成的傳播延遲就會越大;傳輸過程中如果經過比較多的路由器, 那麼交會點處理延遲與送信延遲也會越大;網路上的負載量比較高的時候, 也會有較高機率造成路由器處理不及而把封包放入佇列中的動作, 就增加了佇列延遲的時間. 😱
以上幾種因素造成的延遲時間串連加總之後, 就是造成我們一般網路遊戲常聽到常在講的 Client 與Server 之間的網路延遲 Latency 了. 👻
如何測量 Latency
在 Linux 與 MacOS 中可以使用 traceroute
指令來檢測看看,在 Windows 可使用 tracert
它們的主要功能就是追蹤封包在 IP網路中, 所經過的路由器的 IP 位置, 封包量, 以及時間.
每次封包從相同的來源點(Source) 到相同的目地點(Dest) 所走的路徑不見得每次都相同, 但大部份走的會是同樣的路徑. TraceRoute 在每個設備節點上會傳送三次封包, 所以在同個節點我們會看到三個延遲時間 (以 msec 計算).
Translating "www.google.com"...domain server (168.95.192.1) [OK]
Type escape sequence to abort.
Tracing the route to www.google.com (64.233.187.106)
1 TPDB-3516.hinet.net (210.65.161.22) 0 msec 4 msec 0 msec
2 TPDT-3011.hinet.net (220.128.1.146) 4 msec 4 msec 4 msec
3 tyfo-3012.hinet.net (220.128.9.81) 4 msec 4 msec 4 msec
4 220-128-8-173.HINET-IP.hinet.net (220.128.8.173) 0 msec 0 msec 4 msec
5 72.14.205.102 4 msec 4 msec
72.14.196.3 4 msec
6 108.170.244.34 0 msec
108.170.244.99 4 msec 4 msec
7 108.170.238.245 72 msec 28 msec
209.85.249.1 0 msec
8 72.14.238.136 8 msec
108.170.235.215 4 msec
72.14.232.139 8 msec
9 209.85.245.68 12 msec
216.239.50.45 8 msec
209.85.245.16 4 msec
10 * * *
11 * * *
12 * * *
13 * * *
14 * * *
15 * * *
16 * * *
17 * * *
18 www.google.com (64.233.187.106) 4 msec 8 msec 4 msec
像上面的數值是從 hinet.net → google.com 的路徑與時間, 所以在台北的機房 Hinet.net → Google.com 大約只要 4~8 ms 的時間, 我們如果是自己在台灣架設 Photon Server, 那首選機房當然還是…😬…比較好!
對於 Photon Cloud 的伺服器的封包傳送 Latency 檢測, 我們也可以用 Ping 的指令來看本機連到另一個 IP 的封包傳送來回的時間, 或是查看某個 Server 的上線狀況.
$ ping www.google.com
PING www.google.com (74.125.203.103): 56 data bytes
64 bytes from 74.125.203.103: icmp_seq=0 ttl=44 time=24.826 ms
64 bytes from 74.125.203.103: icmp_seq=1 ttl=44 time=24.994 ms
64 bytes from 74.125.203.103: icmp_seq=2 ttl=44 time=25.145 ms
64 bytes from 74.125.203.103: icmp_seq=3 ttl=44 time=25.304 ms--- www.google.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 24.826/25.067/25.304/0.177 ms
像上面的數值, 是從台北的 HiNet ADSL 連到 google.com 的 ping 值, 可以看到 round-trip 封包來回的最小、平均、最大時間之類的數值, 大約在 25ms.
那麼, 從台北連到 Photon Cloud 雲端機房的 Asia / Japan 等地要花多少時間呢~
我們可以用 PUN 提供的 PhotonNetwork.GetPing() 來查查, 它可以傳回即時的 Round-Trip 封包來回時間, 所以這個值是 Client 傳到了 Server 之後, 再回傳給 Client 的數值唷!
void Start () {
Connect();
InvokeRepeating("UpdatePing", 2, 2);
}void Connect() {
PhotonNetwork.ConnectUsingSettings("PUN_PhotonCloud_1.0");
}void UpdatePing() {
int pingRate = PhotonNetwork.GetPing();
Debug.Log( "Ping: " + pingRate );
}
用上面的 Unity + PUN 程式碼, 我們在台北測量 Photon Cloud 的 Asia 與 Japan 二個地方的 Ping 值如下:
Photon Cloud 的 Asia Region 是在 Singapore, 而 Japan Region 是在 Tokyo; 以上二張的簡單測試, 看起來從台北的 Hinet ADSL 連到日本東京會比新加坡還來得快些~
所以各位朋友可以自行驗証看看, 看哪一個比較好, 然後在程式中可以用 PhotonNetwork.ConnectToRegion( region, gameVersion) 來直接設定想要連的區域, 或是用 PhotonNetwork.ConnectToBestCloudServer, 它會自己做檢測後, 自動連上最佳的區域~
要注意的是, 就算我們在申辦網路時, 裝了很大的網路頻寬供上下傳, 但這是不能保證網路傳輸品質本身的穩定度; 有時候會因為網路塞車、設備損壞、或是遭受網路駭客攻擊等事件, 影響網路的頻寬與延遲; 就算是現在的網路技術, 每個情況也都會是個研究議題, 而如何提前處理並預測、管理或調整這些情況的變化, 都會變得很複雜。
如何改善 Latency
網路上常見所謂最後一哩路的問題, 也就是跟我們的連線裝置設備(Client or Server) 所連上的 ISP 有關, 因為每家 ISP 所使用的機房設備技術、網路結構、拓撲技術等, 有各別的因素考量, 每家 ISP都不一定相同.
就算是現今, 也依然會跟我們在什麼時間地點都有相關; 如果只是想讓上網速度更快些, 選擇網路延遲較低的 ISP 當然好, 只是台灣的總體網速相比週邊國家都還要來得慢, 所以也就沒什麼好選的.. 😅
之前也有研究指出, 連線遊戲的延遲時間如果在 100 ~ 200 ms 之間, 我們就會感覺到有點 lag, 極限大約是 300 ms 內, 再多一點就會累格的很有感覺… 而到了 1000 ms (1秒) 的延遲時,我們就會開始轉移注意力到其它的事情上了, 像是暫停遊戲, 跳出遊戲, 重連或是直接去做別的事情了~🐶
所以 Photon Cloud 從台灣連到日本, 來回的 Ping Rate 竟然不到 100ms 的技術, 我們能不用嗎? 😃
因此若要增進網路遊戲程式的效能, 我們必須在遊戲架構的設計上與所使用的通訊協定與方式, 對於網路使用上做些最佳化的動作; 比如像是減少長距離的網路傳輸動作, 讓資料儘量靠近 Client 方, 或是透過快取存取 caching, 聲光特效(FX) 的方式, 讓網路延遲可以隱藏在程式處理或是注意力之外, 這些技巧我們在之後的文章或是範例, 也會多做說明, 敬請期待唷~ 😃