This commit is contained in:
Martin Slachta
2026-08-03 16:26:59 +02:00
parent 2654dabff4
commit 08170c8389
17 changed files with 794 additions and 825 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

+178 -194
View File
@@ -9,8 +9,8 @@
\providecommand\HyField@AuxAddToCoFields[2]{}
\providecommand\BKM@entry[2]{}
\abx@aux@refcontext{none/global//global/global/global}
\BKM@entry{id=1,open,dest={6B693A7061706572},srcline={150}}{5C3337365C3337375C3030304D5C303030655C303030745C3030306F5C303030645C303030795C3030305C3034305C3030306F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030705C3030315C3133315C303030655C3030306E5C3030306F5C303030735C303030755C3030305C3034305C303030645C303030615C303030745C3030305C3034305C303030765C3030305C3034305C303030645C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030306D5C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303075}
\BKM@entry{id=2,open,dest={6B693A7469746C65},srcline={150}}{5C3337365C3337375C303030545C303030695C303030745C303030755C3030306C5C3030306E5C3030305C3335355C3030305C3034305C303030735C303030745C303030725C303030615C3030306E5C30303061}
\BKM@entry{id=1,open,dest={6B693A7061706572},srcline={148}}{5C3337365C3337375C3030304D5C303030655C303030745C3030306F5C303030645C303030795C3030305C3034305C3030306F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030705C3030315C3133315C303030655C3030306E5C3030306F5C303030735C303030755C3030305C3034305C303030645C303030615C303030745C3030305C3034305C303030765C3030305C3034305C303030645C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030306D5C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303075}
\BKM@entry{id=2,open,dest={6B693A7469746C65},srcline={148}}{5C3337365C3337375C303030545C303030695C303030745C303030755C3030306C5C3030306E5C3030305C3335355C3030305C3034305C303030735C303030745C303030725C303030615C3030306E5C30303061}
\providecommand\@newglossary[4]{}
\@newglossary{main}{glg}{gls}{glo}
\@newglossary{acronym}{alg}{acr}{acn}
@@ -20,208 +20,192 @@
\@istfilename{kidiplom.ist}
\@glsorder{word}
\babel@aux{czech}{}
\BKM@entry{id=3,open,dest={6B693A616E6F746174696F6E},srcline={150}}{5C3337365C3337375C303030415C3030306E5C3030306F5C303030745C303030615C303030635C30303065}
\BKM@entry{id=4,open,dest={6B693A746F63},srcline={150}}{5C3337365C3337375C3030304F5C303030625C303030735C303030615C30303068}
\BKM@entry{id=5,open,dest={73656374696F6E2E31},srcline={161}}{5C3337365C3337375C303030315C3030305C3034305C3030305C3333325C303030765C3030306F5C30303064}
\BKM@entry{id=3,open,dest={6B693A616E6F746174696F6E},srcline={148}}{5C3337365C3337375C303030415C3030306E5C3030306F5C303030745C303030615C303030635C30303065}
\BKM@entry{id=4,open,dest={6B693A746F63},srcline={148}}{5C3337365C3337375C3030304F5C303030625C303030735C303030615C30303068}
\BKM@entry{id=5,open,dest={73656374696F6E2E31},srcline={159}}{5C3337365C3337375C303030315C3030305C3034305C3030305C3333325C303030765C3030306F5C30303064}
\@writefile{toc}{\contentsline {section}{\numberline {1}Úvod}{8}{section.1}\protected@file@percent }
\BKM@entry{id=6,open,dest={73656374696F6E2E32},srcline={203}}{5C3337365C3337375C303030325C3030305C3034305C303030535C3030305C3335355C3030315C3134355C3030306F5C303030765C3030305C3335315C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303079}
\BKM@entry{id=7,open,dest={73656374696F6E2E33},srcline={207}}{5C3337365C3337375C303030335C3030305C3034305C303030445C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303079}
\BKM@entry{id=8,open,dest={73756273656374696F6E2E332E31},srcline={223}}{5C3337365C3337375C303030335C3030302E5C303030315C3030305C3034305C303030415C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\BKM@entry{id=9,open,dest={73756273756273656374696F6E2E332E312E31},srcline={229}}{5C3337365C3337375C303030335C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030535C3030306F5C303030665C303030745C303030775C303030615C303030725C3030306F5C303030765C3030305C3334315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303061}
\@writefile{toc}{\contentsline {section}{\numberline {2}Síťové systémy}{9}{section.2}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {3}Distribuované systémy}{9}{section.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Architektury}{9}{subsection.3.1}\protected@file@percent }
\BKM@entry{id=10,open,dest={73756273756273656374696F6E2E332E312E32},srcline={243}}{5C3337365C3337375C303030335C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030795C303030735C303030745C3030305C3335315C3030306D5C3030306F5C303030765C3030305C3335315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.1}Softwarová architektura}{10}{subsubsection.3.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.2}Systémové architektury}{10}{subsubsection.3.1.2}\protected@file@percent }
\newlabel{sec:system_architecture}{{3.1.2}{10}{Systémové architektury}{subsubsection.3.1.2}{}}
\BKM@entry{id=11,open,dest={73756273656374696F6E2E332E32},srcline={258}}{5C3337365C3337375C303030335C3030302E5C303030325C3030305C3034305C3030304B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=12,open,dest={73756273756273656374696F6E2E332E322E31},srcline={269}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030315C3030305C3034305C3030304D5C3030306F5C303030645C303030655C3030306C5C303030795C3030305C3034305C303030705C303030725C3030306F5C3030305C3034305C3030306B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303069}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Komunikace}{11}{subsection.3.2}\protected@file@percent }
\BKM@entry{id=13,open,dest={73756273656374696F6E2E332E33},srcline={294}}{5C3337365C3337375C303030335C3030302E5C303030335C3030305C3034305C303030505C3030306F5C3030315C3031355C3030305C3335355C303030745C303030615C3030315C3031355C3030306F5C303030765C3030305C3334315C3030305C3034305C303030535C3030305C3335355C3030315C313435}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}Modely pro komunikaci}{12}{subsubsection.3.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Počítačová Síť}{12}{subsection.3.3}\protected@file@percent }
\newlabel{sec:NetworkCommunication}{{3.3}{12}{Počítačová Síť}{subsection.3.3}{}}
\BKM@entry{id=14,open,dest={73756273656374696F6E2E332E34},srcline={303}}{5C3337365C3337375C303030335C3030302E5C303030345C3030305C3034305C3030304B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C303030655C3030305C3034305C303030765C3030305C3034305C303030735C3030305C3335355C303030745C30303069}
\BKM@entry{id=15,open,dest={73756273756273656374696F6E2E332E342E31},srcline={311}}{5C3337365C3337375C303030335C3030302E5C303030345C3030302E5C303030315C3030305C3034305C303030525C3030306F5C303030645C303030695C3030306E5C303030615C3030305C3034305C303030705C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030315C3135375C3030305C3034305C303030545C303030435C303030505C3030302F5C303030495C30303050}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Komunikace v síti}{13}{subsection.3.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.4.1}Rodina protokolů TCP/IP}{13}{subsubsection.3.4.1}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Vrstvená architektura TODO předělat}}{14}{figure.1}\protected@file@percent }
\newlabel{fig:layer_architecture}{{1}{14}{Vrstvená architektura TODO předělat}{figure.1}{}}
\BKM@entry{id=16,open,dest={73756273656374696F6E2E332E35},srcline={360}}{5C3337365C3337375C303030335C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C3030315C3031355C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Komunikace vrstev TCP/IP}}{15}{figure.2}\protected@file@percent }
\newlabel{fig:tcpip}{{2}{15}{Komunikace vrstev TCP/IP}{figure.2}{}}
\BKM@entry{id=17,open,dest={73756273756273656374696F6E2E332E352E31},srcline={364}}{5C3337365C3337375C303030335C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030485C303030545C303030545C30303050}
\BKM@entry{id=18,open,dest={73756273756273656374696F6E2E332E352E32},srcline={385}}{5C3337365C3337375C303030335C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030545C303030545C303030505C3030302F5C30303033}
\BKM@entry{id=19,open,dest={73756273656374696F6E2E332E36},srcline={411}}{5C3337365C3337375C303030335C3030302E5C303030365C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030745C303030725C303030615C3030306E5C303030735C303030705C3030306F5C303030725C303030745C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Protokoly v aplikační vrstvě}{16}{subsection.3.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.5.1}HTTP}{16}{subsubsection.3.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.5.2}HTTP/3}{16}{subsubsection.3.5.2}\protected@file@percent }
\BKM@entry{id=20,open,dest={73756273756273656374696F6E2E332E362E31},srcline={417}}{5C3337365C3337375C303030335C3030302E5C303030365C3030302E5C303030315C3030305C3034305C303030545C303030435C30303050}
\BKM@entry{id=6,open,dest={73656374696F6E2E32},srcline={204}}{5C3337365C3337375C303030325C3030305C3034305C303030505C3030306F5C3030315C3031355C3030305C3335355C303030745C303030615C3030315C3031355C3030306F5C303030765C3030305C3334315C3030305C3034305C303030735C3030305C3335355C3030315C313435}
\BKM@entry{id=7,open,dest={73756273656374696F6E2E322E31},srcline={213}}{5C3337365C3337375C303030325C3030302E5C303030315C3030305C3034305C3030304B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {2}Počítačová síť}{9}{section.2}\protected@file@percent }
\newlabel{sec:NetworkCommunication}{{2}{9}{Počítačová síť}{section.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Komunikace}{9}{subsection.2.1}\protected@file@percent }
\BKM@entry{id=8,open,dest={73756273756273656374696F6E2E322E312E31},srcline={223}}{5C3337365C3337375C303030325C3030302E5C303030315C3030302E5C303030315C3030305C3034305C3030304D5C3030306F5C303030645C303030655C3030306C5C303030795C3030305C3034305C303030705C303030725C3030306F5C3030305C3034305C3030306B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303069}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.1}Modely pro komunikaci}{10}{subsubsection.2.1.1}\protected@file@percent }
\BKM@entry{id=9,open,dest={73656374696F6E2E33},srcline={252}}{5C3337365C3337375C303030335C3030305C3034305C303030445C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303079}
\BKM@entry{id=10,open,dest={73756273656374696F6E2E332E31},srcline={267}}{5C3337365C3337375C303030335C3030302E5C303030315C3030305C3034305C303030415C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\BKM@entry{id=11,open,dest={73756273756273656374696F6E2E332E312E31},srcline={273}}{5C3337365C3337375C303030335C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030535C3030306F5C303030665C303030745C303030775C303030615C303030725C3030306F5C303030765C3030305C3334315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303061}
\@writefile{toc}{\contentsline {section}{\numberline {3}Distribuované systémy}{11}{section.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Architektury}{11}{subsection.3.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.1}Softwarová architektura}{11}{subsubsection.3.1.1}\protected@file@percent }
\BKM@entry{id=12,open,dest={73756273756273656374696F6E2E332E312E32},srcline={289}}{5C3337365C3337375C303030335C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030795C303030735C303030745C3030305C3335315C3030306D5C3030306F5C303030765C3030305C3335315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.2}Systémové architektury}{12}{subsubsection.3.1.2}\protected@file@percent }
\newlabel{sec:system_architecture}{{3.1.2}{12}{Systémové architektury}{subsubsection.3.1.2}{}}
\BKM@entry{id=13,open,dest={73756273656374696F6E2E332E32},srcline={304}}{5C3337365C3337375C303030335C3030302E5C303030325C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C30303079}
\BKM@entry{id=14,open,dest={73756273756273656374696F6E2E332E322E31},srcline={320}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030315C3030305C3034305C303030525C3030306F5C303030645C303030695C3030306E5C303030615C3030305C3034305C303030705C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030315C3135375C3030305C3034305C303030545C303030435C303030505C3030302F5C303030495C30303050}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Vrstvená architektura}}{13}{figure.1}\protected@file@percent }
\newlabel{fig:layer_architecture}{{1}{13}{Vrstvená architektura}{figure.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Protokoly}{13}{subsection.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}Rodina protokolů TCP/IP}{14}{subsubsection.3.2.1}\protected@file@percent }
\BKM@entry{id=15,open,dest={73756273656374696F6E2E332E33},srcline={363}}{5C3337365C3337375C303030335C3030302E5C303030335C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C3030315C3031355C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=16,open,dest={73756273756273656374696F6E2E332E332E31},srcline={367}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030315C3030305C3034305C303030485C303030545C303030545C30303050}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Protokoly v aplikační vrstvě}{15}{subsection.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.1}HTTP}{15}{subsubsection.3.3.1}\protected@file@percent }
\BKM@entry{id=17,open,dest={73756273756273656374696F6E2E332E332E32},srcline={388}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030485C303030545C303030545C303030505C3030302F5C30303033}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Komunikace vrstev TCP/IP}}{16}{figure.2}\protected@file@percent }
\newlabel{fig:tcpip}{{2}{16}{Komunikace vrstev TCP/IP}{figure.2}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.2}HTTP/3}{16}{subsubsection.3.3.2}\protected@file@percent }
\BKM@entry{id=18,open,dest={73756273656374696F6E2E332E34},srcline={414}}{5C3337365C3337375C303030335C3030302E5C303030345C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030745C303030725C303030615C3030306E5C303030735C303030705C3030306F5C303030725C303030745C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=19,open,dest={73756273756273656374696F6E2E332E342E31},srcline={420}}{5C3337365C3337375C303030335C3030302E5C303030345C3030302E5C303030315C3030305C3034305C303030545C303030435C30303050}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Vizualizace HTTP/2 blokování}}{17}{figure.3}\protected@file@percent }
\newlabel{fig:http_blocking}{{3}{17}{Vizualizace HTTP/2 blokování}{figure.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Protokoly v transportní vrstvě}{17}{subsection.3.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.6.1}TCP}{17}{subsubsection.3.6.1}\protected@file@percent }
\BKM@entry{id=21,open,dest={73756273756273656374696F6E2E332E362E32},srcline={431}}{5C3337365C3337375C303030335C3030302E5C303030365C3030302E5C303030325C3030305C3034305C303030555C303030445C30303050}
\BKM@entry{id=22,open,dest={73756273756273656374696F6E2E332E362E33},srcline={439}}{5C3337365C3337375C303030335C3030302E5C303030365C3030302E5C303030335C3030305C3034305C303030515C303030555C303030495C30303043}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.6.2}UDP}{18}{subsubsection.3.6.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.6.3}QUIC}{18}{subsubsection.3.6.3}\protected@file@percent }
\BKM@entry{id=23,open,dest={73756273656374696F6E2E332E37},srcline={489}}{5C3337365C3337375C303030335C3030302E5C303030375C3030305C3034305C303030535C3030306F5C3030306B5C303030655C303030745C30303079}
\BKM@entry{id=24,open,dest={73756273656374696F6E2E332E38},srcline={495}}{5C3337365C3337375C303030335C3030302E5C303030385C3030305C3034305C303030415C303030735C303030795C3030306E5C303030635C303030685C303030725C3030306F5C3030306E5C3030305C3335355C3030305C3034305C303030765C303030735C303030745C303030755C303030705C3030306E5C3030315C3033335C3030305C3034305C303030765C3030305C3337355C303030735C303030745C303030755C303030705C3030306E5C3030305C3335355C3030305C3034305C3030306F5C303030705C303030655C303030725C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Protokoly v transportní vrstvě}{17}{subsection.3.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.4.1}TCP}{17}{subsubsection.3.4.1}\protected@file@percent }
\BKM@entry{id=20,open,dest={73756273756273656374696F6E2E332E342E32},srcline={434}}{5C3337365C3337375C303030335C3030302E5C303030345C3030302E5C303030325C3030305C3034305C303030555C303030445C30303050}
\BKM@entry{id=21,open,dest={73756273756273656374696F6E2E332E342E33},srcline={442}}{5C3337365C3337375C303030335C3030302E5C303030345C3030302E5C303030335C3030305C3034305C303030515C303030555C303030495C30303043}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.4.2}UDP}{18}{subsubsection.3.4.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.4.3}QUIC}{18}{subsubsection.3.4.3}\protected@file@percent }
\BKM@entry{id=22,open,dest={73656374696F6E2E34},srcline={606}}{5C3337365C3337375C303030345C3030305C3034305C303030485C303030725C30303061}
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces QUIC handshake}}{21}{figure.4}\protected@file@percent }
\newlabel{fig:quic_handshake}{{4}{21}{QUIC handshake}{figure.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Sokety}{21}{subsection.3.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.8}Asynchroní vstupně výstupní operace}{21}{subsection.3.8}\protected@file@percent }
\BKM@entry{id=25,open,dest={73756273756273656374696F6E2E332E382E31},srcline={501}}{5C3337365C3337375C303030335C3030302E5C303030385C3030302E5C303030315C3030305C3034305C3030305A5C303030655C303030725C3030306F5C3030304D5C30303051}
\BKM@entry{id=26,open,dest={73756273756273656374696F6E2E332E382E32},srcline={507}}{5C3337365C3337375C303030335C3030302E5C303030385C3030302E5C303030325C3030305C3034305C303030575C3030306F5C303030725C3030306B5C3030305C3034305C303030735C303030745C303030655C303030615C3030306C5C303030695C3030306E5C30303067}
\BKM@entry{id=27,open,dest={73756273756273656374696F6E2E332E382E33},srcline={511}}{5C3337365C3337375C303030335C3030302E5C303030385C3030302E5C303030335C3030305C3034305C303030415C303030735C303030795C3030306E5C303030635C3030302F5C303030415C303030775C303030615C303030695C30303074}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.8.1}ZeroMQ}{22}{subsubsection.3.8.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.8.2}Work stealing}{22}{subsubsection.3.8.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.8.3}Async/Await}{22}{subsubsection.3.8.3}\protected@file@percent }
\BKM@entry{id=28,open,dest={73756273756273656374696F6E2E332E382E34},srcline={520}}{5C3337365C3337375C303030335C3030302E5C303030385C3030302E5C303030345C3030305C3034305C303030425C3030306F5C3030306F5C303030735C303030745C3030305C3034305C303030415C303030735C303030695C3030306F}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.8.4}Boost Asio}{23}{subsubsection.3.8.4}\protected@file@percent }
\BKM@entry{id=29,open,dest={73656374696F6E2E34},srcline={588}}{5C3337365C3337375C303030345C3030305C3034305C303030485C303030725C30303061}
\BKM@entry{id=30,open,dest={73756273656374696F6E2E342E31},srcline={603}}{5C3337365C3337375C303030345C3030302E5C303030315C3030305C3034305C303030455C3030306E5C303030675C303030695C3030306E5C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {4}Hra}{24}{section.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Engine}{24}{subsection.4.1}\protected@file@percent }
\BKM@entry{id=31,open,dest={73756273756273656374696F6E2E342E312E31},srcline={628}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030465C303030795C3030307A5C303030695C303030635C3030306B5C3030305C3337355C3030305C3034305C303030655C3030306E5C303030675C303030695C3030306E5C30303065}
\BKM@entry{id=32,open,dest={73756273756273656374696F6E2E342E312E32},srcline={636}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030565C303030795C3030306B5C303030725C303030655C303030735C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=33,open,dest={73756273756273656374696F6E2E342E312E33},srcline={644}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030455C3030306E5C303030745C303030695C303030745C303030795C3030302D5C303030435C3030306F5C3030306D5C303030705C3030306F5C3030306E5C303030655C3030306E5C303030745C3030302D5C303030535C303030795C303030735C303030745C303030655C3030306D}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{25}{subsubsection.4.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{25}{subsubsection.4.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{25}{subsubsection.4.1.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}Příklad použití knihovny Entt}{26}{lstlisting.1}\protected@file@percent }
\BKM@entry{id=34,open,dest={73656374696F6E2E35},srcline={699}}{5C3337365C3337375C303030355C3030305C3034305C303030485C303030725C303030615C3030305C3034305C303030765C3030305C3335355C303030635C303030655C3030305C3034305C303030685C303030725C3030305C3334315C3030315C3031355C3030315C313537}
\BKM@entry{id=35,open,dest={73756273656374696F6E2E352E31},srcline={721}}{5C3337365C3337375C303030355C3030302E5C303030315C3030305C3034305C303030535C303030655C303030725C303030765C303030655C30303072}
\@writefile{toc}{\contentsline {section}{\numberline {5}Hra více hráčů}{28}{section.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Server}{28}{subsection.5.1}\protected@file@percent }
\BKM@entry{id=36,open,dest={73756273756273656374696F6E2E352E312E31},srcline={731}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030525C303030655C303030675C303030695C303030735C303030745C303030725C3030305C3034305C3030306B5C3030306C5C303030695C303030655C3030306E5C303030745C3030315C313537}
\BKM@entry{id=37,open,dest={73756273756273656374696F6E2E352E312E32},srcline={737}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Softwarová architektura hry}}{29}{figure.5}\protected@file@percent }
\newlabel{fig:client_server_architecture}{{5}{29}{Softwarová architektura hry}{figure.5}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{29}{subsubsection.5.1.1}\protected@file@percent }
\BKM@entry{id=38,open,dest={73756273756273656374696F6E2E352E312E33},srcline={741}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030535C303030705C303030725C3030305C3334315C303030765C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\BKM@entry{id=39,open,dest={73756273656374696F6E2E352E32},srcline={751}}{5C3337365C3337375C303030355C3030302E5C303030325C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C30303074}
\BKM@entry{id=40,open,dest={73756273756273656374696F6E2E352E322E31},srcline={755}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030315C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=41,open,dest={73756273756273656374696F6E2E352E322E32},srcline={759}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030495C3030306E5C303030745C303030655C303030725C303030705C3030306F5C3030306C5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{30}{subsubsection.5.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{30}{subsubsection.5.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Klient}{30}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{30}{subsubsection.5.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{30}{subsubsection.5.2.2}\protected@file@percent }
\BKM@entry{id=42,open,dest={73756273756273656374696F6E2E352E322E33},srcline={763}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030335C3030305C3034305C303030525C3030306F5C3030306C5C3030306C5C303030625C303030615C303030635C3030306B}
\BKM@entry{id=43,open,dest={73756273656374696F6E2E352E33},srcline={773}}{5C3337365C3337375C303030355C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E352E332E31},srcline={786}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E352E332E32},srcline={794}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{31}{subsubsection.5.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{31}{subsection.5.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{31}{subsubsection.5.3.1}\protected@file@percent }
\BKM@entry{id=46,open,dest={73756273756273656374696F6E2E352E332E33},srcline={798}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=47,open,dest={73756273656374696F6E2E352E34},srcline={805}}{5C3337365C3337375C303030355C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{32}{subsubsection.5.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{32}{subsubsection.5.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Serializace}{32}{subsection.5.4}\protected@file@percent }
\BKM@entry{id=48,open,dest={73756273656374696F6E2E352E35},srcline={837}}{5C3337365C3337375C303030355C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}cpp}{33}{lstlisting.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{33}{subsection.5.5}\protected@file@percent }
\BKM@entry{id=49,open,dest={73756273756273656374696F6E2E352E352E31},srcline={850}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030635C30303065}
\BKM@entry{id=50,open,dest={73756273756273656374696F6E2E352E352E32},srcline={863}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{34}{subsubsection.5.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{34}{subsubsection.5.5.2}\protected@file@percent }
\BKM@entry{id=51,open,dest={73756273756273656374696F6E2E352E352E33},srcline={897}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Stavový stroj QUICr handshake}}{35}{figure.6}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{6}{35}{Stavový stroj QUICr handshake}{figure.6}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{35}{subsubsection.5.5.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{5.5.3}{35}{Spolehlivost}{subsubsection.5.5.3}{}}
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E352E352E34},srcline={919}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E352E352E35},srcline={927}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{36}{subsubsection.5.5.4}\protected@file@percent }
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E352E352E36},srcline={958}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030365C3030305C3034305C303030435C3030306F5C3030306E5C303030675C303030655C303030735C303030745C303030695C3030306F5C3030306E5C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=55,open,dest={73756273756273656374696F6E2E352E352E37},srcline={960}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030375C3030305C3034305C303030425C303030615C3030306E5C303030645C303030775C303030695C303030645C303030745C303030685C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=56,open,dest={73756273656374696F6E2E352E36},srcline={964}}{5C3337365C3337375C303030355C3030302E5C303030365C3030305C3034305C303030535C303030685C303030615C303030725C303030645C303030695C3030306E5C30303067}
\BKM@entry{id=57,open,dest={73756273656374696F6E2E352E37},srcline={968}}{5C3337365C3337375C303030355C3030302E5C303030375C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}Testování}{37}{subsubsection.5.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.6}Congestion control}{37}{subsubsection.5.5.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.7}Bandwidth control}{37}{subsubsection.5.5.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Sharding}{37}{subsection.5.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Horizontální škálování}{37}{subsection.5.7}\protected@file@percent }
\BKM@entry{id=58,open,dest={73656374696F6E2E36},srcline={988}}{5C3337365C3337375C303030365C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\BKM@entry{id=59,open,dest={73656374696F6E2E37},srcline={994}}{5C3337365C3337375C303030375C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=60,open,dest={73756273656374696F6E2E372E31},srcline={997}}{5C3337365C3337375C303030375C3030302E5C303030315C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\newlabel{fig:zone_cluster_architecture}{{5.7}{38}{Horizontální škálování}{subsection.5.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Architektura systému s zone clusterem}}{38}{figure.7}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Výsledná hra}{38}{section.6}\protected@file@percent }
\BKM@entry{id=61,open,dest={73756273756273656374696F6E2E372E312E31},srcline={1001}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\BKM@entry{id=62,open,dest={73756273756273656374696F6E2E372E312E32},srcline={1005}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\BKM@entry{id=63,open,dest={73756273756273656374696F6E2E372E312E33},srcline={1009}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\BKM@entry{id=64,open,dest={73756273756273656374696F6E2E372E312E34},srcline={1021}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030345C3030305C3034305C3030304F5C303030725C303030635C303030685C303030655C303030735C303030745C303030725C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {7}Měřění}{39}{section.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Metriky}{39}{subsection.7.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.1}PostgreSQL}{39}{subsubsection.7.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.2}TimescaleDB}{39}{subsubsection.7.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.3}Grafana}{39}{subsubsection.7.1.3}\protected@file@percent }
\BKM@entry{id=65,open,dest={73756273756273656374696F6E2E372E312E35},srcline={1027}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030355C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\BKM@entry{id=66,open,dest={73756273756273656374696F6E2E372E312E36},srcline={1033}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030365C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Příklad Grafana dashboardu}}{40}{figure.8}\protected@file@percent }
\newlabel{fig:grafana}{{8}{40}{Příklad Grafana dashboardu}{figure.8}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.4}Orchestrace}{40}{subsubsection.7.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.5}ImGui}{40}{subsubsection.7.1.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.6}Tracy}{40}{subsubsection.7.1.6}\protected@file@percent }
\BKM@entry{id=67,open,dest={73756273756273656374696F6E2E372E312E37},srcline={1049}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030375C3030305C3034305C3030304B5C3030306F5C3030306E5C3030306B5C303030725C3030305C3335315C303030745C3030306E5C3030305C3335355C3030305C3034305C3030306D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=68,open,dest={73756273756273656374696F6E2E372E312E38},srcline={1065}}{5C3337365C3337375C303030375C3030302E5C303030315C3030302E5C303030385C3030305C3034305C303030535C303030625C3030305C3335355C303030725C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C303030765C3030305C3034305C303030725C303030655C3030305C3334315C3030306C5C3030306E5C3030305C3335315C3030306D5C3030305C3034305C3030315C3031355C303030615C303030735C30303065}
\BKM@entry{id=69,open,dest={73756273656374696F6E2E372E32},srcline={1070}}{5C3337365C3337375C303030375C3030302E5C303030325C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Jeden snímek v Tracy}}{41}{figure.9}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{9}{41}{Jeden snímek v Tracy}{figure.9}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.7}Konkrétní metriky}{41}{subsubsection.7.1.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {7.1.8}Sbírání v reálném čase}{41}{subsubsection.7.1.8}\protected@file@percent }
\BKM@entry{id=70,open,dest={73756273656374696F6E2E372E33},srcline={1115}}{5C3337365C3337375C303030375C3030302E5C303030335C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{toc}{\contentsline {subsection}{\numberline {7.2}QUICr}{42}{subsection.7.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{42}{lstlisting.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Porovnání odezvy TCP a QUICr}}{43}{figure.10}\protected@file@percent }
\newlabel{fig:latencycomparison}{{10}{43}{Porovnání odezvy TCP a QUICr}{figure.10}{}}
\newlabel{fig:integrationcomparison}{{7.2}{43}{QUICr}{figure.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces Porovnání integrace TCP a QUICr}}{43}{figure.11}\protected@file@percent }
\newlabel{fig:playerbenchmark}{{7.2}{44}{QUICr}{figure.11}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces 301 připojených hráčů}}{44}{figure.12}\protected@file@percent }
\newlabel{fig:tracyreplicator}{{7.3}{44}{Optimalizace replikátoru}{subsection.7.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Analýza replikátoru}}{44}{figure.13}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.3}Optimalizace replikátoru}{44}{subsection.7.3}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_01}{{7.3}{45}{Optimalizace replikátoru}{figure.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{45}{figure.14}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_02}{{7.3}{45}{Optimalizace replikátoru}{figure.14}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{45}{figure.15}\protected@file@percent }
\BKM@entry{id=71,open,dest={73756273656374696F6E2E372E34},srcline={1168}}{5C3337365C3337375C303030375C3030302E5C303030345C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\BKM@entry{id=72,open,dest={73756273656374696F6E2E372E35},srcline={1198}}{5C3337365C3337375C303030375C3030302E5C303030355C3030305C3034305C3030305A5C3030305C3334315C303030765C3030315C3033335C303030725C30303079}
\newlabel{table:serialization_comparison}{{7.3}{46}{Optimalizace replikátoru}{figure.15}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Porovnání serializátorů}}{46}{figure.16}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.4}Optimalizace manažera zájmů}{46}{subsection.7.4}\protected@file@percent }
\newlabel{table:range_query_comparison}{{7.4}{47}{Optimalizace manažera zájmů}{subsection.7.4}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Porovnání algoritmů}}{47}{figure.17}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {7.5}Závěry}{47}{subsection.7.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {4}Sazba závěrů}{47}{lstlisting.4}\protected@file@percent }
\BKM@entry{id=73,open,dest={73656374696F6E2A2E33},srcline={1219}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\@writefile{toc}{\contentsline {section}{Z\'av\v er}{48}{section*.3}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {4}Hra}{21}{section.4}\protected@file@percent }
\BKM@entry{id=23,open,dest={73756273656374696F6E2E342E31},srcline={621}}{5C3337365C3337375C303030345C3030302E5C303030315C3030305C3034305C303030455C3030306E5C303030675C303030695C3030306E5C30303065}
\BKM@entry{id=24,open,dest={73756273756273656374696F6E2E342E312E31},srcline={653}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030465C303030795C3030307A5C303030695C303030635C3030306B5C3030305C3337355C3030305C3034305C303030655C3030306E5C303030675C303030695C3030306E5C30303065}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Engine}{22}{subsection.4.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{22}{subsubsection.4.1.1}\protected@file@percent }
\BKM@entry{id=25,open,dest={73756273756273656374696F6E2E342E312E32},srcline={661}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030565C303030795C3030306B5C303030725C303030655C303030735C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=26,open,dest={73756273756273656374696F6E2E342E312E33},srcline={669}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030455C3030306E5C303030745C303030695C303030745C303030795C3030302D5C303030435C3030306F5C3030306D5C303030705C3030306F5C3030306E5C303030655C3030306E5C303030745C3030302D5C303030535C303030795C303030735C303030745C303030655C3030306D}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Architektura hry pro jednoho hráče}}{23}{figure.5}\protected@file@percent }
\newlabel{fig:single_player_game}{{5}{23}{Architektura hry pro jednoho hráče}{figure.5}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{23}{subsubsection.4.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{23}{subsubsection.4.1.3}\protected@file@percent }
\newlabel{code:entt}{{1}{24}{Příklad použití knihovny Entt}{lstlisting.1}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}Příklad použití knihovny Entt}{24}{lstlisting.1}\protected@file@percent }
\BKM@entry{id=27,open,dest={73756273756273656374696F6E2E342E312E34},srcline={711}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.4}ImGui}{25}{subsubsection.4.1.4}\protected@file@percent }
\BKM@entry{id=28,open,dest={73656374696F6E2E35},srcline={730}}{5C3337365C3337375C303030355C3030305C3034305C303030485C303030725C303030615C3030305C3034305C303030765C3030305C3335355C303030635C303030655C3030305C3034305C303030685C303030725C3030305C3334315C3030315C3031355C3030315C313537}
\BKM@entry{id=29,open,dest={73756273656374696F6E2E352E31},srcline={751}}{5C3337365C3337375C303030355C3030302E5C303030315C3030305C3034305C303030535C303030655C303030725C303030765C303030655C30303072}
\@writefile{toc}{\contentsline {section}{\numberline {5}Hra více hráčů}{26}{section.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Server}{26}{subsection.5.1}\protected@file@percent }
\BKM@entry{id=30,open,dest={73756273756273656374696F6E2E352E312E31},srcline={761}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030525C303030655C303030675C303030695C303030735C303030745C303030725C3030305C3034305C3030306B5C3030306C5C303030695C303030655C3030306E5C303030745C3030315C313537}
\BKM@entry{id=31,open,dest={73756273756273656374696F6E2E352E312E32},srcline={767}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Architektura hry pro více hráčů}}{27}{figure.6}\protected@file@percent }
\newlabel{fig:multi_player_game}{{6}{27}{Architektura hry pro více hráčů}{figure.6}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{27}{subsubsection.5.1.1}\protected@file@percent }
\BKM@entry{id=32,open,dest={73756273756273656374696F6E2E352E312E33},srcline={771}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030535C303030705C303030725C3030305C3334315C303030765C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\BKM@entry{id=33,open,dest={73756273656374696F6E2E352E32},srcline={781}}{5C3337365C3337375C303030355C3030302E5C303030325C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C30303074}
\BKM@entry{id=34,open,dest={73756273756273656374696F6E2E352E322E31},srcline={785}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030315C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=35,open,dest={73756273756273656374696F6E2E352E322E32},srcline={789}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030495C3030306E5C303030745C303030655C303030725C303030705C3030306F5C3030306C5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{28}{subsubsection.5.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{28}{subsubsection.5.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Klient}{28}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{28}{subsubsection.5.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{28}{subsubsection.5.2.2}\protected@file@percent }
\BKM@entry{id=36,open,dest={73756273756273656374696F6E2E352E322E33},srcline={793}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030335C3030305C3034305C303030525C3030306F5C3030306C5C3030306C5C303030625C303030615C303030635C3030306B}
\BKM@entry{id=37,open,dest={73756273656374696F6E2E352E33},srcline={803}}{5C3337365C3337375C303030355C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=38,open,dest={73756273756273656374696F6E2E352E332E31},srcline={814}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{29}{subsubsection.5.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{29}{subsection.5.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{29}{subsubsection.5.3.1}\protected@file@percent }
\BKM@entry{id=39,open,dest={73756273756273656374696F6E2E352E332E32},srcline={822}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\BKM@entry{id=40,open,dest={73756273756273656374696F6E2E352E332E33},srcline={826}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=41,open,dest={73756273656374696F6E2E352E34},srcline={833}}{5C3337365C3337375C303030355C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{30}{subsubsection.5.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{30}{subsubsection.5.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Serializace}{30}{subsection.5.4}\protected@file@percent }
\BKM@entry{id=42,open,dest={73756273656374696F6E2E352E35},srcline={867}}{5C3337365C3337375C303030355C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}cpp}{31}{lstlisting.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{31}{subsection.5.5}\protected@file@percent }
\BKM@entry{id=43,open,dest={73756273756273656374696F6E2E352E352E31},srcline={880}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030635C30303065}
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E352E352E32},srcline={893}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{32}{subsubsection.5.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{32}{subsubsection.5.5.2}\protected@file@percent }
\newlabel{sec:quicr_handshake}{{5.5.2}{32}{Handshake}{subsubsection.5.5.2}{}}
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E352E352E33},srcline={927}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Stavový stroj QUICr handshake}}{33}{figure.7}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{7}{33}{Stavový stroj QUICr handshake}{figure.7}{}}
\BKM@entry{id=46,open,dest={73756273756273656374696F6E2E352E352E34},srcline={949}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{34}{subsubsection.5.5.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{5.5.3}{34}{Spolehlivost}{subsubsection.5.5.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{34}{subsubsection.5.5.4}\protected@file@percent }
\BKM@entry{id=47,open,dest={73756273756273656374696F6E2E352E352E35},srcline={957}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=48,open,dest={73756273656374696F6E2E352E36},srcline={998}}{5C3337365C3337375C303030355C3030302E5C303030365C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}Testování}{35}{subsubsection.5.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Horizontální škálování}{35}{subsection.5.6}\protected@file@percent }
\BKM@entry{id=49,open,dest={73756273656374696F6E2E352E37},srcline={1018}}{5C3337365C3337375C303030355C3030302E5C303030375C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\newlabel{fig:zone_cluster_architecture}{{5.6}{36}{Horizontální škálování}{subsection.5.6}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Architektura systému s zone clusterem}}{36}{figure.8}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Výsledná hra}{36}{subsection.5.7}\protected@file@percent }
\newlabel{fig:lobby_ui}{{5.7}{37}{Výsledná hra}{subsection.5.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Uživatelské rozhraní v lobby}}{37}{figure.9}\protected@file@percent }
\newlabel{fig:ui_showcase}{{5.7}{37}{Výsledná hra}{figure.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Uživatelské rozhraní v klientovi}}{37}{figure.10}\protected@file@percent }
\BKM@entry{id=50,open,dest={73656374696F6E2E36},srcline={1042}}{5C3337365C3337375C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=51,open,dest={73756273656374696F6E2E362E31},srcline={1046}}{5C3337365C3337375C303030365C3030302E5C303030315C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E362E312E31},srcline={1054}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E362E312E32},srcline={1058}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E362E312E33},srcline={1062}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\@writefile{toc}{\contentsline {section}{\numberline {6}Měřění}{38}{section.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}\protected@file@percent }
\BKM@entry{id=55,open,dest={73756273756273656374696F6E2E362E312E34},srcline={1074}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\BKM@entry{id=56,open,dest={73756273756273656374696F6E2E362E312E35},srcline={1104}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030355C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C303030735C3030306B5C3030305C3334315C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=57,open,dest={73756273656374696F6E2E362E32},srcline={1108}}{5C3337365C3337375C303030365C3030302E5C303030325C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces Příklad Grafana dashboardu}}{39}{figure.11}\protected@file@percent }
\newlabel{fig:grafana}{{11}{39}{Příklad Grafana dashboardu}{figure.11}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{39}{subsubsection.6.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{39}{subsubsection.6.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{39}{subsubsection.6.1.5}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Jeden snímek v Tracy}}{40}{figure.12}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{12}{40}{Jeden snímek v Tracy}{figure.12}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}QUICr}{40}{subsection.6.2}\protected@file@percent }
\newlabel{kod:tc}{{3}{40}{Příklad volání TC}{lstlisting.3}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{40}{lstlisting.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Porovnání odezvy TCP a QUICr}}{41}{figure.13}\protected@file@percent }
\newlabel{fig:latencycomparison}{{13}{41}{Porovnání odezvy TCP a QUICr}{figure.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Porovnání integrace TCP a QUICr}}{41}{figure.14}\protected@file@percent }
\newlabel{fig:integrationcomparison}{{14}{41}{Porovnání integrace TCP a QUICr}{figure.14}{}}
\BKM@entry{id=58,open,dest={73756273656374696F6E2E362E33},srcline={1155}}{5C3337365C3337375C303030365C3030302E5C303030335C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces 301 připojených hráčů}}{42}{figure.15}\protected@file@percent }
\newlabel{fig:playerbenchmark}{{15}{42}{301 připojených hráčů}{figure.15}{}}
\newlabel{fig:tracyreplicator}{{6.3}{42}{Optimalizace replikátoru}{subsection.6.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Analýza replikátoru}}{42}{figure.16}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{42}{subsection.6.3}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_01}{{6.3}{43}{Optimalizace replikátoru}{figure.16}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{43}{figure.17}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_02}{{6.3}{43}{Optimalizace replikátoru}{figure.17}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{43}{figure.18}\protected@file@percent }
\BKM@entry{id=59,open,dest={73756273656374696F6E2E362E34},srcline={1210}}{5C3337365C3337375C303030365C3030302E5C303030345C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces Porovnání serializátorů}}{44}{figure.19}\protected@file@percent }
\newlabel{table:serialization_comparison}{{6.3}{44}{Optimalizace replikátoru}{figure.19}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{44}{subsection.6.4}\protected@file@percent }
\BKM@entry{id=60,open,dest={73756273656374696F6E2E362E35},srcline={1238}}{5C3337365C3337375C303030365C3030302E5C303030355C3030305C3034305C303030505C303030655C303030655C303030725C3030302D5C303030745C3030306F5C3030302D5C303030705C303030655C303030655C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {20}{\ignorespaces Porovnání algoritmů}}{45}{figure.20}\protected@file@percent }
\newlabel{table:range_query_comparison}{{20}{45}{Porovnání algoritmů}{figure.20}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.5}Peer-to-peer}{45}{subsection.6.5}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {21}{\ignorespaces Porovnání TCP a QUICr v peer-to-peer}}{46}{figure.21}\protected@file@percent }
\newlabel{fig:peer_to_peer}{{21}{46}{Porovnání TCP a QUICr v peer-to-peer}{figure.21}{}}
\BKM@entry{id=61,open,dest={73656374696F6E2A2E33},srcline={1277}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\@writefile{toc}{\contentsline {section}{Z\'av\v er}{47}{section*.3}\protected@file@percent }
\babel@aux{czech}{}
\babel@aux{czech}{}
\BKM@entry{id=74,open,dest={73656374696F6E2A2E35},srcline={1222}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\@writefile{toc}{\contentsline {section}{Conclusions}{49}{section*.5}\protected@file@percent }
\BKM@entry{id=62,open,dest={73656374696F6E2A2E35},srcline={1286}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\@writefile{toc}{\contentsline {section}{Conclusions}{48}{section*.5}\protected@file@percent }
\babel@aux{english}{}
\babel@aux{czech}{}
\BKM@entry{id=75,open,dest={617070656E6469782E41},srcline={1229}}{5C3337365C3337375C303030415C3030305C3034305C303030505C303030725C303030765C3030306E5C3030305C3335355C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=76,open,dest={617070656E6469782E42},srcline={1232}}{5C3337365C3337375C303030425C3030305C3034305C303030445C303030725C303030755C303030685C3030305C3334315C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=77,open,dest={617070656E6469782E43},srcline={1237}}{5C3337365C3337375C303030435C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\@writefile{toc}{\contentsline {section}{\numberline {A}První příloha}{50}{appendix.A}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {B}Druhá příloha}{50}{appendix.B}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {C}Obsah elektronických dat}{50}{appendix.C}\protected@file@percent }
\newlabel{sec:ObsahData}{{C}{50}{Obsah elektronických dat}{appendix.C}{}}
\BKM@entry{id=78,open,dest={73656374696F6E2A2E37},srcline={1304}}{5C3337365C3337375C303030535C303030655C3030307A5C3030306E5C303030615C3030306D5C3030305C3034305C3030307A5C3030306B5C303030725C303030615C303030745C303030655C3030306B}
\BKM@entry{id=63,open,dest={617070656E6469782E41},srcline={1293}}{5C3337365C3337375C303030415C3030305C3034305C303030505C303030725C303030765C3030306E5C3030305C3335355C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=64,open,dest={617070656E6469782E42},srcline={1296}}{5C3337365C3337375C303030425C3030305C3034305C303030445C303030725C303030755C303030685C3030305C3334315C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=65,open,dest={617070656E6469782E43},srcline={1301}}{5C3337365C3337375C303030435C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\@writefile{toc}{\contentsline {section}{\numberline {A}První příloha}{49}{appendix.A}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {B}Druhá příloha}{49}{appendix.B}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {C}Obsah elektronických dat}{49}{appendix.C}\protected@file@percent }
\newlabel{sec:ObsahData}{{C}{49}{Obsah elektronických dat}{appendix.C}{}}
\abx@aux@nociteall
\@writefile{toc}{\contentsline {section}{Seznam zkratek}{52}{section*.7}\protected@file@percent }
\BKM@entry{id=79,open,dest={73656374696F6E2A2E38},srcline={1314}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\BKM@entry{id=66,open,dest={73656374696F6E2A2E37},srcline={1378}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\abx@aux@read@bbl@mdfivesum{nobblfile}
\abx@aux@read@bblrerun
\newlabel{LastPage}{{C}{52}{Obsah elektronických dat}{page.52}{}}
\gdef\lastpage@lastpage{52}
\gdef\lastpage@lastpageHy{52}
\newlabel{LastPage}{{C}{50}{Obsah elektronických dat}{page.50}{}}
\gdef\lastpage@lastpage{50}
\gdef\lastpage@lastpageHy{50}
\gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }}
\gdef \@abspage@last{52}
\gdef \@abspage@last{50}
+29 -17
View File
@@ -1,18 +1,18 @@
# Fdb version 4
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785390671.024 2
"kidiplom.bcf" 1785390670.89993 100507 e04409a00ea07820a76aae942e927593 "pdflatex"
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785734460.88696 2
"kidiplom.bcf" 1785734460.76816 100507 e04409a00ea07820a76aae942e927593 "pdflatex"
(generated)
"kidiplom.bbl"
"kidiplom.blg"
(rewritten before read)
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785390671.02099 0
"kidiplom.idx" 1785390669.2329 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785734460.88304 0
"kidiplom.idx" 1785734458.87112 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
(generated)
"kidiplom.ilg"
"kidiplom.ind"
(rewritten before read)
["pdflatex"] 1785390668.42988 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785390671.02112 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785390668.26589 122685 fd1dbf8e4d3c9e62acdb8caec97addec ""
["pdflatex"] 1785734457.87696 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785734460.88327 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785734457.71009 133663 75349692139a27e411a43603765c9f1e ""
"/usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc" 1775415801 4850 80dc9bab7f31fb78a000ccfed0e27cab ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ec.enc" 1775415801 2375 baa924870cfb487815765f9094cf3728 ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc" 1775415801 2405 5dcf2c1b967ee25cc46c58cd52244aed ""
@@ -25,8 +25,10 @@
"/usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8r.tfm" 1775415801 1292 bd42be2f344128bff6d35d98474adfe3 ""
"/usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8t.tfm" 1775415801 1384 4632f5e54900a7dadbb83f555bc61e56 ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1775415801 916 f87d7c45f9c908e672703b83b72241a3 ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm" 1775415801 924 9904cf1d39e9767e7a3622f2a125a565 ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm" 1775415801 928 2dc8d444221b7a635bb58038579b861a ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm" 1775415801 908 2921f8a10601f252058503cc6570e581 ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm" 1775415801 940 75ac932a52f80982a9f8ea75d03a34cf ""
"/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm" 1775415801 940 228d6584342e91276bf566bcf9716b83 ""
"/usr/share/texmf-dist/fonts/tfm/public/cm/cmr12.tfm" 1775415801 1288 655e228510b4c2a1abe905c368440826 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmbx10.tfm" 1775415801 12076 b54175e02101bea1addf6b2d0197ed12 ""
@@ -34,29 +36,36 @@
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr10.tfm" 1775415801 12056 7e13df7fe4cbce21b072ba7c4f4deb6e ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr12.tfm" 1775415801 12092 7b1546e2d096cfd5dcbd4049b0b1ec2e ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr17.tfm" 1775415801 12156 ca1ae6a3c8564e89597f1f993fba1608 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr7.tfm" 1775415801 12064 09aa3eeac96bf141d673bb1b0385ce55 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr8.tfm" 1775415801 12064 a35db870f0b76c338d749c56dc030ef5 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri12.tfm" 1775415801 17144 271aaf9ebb339934b04110dc5211fba4 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri8.tfm" 1775415801 17152 c8240fef851c4991afefdae37a539ee1 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmex10.tfm" 1775415801 992 ce925c9346c7613270a79afbee98c070 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi10.tfm" 1775415801 1528 6d36b2385e0ca062a654de6ac59cb34f ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi12.tfm" 1775415801 1524 753b192b18f2991794f9d41a8228510b ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi5.tfm" 1775415801 1508 198f5b7b99b5769126de3a533f6fc334 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi6.tfm" 1775415801 1512 94a3fd88c6f27dbd9ecb46987e297a4e ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi7.tfm" 1775415801 1528 d5b028dd23da623848ef0645c96a1ed7 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi8.tfm" 1775415801 1520 a3fe5596932db2db2cbda300920dd4e9 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmsy10.tfm" 1775415801 1308 02cc510f9dd6012e5815d0c0ffbf6869 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmsy5.tfm" 1775415801 1296 54ed1a711e2303d5282575278e3620b0 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmsy6.tfm" 1775415801 1300 b0605d44c16c22d99dc001808e4f24ea ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmsy7.tfm" 1775415801 1304 32f22a15acc296b2a4e15698403dcb88 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmsy8.tfm" 1775415801 1304 cdc9a17df9ef0d2dc320eff37bbab1c4 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr10.tfm" 1775415801 11868 4f81e9b6033c032bdaf9884f4d7ef412 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr12.tfm" 1775415801 11888 6841b91e46b65cf41a49b160e6e74130 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr5.tfm" 1775415801 11804 aefb10c002e6492c25236524a447f969 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr6.tfm" 1775415801 11836 e3b6ce3e601aec94f64a536e7f4224d5 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr7.tfm" 1775415801 11852 5a9022f105fd1ee2797df861e79ae9a0 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr8.tfm" 1775415801 11864 309fd7f43e4a0ba39f6f7644d76e8edf ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ts1-lmr12.tfm" 1775415801 1596 1d4548788e389ded56d0b01b28377882 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmbx10.pfb" 1775415801 121021 1bf809ce4a594679006bd72263eba59b ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmbx12.pfb" 1775415801 116908 1fca96723793882c2e0160350c192fc8 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmmi12.pfb" 1775415801 30696 2654571912f9cd384da9f7cb8a60c568 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmmi8.pfb" 1775415801 30635 833ec815d446ec453a4913fc26d24cbc ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr10.pfb" 1775415801 119235 f35b44530a1d90eb90fe15d9cba67ea0 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr12.pfb" 1775415801 113634 f99c44d58bae0863375faf0e1d74d612 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr17.pfb" 1775415801 119752 1bd8d06e4079df624bf59ce3ad7c9aa6 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr7.pfb" 1775415801 121145 68312a933e2c689ed40ec0aba373e279 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr8.pfb" 1775415801 122174 a7a08406857c9530a0320a2517f60370 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmri12.pfb" 1775415801 109265 32320cb6133d4d76bf83e27b5eb4009b ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb" 1775415801 109952 3dd76c0c5c680d519bb6d59a066c0826 ""
@@ -240,34 +249,37 @@
"graphics/300playerstrace.png" 1775758530.81909 49763 3cc41557a1ddcc2acef988ea4667dfe8 ""
"graphics/TcpIp.png" 1775414953.33879 64639 00f2319f3474a2ac8cf43569bc9af998 ""
"graphics/UP_znak.pdf" 1681557593 3121 caaf4f5447a3a0b25b356a30208583d1 ""
"graphics/client-server-architecture.pdf" 1777452157.2459 87165 29c6b564f112814268f2465c1c3c0188 ""
"graphics/ecs_optimization_tracy_01.png" 1776022974.05461 130401 258005bf8593377b2ff6bade36c08384 ""
"graphics/ecs_optimization_tracy_02.png" 1776023016.44493 121676 ab7b6fd1d3d0d0b0a564447c2067c920 ""
"graphics/grafana.png" 1777742255.36748 177249 00bc0e853ef0c5f6e56d0e482cd0070c ""
"graphics/http2.pdf" 1776969007.60601 46800 91209613d245a76f155c3f9e6f79cdf6 ""
"graphics/http3.pdf" 1776968997.16731 79793 31bf8e82583c4435518e5143b8792c85 ""
"graphics/integrationcomparison.pdf" 1775588282.49964 20019 870793ee528516a5c736ac47a287f24f ""
"graphics/integrationcomparison.pdf" 1785598900.05035 21400 e9a5f98ce0119825ff32deab9aeb8849 ""
"graphics/kititle-cz-nofont.pdf" 1681557593 12762 4b9f69751f3c44debf721c7e80adffc7 ""
"graphics/latencycomparison.pdf" 1778155349.2454 19017 2406ef2b6ba3de406fb00a57ae6eb4a0 ""
"graphics/layer_architecture.png" 1777273464.39449 24159 f110280074d3b9a1444f44da6168aefc ""
"graphics/latencycomparison.pdf" 1785598896.77326 20418 cce68df2d0a9cefe2fb78a48a6bd216b ""
"graphics/layer_architecture.pdf" 1785519927.28205 18700 76efc7ba73621fe471df54327abb2b71 ""
"graphics/lobby_ui.png" 1785589829.68089 17027 d525c244f118622ea99f3cb594f0d9a2 ""
"graphics/multi_player_game.pdf" 1785442795.86465 21498 2bd066f384a69add517f0e8976459706 ""
"graphics/peer_to_peer.pdf" 1785599197.29362 16751 004040111b685ec10da530255471392f ""
"graphics/playerbenchmark.png" 1774990129.78598 36699 4e11286fcaf50fefe34cf42456e981bc ""
"graphics/quic_handshake.pdf" 1777135207.08321 51400 2edd580d3287b4878651db3546952446 ""
"graphics/quicr_handshake.pdf" 1777671629.01477 54410 98ae3707915e14050914f5953b2aa2a7 ""
"graphics/single_player_game.pdf" 1785442493.01935 13333 4aa853afca2e648aa2538dafc63085da ""
"graphics/ui_showcase.png" 1785588400.769 84643 879725aac5c66e2603bf04c021a476bb ""
"graphics/zone_server_architecture.pdf" 1777668683.31198 89331 7bcdb7a734277a007eb50aab7d27d76c ""
"iso-numeric.bbx" 1681557593 319 50b9ccdb608c40ac14dd498079e9ab29 ""
"iso-numeric.cbx" 1681557593 73 45828f8df9dead5135d2c8a727f5b601 ""
"iso.bbx" 1681557593 13233 9f9e9c852fe772bfe1efaacc6b415eb7 ""
"kibase.sty" 1681557593 23853 021ae8236751950ac5e18f6a5bcf1da7 ""
"kidiplom.acr" 0 -1 0 ""
"kidiplom.aux" 1785390670.88193 37634 ce061d65e7dd2c494759a26a735ac34c "pdflatex"
"kidiplom.aux" 1785734460.75516 33014 8f9de60623bd15db1cac21f140953644 "pdflatex"
"kidiplom.bbl" 0 -1 0 "biber kidiplom"
"kidiplom.cls" 1681557593 18598 7684b2d13ac67d7b017c4eea1e12fa0c ""
"kidiplom.glsdefs" 1777655247.6059 525 791a05cd0a9f8650067804d8f5ff3f41 ""
"kidiplom.ind" 1777641420.71105 0 d41d8cd98f00b204e9800998ecf8427e "makeindex kidiplom.idx"
"kidiplom.lot" 1785390670.90143 142 0f926846b4ca0023532a29a360cf54d1 "pdflatex"
"kidiplom.run.xml" 1785390670.90143 2535 4e001a965ee2f4de88dc6271855a61ea "pdflatex"
"kidiplom.tex" 1785390668.26589 122685 fd1dbf8e4d3c9e62acdb8caec97addec ""
"kidiplom.toc" 1785390670.90143 6373 f29d0b7aa774ff86ece0f349c04bd0a5 "pdflatex"
"kidiplom.lot" 1785734460.76939 142 0f926846b4ca0023532a29a360cf54d1 "pdflatex"
"kidiplom.run.xml" 1785734460.76939 2535 4e001a965ee2f4de88dc6271855a61ea "pdflatex"
"kidiplom.tex" 1785734457.71009 133663 75349692139a27e411a43603765c9f1e ""
"kidiplom.toc" 1785734460.76939 5253 64abddb6b0acaee5064c1f803435fbd1 "pdflatex"
(generated)
"kidiplom.acn"
"kidiplom.aux"
+54 -42
View File
@@ -486,9 +486,6 @@ INPUT ./kidiplom.lot
INPUT kidiplom.lot
OUTPUT kidiplom.lot
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmbx12.tfm
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathsy.enc
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-rm.enc
INPUT /usr/share/texmf-dist/tex/latex/psnfss/t1pcr.fd
INPUT /usr/share/texmf-dist/tex/latex/psnfss/t1pcr.fd
INPUT /usr/share/texmf-dist/tex/latex/psnfss/t1pcr.fd
@@ -496,11 +493,14 @@ INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8t.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrr8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8r.tfm
INPUT /usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc
INPUT ./graphics/layer_architecture.png
INPUT ./graphics/layer_architecture.png
INPUT ./graphics/layer_architecture.png
INPUT ./graphics/layer_architecture.png
INPUT ./graphics/layer_architecture.png
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathsy.enc
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-rm.enc
INPUT ./graphics/layer_architecture.pdf
INPUT ./graphics/layer_architecture.pdf
INPUT ./graphics/layer_architecture.pdf
INPUT ./graphics/layer_architecture.pdf
INPUT ./graphics/layer_architecture.pdf
INPUT ./graphics/TcpIp.png
INPUT ./graphics/TcpIp.png
INPUT ./graphics/TcpIp.png
@@ -520,22 +520,43 @@ INPUT ./graphics/quic_handshake.pdf
INPUT ./graphics/quic_handshake.pdf
INPUT ./graphics/quic_handshake.pdf
INPUT ./graphics/quic_handshake.pdf
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8t.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr8.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr5.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmmi10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmmi7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmmi5.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmsy10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmsy7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/lmsy5.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr7.tfm
INPUT ./graphics/single_player_game.pdf
INPUT ./graphics/single_player_game.pdf
INPUT ./graphics/single_player_game.pdf
INPUT ./graphics/single_player_game.pdf
INPUT ./graphics/single_player_game.pdf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8t.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrr8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8r.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8t.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8t.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrr8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8r.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrr8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrr8r.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrb8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8r.tfm
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
@@ -549,6 +570,16 @@ INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/lobby_ui.png
INPUT ./graphics/lobby_ui.png
INPUT ./graphics/lobby_ui.png
INPUT ./graphics/lobby_ui.png
INPUT ./graphics/lobby_ui.png
INPUT ./graphics/ui_showcase.png
INPUT ./graphics/ui_showcase.png
INPUT ./graphics/ui_showcase.png
INPUT ./graphics/ui_showcase.png
INPUT ./graphics/ui_showcase.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
@@ -588,45 +619,26 @@ INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ts1-lmr12.tfm
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ts1.enc
INPUT ./kidiplom.ind
INPUT ./kidiplom.ind
INPUT kidiplom.ind
INPUT kidiplom.aux
INPUT kidiplom.run.xml
OUTPUT kidiplom.run.xml
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmbx10.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmbx12.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmmi12.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmmi8.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr10.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr12.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr17.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr7.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr8.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmri12.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb
+1 -1
View File
@@ -1,5 +1,5 @@
% makeindex style file created by the glossaries package
% for document 'kidiplom' on 2026-7-30
% for document 'kidiplom' on 2026-8-3
actual '?'
encap '|'
level '!'
+187 -277
View File
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.29 (TeX Live 2026/Arch Linux) (preloaded format=pdflatex 2026.6.8) 30 JUL 2026 07:51
This is pdfTeX, Version 3.141592653-2.6-1.40.29 (TeX Live 2026/Arch Linux) (preloaded format=pdflatex 2026.6.8) 3 AUG 2026 07:20
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
@@ -1266,7 +1266,7 @@ Package biblatex Warning: Attempt to redefine deprecated '\mkbibnamelast'.
Package biblatex Warning: Conflicting options.
(biblatex) 'urldate=iso' requires 'seconds=true'.
(biblatex) Setting 'seconds=true' on input line 145.
(biblatex) Setting 'seconds=true' on input line 143.
(./kidiplom.aux
Package babel Info: 'czech' activates 'czech' shorthands.
@@ -1274,24 +1274,24 @@ Package babel Info: 'czech' activates 'czech' shorthands.
)
\openout1 = `kidiplom.aux'.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 145.
LaTeX Font Info: ... okay on input line 145.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 143.
LaTeX Font Info: ... okay on input line 143.
(/usr/share/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count518
@@ -1314,7 +1314,7 @@ Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
e
))
Package hyperref Info: Link coloring ON on input line 145.
Package hyperref Info: Link coloring ON on input line 143.
\c@lstlisting=\count524
(./kidiplom.glsdefs)
@@ -1373,8 +1373,8 @@ Package biblatex Info: Trying to load bibliographic data...
Package biblatex Info: ... file 'kidiplom.bbl' not found.
No file kidiplom.bbl.
Package biblatex Info: Reference section=0 on input line 145.
Package biblatex Info: Reference segment=0 on input line 145.
Package biblatex Info: Reference section=0 on input line 143.
Package biblatex Info: Reference segment=0 on input line 143.
*geometry* detected driver: pdftex
*geometry* verbose mode - [ preamble ] result:
* driver: pdftex
@@ -1411,50 +1411,50 @@ Package biblatex Info: Reference segment=0 on input line 145.
<graphics/kititle-cz-nofont.pdf, id=7, 375.4025pt x 72.27pt>
File: graphics/kititle-cz-nofont.pdf Graphic file (type pdf)
<use graphics/kititle-cz-nofont.pdf>
Package pdftex.def Info: graphics/kititle-cz-nofont.pdf used on input line 150
Package pdftex.def Info: graphics/kititle-cz-nofont.pdf used on input line 148
.
(pdftex.def) Requested size: 225.24323pt x 43.36232pt.
<graphics/UP_znak.pdf, id=8, 101.59215pt x 101.59215pt>
File: graphics/UP_znak.pdf Graphic file (type pdf)
<use graphics/UP_znak.pdf>
Package pdftex.def Info: graphics/UP_znak.pdf used on input line 150.
Package pdftex.def Info: graphics/UP_znak.pdf used on input line 148.
(pdftex.def) Requested size: 101.59187pt x 101.59187pt.
LaTeX Font Info: Trying to load font information for OT1+lmr on input line 1
50.
48.
(/usr/share/texmf-dist/tex/latex/lm/ot1lmr.fd
File: ot1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
)
LaTeX Font Info: Trying to load font information for OML+lmm on input line 1
50.
48.
(/usr/share/texmf-dist/tex/latex/lm/omllmm.fd
File: omllmm.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
)
LaTeX Font Info: Trying to load font information for OMS+lmsy on input line
150.
148.
(/usr/share/texmf-dist/tex/latex/lm/omslmsy.fd
File: omslmsy.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
)
LaTeX Font Info: Trying to load font information for OMX+lmex on input line
150.
148.
(/usr/share/texmf-dist/tex/latex/lm/omxlmex.fd
File: omxlmex.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
)
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <12> on input line 150.
(Font) <12> on input line 148.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <8> on input line 150.
(Font) <8> on input line 148.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <6> on input line 150.
LaTeX Font Info: Trying to load font information for U+msa on input line 150
(Font) <6> on input line 148.
LaTeX Font Info: Trying to load font information for U+msa on input line 148
.
(/usr/share/texmf-dist/tex/latex/amsfonts/umsa.fd
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
)
LaTeX Font Info: Trying to load font information for U+msb on input line 150
LaTeX Font Info: Trying to load font information for U+msb on input line 148
.
(/usr/share/texmf-dist/tex/latex/amsfonts/umsb.fd
@@ -1467,7 +1467,7 @@ File: umsb.fd 2013/01/14 v3.01 AMS symbols B
/enc/dvips/lm/lm-ec.enc} <./graphics/kititle-cz-nofont.pdf> <./graphics/UP_znak
.pdf>]
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <10.95> on input line 150.
(Font) <10.95> on input line 148.
[2] [3
] [4
@@ -1487,187 +1487,100 @@ LaTeX Font Info: External font `lmex10' loaded for size
] [8
] [9] [10{/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc}{/usr/share/te
xmf-dist/fonts/enc/dvips/lm/lm-mathsy.enc}{/usr/share/texmf-dist/fonts/enc/dvip
s/lm/lm-rm.enc}]
LaTeX Font Info: Trying to load font information for T1+pcr on input line 26
2.
]
LaTeX Font Info: Trying to load font information for T1+pcr on input line 21
7.
(/usr/share/texmf-dist/tex/latex/psnfss/t1pcr.fd
File: t1pcr.fd 2001/06/04 font definitions for T1/pcr.
) [11{/usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc}]
Overfull \hbox (0.28238pt too wide) in paragraph at lines 277--281
) [9{/usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc}]
Overfull \hbox (0.28238pt too wide) in paragraph at lines 231--235
[]\T1/lmr/m/n/12 Druhým p°í-stu-pem je po-sí-lání zpráv. V tomto p°í-stupu po-s
í-lají pro-cesy zprávy
[]
[12]
<graphics/layer_architecture.png, id=234, 663.47874pt x 321.2pt>
File: graphics/layer_architecture.png Graphic file (type png)
<use graphics/layer_architecture.png>
Package pdftex.def Info: graphics/layer_architecture.png used on input line 31
7.
(pdftex.def) Requested size: 409.50119pt x 198.24504pt.
[13] [14 <./graphics/layer_architecture.png>]
<graphics/TcpIp.png, id=250, 805.0075pt x 512.91624pt>
[10] [11] [12{/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc}{/usr/shar
e/texmf-dist/fonts/enc/dvips/lm/lm-mathsy.enc}{/usr/share/texmf-dist/fonts/enc/
dvips/lm/lm-rm.enc}]
<graphics/layer_architecture.pdf, id=206, 341.35529pt x 174.6525pt>
File: graphics/layer_architecture.pdf Graphic file (type pdf)
<use graphics/layer_architecture.pdf>
Package pdftex.def Info: graphics/layer_architecture.pdf used on input line 31
2.
(pdftex.def) Requested size: 409.50119pt x 209.52332pt.
[13 <./graphics/layer_architecture.pdf>] [14]
<graphics/TcpIp.png, id=230, 805.0075pt x 512.91624pt>
File: graphics/TcpIp.png Graphic file (type png)
<use graphics/TcpIp.png>
Package pdftex.def Info: graphics/TcpIp.png used on input line 353.
Package pdftex.def Info: graphics/TcpIp.png used on input line 356.
(pdftex.def) Requested size: 409.50119pt x 260.91075pt.
[15 <./graphics/TcpIp.png>]
<graphics/http2.pdf, id=257, 275.10779pt x 225.7233pt>
[15]
[16 <./graphics/TcpIp.png>]
<graphics/http2.pdf, id=244, 275.10779pt x 225.7233pt>
File: graphics/http2.pdf Graphic file (type pdf)
<use graphics/http2.pdf>
Package pdftex.def Info: graphics/http2.pdf used on input line 392.
Package pdftex.def Info: graphics/http2.pdf used on input line 395.
(pdftex.def) Requested size: 196.5588pt x 161.2807pt.
<graphics/http3.pdf, id=258, 349.305pt x 262.0992pt>
<graphics/http3.pdf, id=245, 349.305pt x 262.0992pt>
File: graphics/http3.pdf Graphic file (type pdf)
<use graphics/http3.pdf>
Package pdftex.def Info: graphics/http3.pdf used on input line 398.
Package pdftex.def Info: graphics/http3.pdf used on input line 401.
(pdftex.def) Requested size: 196.5588pt x 147.48642pt.
[16] [17 <./graphics/http2.pdf> <./graphics/http3.pdf>] [18] [19]
<graphics/quic_handshake.pdf, id=314, 243.79079pt x 327.14218pt>
[17 <./graphics/http2.pdf> <./graphics/http3.pdf>]
[18] [19]
<graphics/quic_handshake.pdf, id=295, 243.79079pt x 327.14218pt>
File: graphics/quic_handshake.pdf Graphic file (type pdf)
<use graphics/quic_handshake.pdf>
Package pdftex.def Info: graphics/quic_handshake.pdf used on input line 477.
Package pdftex.def Info: graphics/quic_handshake.pdf used on input line 495.
(pdftex.def) Requested size: 204.7506pt x 274.7626pt.
[20] [21 <./graphics/quic_handshake.pdf>]
! Undefined control sequence.
l.503 ...váříme objekt kontextu pomocí \inlcpp
{ctx=zmq\_context(num\_thr...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <10> on input line 643.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <7> on input line 643.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <5> on input line 643.
! Undefined control sequence.
l.503 ...vláken specifikovaný parametrem \inlcpp
{num\_thread}. Když násl...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.503 ...read}. Když následně zavoláme \inlcpp
{zmq\_send(ctx, x)}, protÄ...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.503 ...ctx, x)}, protějšek klasického \inlcpp
{send(x)}, tak nedojde k b...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.503 ...o fronty, ze které pak vlákna z \inlcpp
{zmq\_context} tzv. \uv{kr...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
Overfull \hbox (92.69887pt too wide) in paragraph at lines 503--504
\T1/lmr/m/n/12 P°i po-u-ºití knihovny Ze-roMQ vy-tvá-°íme ob-jekt kon-textu po-
mocí ctx=zmq_context(num_threads).
Underfull \hbox (badness 10000) in paragraph at lines 643--643
[][][]\T1/lmr/m/n/10 ƒlánek od Riot Ga-mes uka-zuje, jak d·-le-ºitá je ode-zva
u kom-pe-te-tiv-
[]
! Undefined control sequence.
l.505 To samé platí o \inlcpp
{zmq\_receive}, které si v pozadí skládá ...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.513 ...ronní pomocí klíÄového slova \inlcpp
{async}. Zavoláním takov...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.513 ...¡ním takové funkce speciálním \inlcpp
{await} voláním způsobÃ...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
l.513 ...kce, kterou jsou zavolali pomocí \inlcpp
{await}. Toto volání tak...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
Overfull \hbox (13.61082pt too wide) in paragraph at lines 513--514
\T1/lmr/m/n/12 Populární im-ple-men-tací, kte-rou vi-díme na-p°í-klad v Rust ne
bo C#, je ^^R async/await^^P .
Underfull \hbox (badness 10000) in paragraph at lines 643--643
\T1/lmr/m/n/10 ních her. U pro-fe-si-o-nál-ních hr᣷ je po-znat i roz-díl mezi
120Hz a 240Hz.
[]
[22]
! Undefined control sequence.
l.522 ...Pouze vytvoříme objekt kontextu \inlcpp
{asio\_context}, který mÃ...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
<graphics/single_player_game.pdf, id=315, 334.3692pt x 171.76169pt>
File: graphics/single_player_game.pdf Graphic file (type pdf)
<use graphics/single_player_game.pdf>
Package pdftex.def Info: graphics/single_player_game.pdf used on input line 64
7.
(pdftex.def) Requested size: 204.7506pt x 105.1807pt.
! Undefined control sequence.
l.522 ...terý má frontu úkolů a metodu \inlcpp
{run}. Když z vlákna zav...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
Overfull \hbox (9.23495pt too wide) in paragraph at lines 657--658
\T1/lmr/m/n/12 en-gine po-sune stav en-tit (zrych-lení a po-zice). V²e jsme oba
-lili do []
[]
[23] [24]
! Undefined control sequence.
l.632 ...­ a pozice). VÅ¡e jsme obalili do \inlcpp
{JoltPhysicsWorld}.
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
[25]
[22] [23 <./graphics/single_player_game.pdf>]
Package hyperref Info: bookmark level for unknown lstlisting defaults to 0 on i
nput line 654.
[26] [27]
<graphics/client-server-architecture.pdf, id=375, 609.23605pt x 404.47108pt>
File: graphics/client-server-architecture.pdf Graphic file (type pdf)
<use graphics/client-server-architecture.pdf>
Package pdftex.def Info: graphics/client-server-architecture.pdf used on input
line 715.
(pdftex.def) Requested size: 409.50119pt x 271.8706pt.
[28] [29 <./graphics/client-server-architecture.pdf>]
nput line 679.
[24] [25]
LaTeX Warning: Reference `fig:client_server_architecture' on page 26 undefined
on input line 734.
<graphics/multi_player_game.pdf, id=364, 385.44pt x 457.71pt>
File: graphics/multi_player_game.pdf Graphic file (type pdf)
<use graphics/multi_player_game.pdf>
Package pdftex.def Info: graphics/multi_player_game.pdf used on input line 744
.
(pdftex.def) Requested size: 204.7506pt x 243.13689pt.
[26] [27 <./graphics/multi_player_game.pdf>]
! Undefined control sequence.
l.753 ...World}, která reprezentuje stav a \inlcp
l.783 ...World}, která reprezentuje stav a \inlcp
{ClientWorldController}, k...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
@@ -1675,156 +1588,153 @@ misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
[30]
Overfull \hbox (8.12425pt too wide) in paragraph at lines 796--797
[28] [29]
Overfull \hbox (8.12425pt too wide) in paragraph at lines 824--825
\T1/lmr/m/n/12 Vytvo°ili jsme t°ídu [][][][], která má na roz-hraní me-tody []
[]
Overfull \hbox (20.39532pt too wide) in paragraph at lines 796--797
Overfull \hbox (20.39532pt too wide) in paragraph at lines 824--825
[][][][][][][][][]\T1/lmr/m/n/12 , [][][][] a [][][][]. První me-toda na-staví
pro kon-cový bod []
[]
[31]
[30]
LaTeX Warning: Reference `code:entity_spawn_message' on page 32 undefined on in
put line 811.
LaTeX Warning: Reference `code:entity_spawn_message' on page 31 undefined on in
put line 841.
[32] [33] [34]
<graphics/quicr_handshake.pdf, id=431, 337.26pt x 246.9225pt>
[31] [32]
<graphics/quicr_handshake.pdf, id=420, 337.26pt x 246.9225pt>
File: graphics/quicr_handshake.pdf Graphic file (type pdf)
<use graphics/quicr_handshake.pdf>
Package pdftex.def Info: graphics/quicr_handshake.pdf used on input line 891.
Package pdftex.def Info: graphics/quicr_handshake.pdf used on input line 921.
(pdftex.def) Requested size: 409.50119pt x 299.82079pt.
[35 <./graphics/quicr_handshake.pdf>]
Overfull \hbox (3.49525pt too wide) in paragraph at lines 901--902
[33 <./graphics/quicr_handshake.pdf>]
Overfull \hbox (3.49525pt too wide) in paragraph at lines 931--932
[]\T1/lmr/m/n/12 Spolehlivost °e²í kom-po-nenta [][][][], která si udr-ºuje fro
ntu rámc·,
[]
[36]
Overfull \hbox (6.44025pt too wide) in paragraph at lines 972--973
[34]
Overfull \hbox (6.44025pt too wide) in paragraph at lines 1002--1003
[][][][][][][][][][][][][] \T1/lmr/m/n/12 a [][][][][][][][][][][][][][][][]. K
aºdý
[]
[37]
<graphics/zone_server_architecture.pdf, id=455, 453.61469pt x 298.23419pt>
[35]
<graphics/zone_server_architecture.pdf, id=444, 453.61469pt x 298.23419pt>
File: graphics/zone_server_architecture.pdf Graphic file (type pdf)
<use graphics/zone_server_architecture.pdf>
Package pdftex.def Info: graphics/zone_server_architecture.pdf used on input l
ine 980.
ine 1010.
(pdftex.def) Requested size: 409.50119pt x 269.24106pt.
[38 <./graphics/zone_server_architecture.pdf>]
<graphics/grafana.png, id=476, 2813.51125pt x 913.4125pt>
<graphics/lobby_ui.png, id=445, 1929.2075pt x 1209.51875pt>
File: graphics/lobby_ui.png Graphic file (type png)
<use graphics/lobby_ui.png>
Package pdftex.def Info: graphics/lobby_ui.png used on input line 1028.
(pdftex.def) Requested size: 409.50119pt x 256.73788pt.
<graphics/ui_showcase.png, id=446, 2566.58875pt x 1412.27625pt>
File: graphics/ui_showcase.png Graphic file (type png)
<use graphics/ui_showcase.png>
Package pdftex.def Info: graphics/ui_showcase.png used on input line 1035.
(pdftex.def) Requested size: 409.50119pt x 225.32233pt.
[36 <./graphics/zone_server_architecture.pdf>] [37 <./graphics/lobby_ui.png> <
./graphics/ui_showcase.png>] [38]
<graphics/grafana.png, id=481, 2813.51125pt x 913.4125pt>
File: graphics/grafana.png Graphic file (type png)
<use graphics/grafana.png>
Package pdftex.def Info: graphics/grafana.png used on input line 1015.
Package pdftex.def Info: graphics/grafana.png used on input line 1068.
(pdftex.def) Requested size: 409.50119pt x 132.9362pt.
[39] [40 <./graphics/grafana.png>]
<graphics/300playerstrace.png, id=488, 1348.03625pt x 397.485pt>
<graphics/300playerstrace.png, id=483, 1348.03625pt x 397.485pt>
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1043.
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1082.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
[41 <./graphics/300playerstrace.png>]
<graphics/latencycomparison.pdf, id=496, 462.52798pt x 346.89601pt>
[39 <./graphics/grafana.png>]
<graphics/latencycomparison.pdf, id=492, 462.52798pt x 346.89601pt>
File: graphics/latencycomparison.pdf Graphic file (type pdf)
<use graphics/latencycomparison.pdf>
Package pdftex.def Info: graphics/latencycomparison.pdf used on input line 108
9.
Package pdftex.def Info: graphics/latencycomparison.pdf used on input line 112
6.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
<graphics/integrationcomparison.pdf, id=497, 462.52798pt x 346.89601pt>
<graphics/integrationcomparison.pdf, id=494, 462.52798pt x 346.89601pt>
File: graphics/integrationcomparison.pdf Graphic file (type pdf)
<use graphics/integrationcomparison.pdf>
Package pdftex.def Info: graphics/integrationcomparison.pdf used on input line
1097.
1136.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
<graphics/playerbenchmark.png, id=500, 1926.19624pt x 1221.56375pt>
[40 <./graphics/300playerstrace.png>] [41 <./graphics/latencycomparison.pdf> <
./graphics/integrationcomparison.pdf>]
<graphics/playerbenchmark.png, id=600, 1926.19624pt x 1221.56375pt>
File: graphics/playerbenchmark.png Graphic file (type png)
<use graphics/playerbenchmark.png>
Package pdftex.def Info: graphics/playerbenchmark.png used on input line 1109.
Package pdftex.def Info: graphics/playerbenchmark.png used on input line 1148.
(pdftex.def) Requested size: 204.7506pt x 129.84302pt.
[42] [43 <./graphics/latencycomparison.pdf> <./graphics/integrationcomparison.
pdf>]
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1121.
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1159.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
[44 <./graphics/playerbenchmark.png>]
<graphics/ecs_optimization_tracy_01.png, id=602, 1707.37875pt x 472.76625pt>
[42 <./graphics/playerbenchmark.png>]
<graphics/ecs_optimization_tracy_01.png, id=611, 1707.37875pt x 472.76625pt>
File: graphics/ecs_optimization_tracy_01.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_01.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_01.png used on input
line 1132.
line 1174.
(pdftex.def) Requested size: 409.50119pt x 113.38686pt.
<graphics/ecs_optimization_tracy_02.png, id=603, 1196.47pt x 583.17876pt>
<graphics/ecs_optimization_tracy_02.png, id=612, 1196.47pt x 583.17876pt>
File: graphics/ecs_optimization_tracy_02.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_02.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_02.png used on input
line 1139.
line 1181.
(pdftex.def) Requested size: 409.50119pt x 199.59514pt.
[45 <./graphics/ecs_optimization_tracy_01.png> <./graphics/ecs_optimization_tr
[43 <./graphics/ecs_optimization_tracy_01.png> <./graphics/ecs_optimization_tr
acy_02.png>]
Underfull \hbox (badness 10000) in paragraph at lines 1180--1180
Underfull \hbox (badness 10000) in paragraph at lines 1220--1220
[]|\T1/lmr/m/n/12 Název
[]
Underfull \hbox (badness 10000) in paragraph at lines 1184--1184
Underfull \hbox (badness 10000) in paragraph at lines 1224--1224
[]|\T1/lmr/m/n/12 Fixní
[]
Underfull \hbox (badness 10000) in paragraph at lines 1186--1186
Underfull \hbox (badness 10000) in paragraph at lines 1226--1226
[]|\T1/lmr/m/n/12 Hashovací
[]
[46] (/usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
File: lstlang1.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
File: lstlang2.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
File: lstlang3.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
File: lstlang1.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
File: lstlang2.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
File: lstlang3.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
File: lstmisc.sty 2025/11/14 1.11b (Carsten Heinz)
) [47] [48
[44] [45]
<graphics/peer_to_peer.pdf, id=636, 433.62pt x 361.35pt>
File: graphics/peer_to_peer.pdf Graphic file (type pdf)
<use graphics/peer_to_peer.pdf>
Package pdftex.def Info: graphics/peer_to_peer.pdf used on input line 1254.
(pdftex.def) Requested size: 204.7506pt x 170.6285pt.
[46 <./graphics/peer_to_peer.pdf>] [47
] [49
] [48
]
LaTeX Font Info: Trying to load font information for TS1+lmr on input line 1
278.
342.
(/usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
File: ts1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
) [50
) [49
{/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ts1.enc}] [51]
No file kidiplom.acr.
[52
{/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ts1.enc}] [50]
]
LaTeX Warning: Empty bibliography on input line 1378.
Package glossaries Warning: No \printglossary or \printglossaries found.
(Remove \makeglossaries if you don't want any glossaries.)
This document will not have a glossary.
LaTeX Warning: Empty bibliography on input line 1314.
(./kidiplom.ind)
enddocument/afterlastpage (AED): lastpage setting LastPage.
(./kidiplom.aux)
***********
@@ -1845,31 +1755,31 @@ Package logreq Info: Writing requests to 'kidiplom.run.xml'.
)
Here is how much of TeX's memory you used:
33745 strings out of 469481
635478 string characters out of 5469631
1772275 words of memory out of 5000000
61629 multiletter control sequences out of 15000+600000
692285 words of font info for 87 fonts, out of 8000000 for 9000
33720 strings out of 469481
635121 string characters out of 5469631
1771893 words of memory out of 5000000
61632 multiletter control sequences out of 15000+600000
707308 words of font info for 103 fonts, out of 8000000 for 9000
24 hyphenation exceptions out of 8191
110i,11n,125p,2637b,2312s stack positions out of 10000i,1000n,20000p,200000b,200000s
110i,11n,112p,2637b,2312s stack positions out of 10000i,1000n,20000p,200000b,200000s
pdfTeX warning (dest): name{section*.8} has been referenced but does not exist,
pdfTeX warning (dest): name{section*.7} has been referenced but does not exist,
replaced by a fixed one
</usr/share/texmf-dist/fonts/type1/public/lm/lmbx10.pfb></usr/share/texmf-dist/
fonts/type1/public/lm/lmbx12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/l
mmi12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmmi8.pfb></usr/share/te
xmf-dist/fonts/type1/public/lm/lmr10.pfb></usr/share/texmf-dist/fonts/type1/pub
lic/lm/lmr12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmr17.pfb></usr/s
hare/texmf-dist/fonts/type1/public/lm/lmr8.pfb></usr/share/texmf-dist/fonts/typ
e1/public/lm/lmri12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb>
</usr/share/texmf-dist/fonts/type1/public/lm/lmsy10.pfb></usr/share/texmf-dist/
fonts/type1/urw/courier/ucrb8a.pfb></usr/share/texmf-dist/fonts/type1/urw/couri
er/ucrr8a.pfb>
Output written on kidiplom.pdf (52 pages, 1032642 bytes).
mmi12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmr10.pfb></usr/share/te
xmf-dist/fonts/type1/public/lm/lmr12.pfb></usr/share/texmf-dist/fonts/type1/pub
lic/lm/lmr17.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmr7.pfb></usr/sh
are/texmf-dist/fonts/type1/public/lm/lmr8.pfb></usr/share/texmf-dist/fonts/type
1/public/lm/lmri12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb><
/usr/share/texmf-dist/fonts/type1/public/lm/lmsy10.pfb></usr/share/texmf-dist/f
onts/type1/urw/courier/ucrb8a.pfb></usr/share/texmf-dist/fonts/type1/urw/courie
r/ucrr8a.pfb>
Output written on kidiplom.pdf (50 pages, 1162426 bytes).
PDF statistics:
1008 PDF objects out of 1200 (max. 8388607)
798 compressed objects within 8 object streams
190 named destinations out of 1000 (max. 500000)
730 words of extra memory for PDF output out of 10000 (max. 10000000)
757 compressed objects within 8 object streams
170 named destinations out of 1000 (max. 500000)
646 words of extra memory for PDF output out of 10000 (max. 10000000)
BIN
View File
Binary file not shown.
Binary file not shown.
+285 -221
View File
@@ -104,11 +104,7 @@
%% Anotace práce, včetně anglické (obvykle překlad z jazyka
%% práce). Jeden odstavec!
\annotation{Ukázkový text závěrečné práce na Katedře informatiky
Přírodovědecké fakulty Univerzity Palackého v Olomouci, který je
zároveň dokumentací stylu pro text práce v \LaTeX{}u. Zdrojový text
v \LaTeX{}u je doporučeno použít jako šablonu pro text skutečné
závěrečné práce studenta.}
\annotation{V diplomová práci se budeme zabývat optimalizacemi datového přenosu v distribuovaných systémech. Konkrétně se zaměřuje na systémy pro hry více hráčů. Analyzovali jsme jejich problematiku a specifika, které popíšeme. Následně představíme optimalizace, které jsme implementovali. Mezi hlavní části patří náš vlastní protokol transportní vrstvy. Mimo jiné v práci popisujeme vývoj našeho vlastního herního enginu, do kterého právě různé techniky a optimalizace implementujeme.}
\annotation[english]{Sample text of thesis at the \kitextdepten,
\kitextfacultyen, \kitextuniven{} and, at the same time,
@@ -116,6 +112,8 @@
\LaTeX{} is recommended to be used as a template for real student's
thesis text.}
\newcommand{\inlcpp}[1]{\kiinlinecode{cpp}{!}{#1}}
%% Klíčová slova práce, včetně anglických. Oddělená (obvykle) středníkem.
\keywords{styl textu; závěrečná práce; dokumentace; ukázkový text}
\keywords[english]{text style; thesis; documentation; sample text}
@@ -160,17 +158,19 @@
\section{Úvod}
Hry pro více hráčů jsou stále populárnější. Například na internetovém tržišti her Steam 9 z 10 nejhranějších her podporuje hru více hráčů a 6 z nich dokonce ani nepodporuje hru pro jednoho hráče. Kvůli stále rostoucí popularitě online her vznikly sporty v počítačových hrách, tzv. \uv{e-sporty}, ve kterých se utkávají profesionální týmy proti sobě v kompetetivních hrách pro více hráčů. Kompetetivní hry jsou často rozděleny do zápasů a na jejich konci se provede evaluace hráčova skóre.
Dalším typem jsou masivní multiplayerové online hry, tzv. MMO, které zvládnou online světy pro tisíce hráčů. Používají trochu jiné principy a optimalizace, aby systém fungoval optimálně. Kompetetivní hry se soustředí na minimální odezvu a masivní online hry na zvládání co nejvíce hráčů současně pro co nejživější svět.
Hry pro více hráčů jsou stále populárnější. Například na internetovém tržišti her Steam 9 z 10 nejhranějších her podporuje hru více hráčů 6 z nich dokonce ani nepodporuje hru jednoho hráče. Dokonce vznikly sporty v počítačových hrách, tzv. \uv{e-sporty}, ve kterých se utkávají profesionální týmy proti sobě a kompetetivních hrách pro více hráčů. Trochu jiný typ her pro více hráčů, ale o nic míň výdělečný, jsou masivně online hry pro více hráčů. Kompetetivní hry jsou rozdělené do zápasů pro pár hráčů a jsou optimalizované pro minimální odezvu mezi akcemi hráče a reakcí systému. Naopak MMO hry jsou masivní a zvládnou masivní online světy pro tisíce hráčů. Optimalizují pro obrovský datový tok z tisíce klientů na server, který musí rozdělit svou zátěž na vícero dalších serverů.
V práci se zaměřujeme právě na metody optimalizace datového přenosu v síťových systémech pro hry více hráčů. Charakteristiky jsme analyzovali a implementovali různá řešení. Na konci představíme naše testovací scénáře pro měření optimality těchto technik. Zároveň popíšeme, jaké nástroje jsme k měření použili a jak.
V práci se zaměřujeme na metody optimalizace datového přenosu v síťových systémech ve hrách více hráčů. To znamená nejen velikost dat, ale i odezvu mezi vstupem hráče a reakcí stavu hry. Tyto optimalizace jsou obecné pro síťové systémy, distribuované nevyjímaje. Hru stavíme na vlastním herním enginu tak, abychom různé algoritmy měli pod kontrolou. Například jsme vytvořili vlastní protokol pro obousměrné posílání spolehlivých i nespolehlivých zpráv zvaný QUICr. Popíšeme, jakým způsobem jsme optimalizace měřili a jaké metriky jsou k tomu potřeba.
% Vytvořili jsme hru vlastní herní engine a v něm hru pro více hráčů. Implementovali jsme nástroje pro různé optimalizace přenosu dat. Analyzovalili jsme výkon pomocí různých nástrojů a výsledky demonstrujeme. Nesoustředíme se jen na síťové protokoly, ale i na koncové body, které potřebují posíláním informací koordinovat a kompresovat. Změřili jsme různé datové struktury a naše výsledky představíme.
% V naší práci se zaměříme právě na síťové a distribuované systémy, které slouží pro hry. Zajímali nás optimalizace, které pro různé herní světy můžeme použít. Vytvořili jsme jednoduchou hru, ve které se hráči mohou pohybovat. Hra pro komunikaci mezi klienty a servery využívá náš vlastní protokol QUICr, který umožňuje posílat zprávy spolehlivě i nespolehlivě pro snížení odezvy a eliminaci blokování. Představíme formu serializace, která kombinuje možnost vlastního rychlého zápisu, ale pro zprávy využívá fallback ProtoBuf.
Nejprve v další kapitole popíšeme distribuované systémy obecně: jak probíhá komunikace mezi dvěma procesy na dvou různých počítačích. Tyto procesy budeme skládat do distribuovaného systému. Uvedeme různé modely a atributy, které může komunikace nebo distribovaný systém mít.
V následujících kapitolách popisujeme samotnou hru. Představíme náš vlastní herní engine, který vytvořili. Engine je navrhžen jako modulární monolit. Zároveň s ním budeme popisovat architekturu samotné hry. Začneme hrou pro jednoho hráče a návrh rozšíříme o hru více hráčů tak, aby byl přehledný a snadno se s kódem pracovalo.
Pro demonstraci různých technik jsme vytvořili hru. Jedná se o jednoduchou hru ve 3D prostoru, kde každý hráč má svou postavu, se kterou může pohybovat. Tu stavíme na vlastním herním enginu tak, abychom různé algoritmy měli pod kontrolou. Například jsme vytvořili vlastní protokol pro obousměrné posílání spolehlivých i nespolehlivých zpráv zvaný QUICr. Celý engine jsme navrhovali jako modulární monolit a snažíme se organizovat jednotlivé řešení problémů do modulů. Díky tomu je návrh intuitivní a snadno rozšiřitelný.
V poslední kapitole představíme měření, které jsme provedli a jejich výsledky. Ukážeme důležité metriky a uvidíme, že u vysokých frekvencí zpráv bylo třeba optimalizovat nejen datový přenos, ale i samotné kódování zpráv.
@@ -200,60 +200,15 @@ V práci se zaměřujeme na metody optimalizace datového přenosu v síťových
% - 2. Ukázat další rozhraní jako ZMQ nebo Boost ASIO
% - 3. Představit asynchroní posílání zpráv
\section{Síťové systémy}
\section{Distribuované systémy}
V této kapitole představíme distribuované systémy. Popíšeme, na čem stojí a jaké jsou cíle, pokud se takový systém rozhodneme implementovat. Začneme od síťových systémů, na kterých jsou distribuované systémy stavěné. Ukážeme softwarové a systémové architektury v distribovaných systémech. Poté podrobněji rozebereme komunikaci v síti.
Počítačový systém se skládá ze služeb, každá implementovaná jako kolekce procesů, které dohromady plní společný úkol. Moderní systémy jsou ale čím dál větší a úkoly, které musí plnit, jsou složitější. To vedlo ke vzniku síťových systémům, ve kterých jsou procesy rozmístěné přes více počítačů a komunikují spolu posíláním zpráv. Výhod je hned několik. Část systému může být umístěna počítači blíž zákazníkovi a snížit tak odezvu. Když jeden proces selže, může být jiný, který plní stejnou službu a může systém udržet v provozu. Konkrétní skupinou jsou distribuované systémy, které mají mnoho procesů rozmístěných přes více počítačů, které aktivně spolupracují a jeví se jako jeden celek.
% Počítačový systém se skládá ze služeb, každá je implementována jako kolekce procesů a dohromady plní společný úkol. Systém, ve kterém jsou procesy služeb na různých počítačích propojených v síti, se nazývá \uv{síťový systém}. Zmíníme dva důvody, proč procesy takto rozmístit. Prvním může být záměr \uv{integrace} více existujících systémů. Například se v průběhu života software zjistí, že neposkytuje všechny potřebné služby. Mohou se změnit požadavky nebo se rozšíří uživatelská základna o skupinu, se kterou se původně nepočítalo. Pokud tuto službu poskytuje jiný systém na jiném počítači, můžeme oba systémy spojit. Druhým důvodem může být \uv{expanze}, kdy jeden počítač nesplňuje požadavky na výkon.
% Síťové systémy můžeme dále rozdělit na \uv{decentralizované} a \uv{distribuované}. Decentralizované jsou většinou ty, které se rozrostly přes více počítačů kvůli integraci. Distribuovaný systém se snaží být dostatečně rozprostřen přes více počítačů tak, aby dokázal plnit svůj úkol. Například aby umožňil snadno přidávat do systému služby, měl dostatečně nízkou odezvu nebo aby bylo možné ho škálovat pro velké množství požadavků.
Příkladem distribuovaného systému je World Wide Web, zkráceně WWW. Jedná se o informační systém, který umožňuje prohlížet, ukládat a odkazovat dokumenty umístěné na internetu. Dokumenty mohou být například webové stránky, obrázky nebo videa a jsou uloženy na webových serverech. Odkazy na ně jsou ve formátu URL. Distribuovanost systému umožňuje snadné rozšíření, protože každý může snadno přidat svůj server se svými dokumenty, které se tak stanou dostupné v systému. To zároveň rozloží zátěž přes více počítačů a systém tak zvládá miliardy požadavků denně. Zároveň se celý systém jeví jako jeden celek, který z URL adresy vyhledá server a dokument vrátí.
\subsection{Architektury}
V praktické části jsme navrhli síťový systém. V návrhu jsme využívali známé vzory, které představíme. Návrh systému rozdělíme na dvě části: softwarovou a systémovou architekturu. V softwarové architektuře řešíme komponenty a konektory mezi nimi. Mezi typy softwarových architektur patří například vrstvená, orientovaná na služby nebo publish-subscribe. Druhá část architektury, která řeší role jednotlivých služeb, se nazývá \uv{systémová architektura}. Mezi příklady patří peer-to-peer nebo klient-server.
Pro ilustraci rozdílu představíme známý příklad třívrstvé softwarové architektury: databázová, výpočetní a frontendová vrstva. Systémová architektura definuje, že databáze jako služba pro výpočetní vrstvu má roli serveru. Naopak služba pro replikaci ve skupině databázových serverů má roli peer-to-peer. Typy si rozebereme podrobněji v této kapitole.
\subsubsection{Softwarová architektura}
V první části se zaměříme na softwarovou architekturu. Budeme řešit komponenty a konektory mezi nimi. Představíme tři známé vzory: vrstvená architektura, architektura orientovaná na služby a publish-subscribe architektura.
Pokud komponenty organizujeme do vrstev, kde komponenta ve vrstvě $N$ může volat rozhraní vrstvy $N-1$, říkáme tomu \uv{vrstvená architektura}. Příkladem je vrstva operačního systému, nad kterým je vrstva uživatelského prostoru. Občas je možné, aby nižší vrstva volala vyšší, ale mělo by se dít přes rozhraní definované nižší vrstvou, které vyšší vrstva pouze implementuje. Příkladem je operační systém, který oznamuje událost aplikaci. Aplikace proto registruje funkci, která se v případě události zavolá. Rozhraní funkce ale určuje vrstva pod ní: operační systém.
Nevýhodou vrstvené architektury je silná provázanost mezi vrstvami. Namísto toho lze software organizovat do nezávislých entit, kde každá zapouzdřuje službu. Takovým entitám se říká: služba, objekt nebo mikroslužba. Na komponenty se můžeme dívat jako na objekty a konektory mezi nimi jsou volání metod. Instance objektu mohou být rozmístěny na více počítačích. To, že jiný objekt je na jiném počítači, by mělo být skryté. Když chce klient použít jiný objekt, lokálně si vytvoří jeho instanci, která ale po zavolání metody volání zabalí do zprávy a odešle objektu, který metodu implementuje. Tomuto modelu se říká \uv{remote procedure call}, nebo zkráceně RPC. Klient obdrží zprávu s výsledkem, kterou rozbalí a pokračuje v běhu. Lokální instanci se někdy říká \uv{proxy} nebo \uv{klient-stub}.
Co občas může vadit je, že jsou služby \uv{referenčně vázané}. To znamená, že služby musejí znát adresu nebo jméno jiné, pokud ji chtějí používat. Od tohoto omezení můžeme upustit například tím, že budou \uv{publikovat} události do různých \uv{témat} a dělat na tyto témata dotazy. Pokud například služba publikuje událost do tématu $A$, jiná služba, která udělá dotaz na téma $A$, dostane právě tuto událost. Odesílatel tak neví, kdo zprávu zpracuje, kolikrát a kdy. Implementace je přes \uv{brokera}, který slouží jako jednotný bod pro všechny procesy, do kterého publikují události a broker je třídí vhodným jiným procesům. Tento princip lze využít u systémů pro hry více hráčů pro komunikační kanály. Klient hráče chce například napsat do lokálního kanálu pro město, ve kterém se v herním světě nachází. Komponenta pro chatovou službu tuto zprávu zařadí do správného kanálu a rozešle klientům, kteří tento kanál také odebírají.
\subsubsection{Systémové architektury} \label{sec:system_architecture}
Pro systémové architektury představíme a později využijeme dva modely: asymetrickou klient-server a symetrickou peer-to-peer.
Asymetrickou architekturou, kde je komponenta buď server, nebo klient, se nazývá \uv{klient-server}. Pouze klienti mohou serverům posílat dotazy a dostávat od nich odpovědi. Vztah je tedy asymetrický. Příkladem jsou webové servery a webové prohlížeče, které fungují jako klienti. Tento model se hodí například pro autoritativní server, který určuje stav hry a pouze jej replikuje klientům. Usnadňuje synchronizaci jednotlivých klientů a zvyšuje efektivitu, protože se účastníci nemusí shodovat, ale pouze přijmout fakt ze serveru.
Symetrická architektura, kdy obě strany jsou si rovny, se nazývá \uv{peer-to-peer}. Znamená to, že obě strany mohou posílat požadavky a zprávy na druhou stranu. Využívá se například při replikaci, kdy máme několik replik, které jsou si rovny. Pouze řešíme, která vlastní jaký zdroj tak, aby nedošlo ke konfliktu dvou replik při psaní konkrétního záznamu. Libovolná replika má ale možnost odeslat svůj stav jiné, protože jsou si rovny. Tento model je vhodný například pro horizontální škálování stavových serverů, které si rozdělují část stejné služby. Například vícero serverů může zpracovávat různé části herního světa a předávají si mezi sebou entity, které mají na starost.
\section{Počítačová síť} \label{sec:NetworkCommunication}
Distribované systémy stojí na počítačových sítích. Ty umožňují komunikaci mezi dvěma procesy na dvou různých počítačích. Počítačová síť je skupina propojených počítačů, které si mezi sebou přenášejí data. Definujeme několik typů sítí, které se liší velikostí a provedením. Například lokální sítě (LAN) propojují až tisíce počítačů, které jsou geograficky blízko, například v rámci jedné budovy. Rozsáhlé sítě (WAN) propojují miliony různých zařízení po celém světě. Příkladem je rozsáhlá síť Internet.
Počítačovou síť si lze představit jako graf, ve kterém počítače představují
vrcholy a fyzická média mezi nimi jsou hrany. Vrcholy dále dělíme na \uv{koncové body} a \uv{propojovací prvky}. Díky propojovacím prvkům je možné poslat zprávu přes více vrcholů na cílový počítač. Příkladem takových prvků jsou přepínače, rozbočovače a opakovače. Sítím, které je využívají, se říká \uv{přepínané sítě}. Koncové body jsou například stolní počítače, mobilní telefony a jiná zařízení, na kterých běží komunikující procesy.
Dva počítače, přímo propojené fyzickým médiem, komunikují posíláním n-tic bytů zvané \uv{rámce}. V přepínaných sítích mají rámce konkrétní formát, který pomáhá při hledání cesty v grafu, tzv. \uv{směrování}. Takový formátovaný rámec se nazývá \uv{paket}. Skládá se z hlavičky, kde jsou informace ke směrování, a těla, kde je samotná zpráva. Každý vrchol v takové síti má přiřazenou unikátní \uv{síťovou adresu}. Cílovou adresu najdeme právě v hlavičce paketu.
\subsection{Komunikace}
@@ -265,10 +220,9 @@ Pro různé účely a situace máme jiné modely komunikace. Například email j
Dále může být komunikace \uv{synchronní} nebo \uv{asynchronní}. Asynchronní znamená, že odesílatel pokračuje v běhu okamžitě po odeslání zprávy. Ta se dočasně uloží v middleware do doby, než se odešle. Na druhou stranu při synchronní komunikaci volající proces zastaví, dokud neobdrží odpověď z cílového procesu. Obecně tedy definujeme tři body, kde může nastat synchronizace (proces odesílatele pokračuje v práci). Zaprvé hned poté, co middleware převzal zprávu a zodpovědnost za její doručení. Zadruhé v moment, kdy byla zpráva doručena druhému procesu. Zatřetí až v moment, kdy druhá strana zpracovala požadavek a dostali jsme odpověď.
\subsubsection{Modely pro komunikaci}
Pro každý účel musíme vhodně zvolit konfiguraci perzistence a synchronizace. Představíme dva modely komunikace, které posílání primitivních zpráv skrývají a jsou implementovány jako middleware: Message Oriented Middleware (MOM) a Remote Procedure Call (RPC).
Pro každý účel musíme vhodně zvolit konfiguraci perzistence a synchronizace. Představíme dva modely komunikace, které posílání zpráv skrývají a jsou implementovány jako middleware: Message Oriented Middleware (MOM) a Remote Procedure Call (RPC).
Prvním přístupem je Remote Procedure Call, který procesu umožňuje zavolat lokální proceduru s implementací na jiném počítači. Když proces A zavolá proceduru na počítači B, A se pozastaví a začne se vykonávat na B. Jakmile se dokončí, pošle se výsledek zpět na A, které poté pokračuje. Tento model je synchronní a transientní. Cílem je, aby volání vypadalo jako by implementace byla lokální a skrýt tak komunikaci mezi počítači.
@@ -291,39 +245,88 @@ Opět je potřeba, aby se dva koncové body shodli na významu bitů jednotlivý
\subsection{Počítačová Síť} \label{sec:NetworkCommunication}
V této části popíšeme, jak mezi sebou mohou komunikovat dva procesy, které běží na dvou různých počítačích. Počítačová síť je skupina propojených počítačů, které si mezi sebou přenášejí data. Definujeme několik typů sítí, které se liší velikostí a provedením. Například lokální sítě (LAN) propojují až tisíce počítačů, které jsou geograficky blízko, například v rámci jedné budovy. Rozsáhlé sítě (WAN) propojují miliony různých zařízení po celém světě. Příkladem je rozsáhlá síť Internet.
Počítačovou síť si lze představit jako graf, ve kterém počítače představují
vrcholy a fyzická média mezi nimi jsou hrany. Vrcholy dále dělíme na \uv{koncové body} a \uv{propojovací prvky}. Díky propojovacím prvkům je možné poslat zprávu přes více vrcholů na cílový počítač. Příkladem takových prvků jsou přepínače, rozbočovače a opakovače. Sítím, které je využívají, se říká \uv{přepínané sítě}. Koncové body jsou například stolní počítače, mobilní telefony a jiná zařízení, na kterých běží komunikující procesy.
\newpage
Dva počítače, přímo propojené fyzickým médiem, komunikují posíláním n-tic bytů zvané \uv{rámce}. V přepínaných sítích mají rámce konkrétní formát, který pomáhá při hledání cesty v grafu, tzv. \uv{směrování}. Takový formátovaný rámec se nazývá \uv{paket}. Zároveň musí mít každý vrchol v takové síti přiřazenou unikátní \uv{síťovou adresu}. Paket se skládá z hlavičky a těla. V hlavičce najdeme síťovou adresu cílového počítače, pomocí které přepínače hledají pro paket cestu. V těle paketu pak samotná zpráva.
\section{Distribuované systémy}
\subsection{Komunikace v síti}
V této kapitole představíme distribuované systémy. Popíšeme, na čem stojí a jaké jsou cíle, pokud se takový systém rozhodneme implementovat. Ukážeme softwarové a systémové architektury v distribovaných systémech. Poté podrobněji rozebereme komunikaci v síti.
Počítačový systém se skládá ze služeb, každá implementovaná jako kolekce procesů, které dohromady plní společný úkol. Moderní systémy jsou ale čím dál větší a úkoly, které musí plnit, jsou složitější. To vedlo ke vzniku síťových systémů, ve kterých jsou procesy rozmístěné přes více počítačů a komunikují spolu posíláním zpráv. Výhod je hned několik. Část systému může být umístěna počítači blíž zákazníkovi a snížit tak odezvu. Když jeden proces selže, může být jiný, který plní stejnou službu a může systém udržet v provozu. Konkrétní skupinou jsou distribuované systémy, které mají mnoho procesů rozmístěných přes více počítačů, které aktivně spolupracují a jeví se jako jeden celek.
% Počítačový systém se skládá ze služeb, každá je implementována jako kolekce procesů a dohromady plní společný úkol. Systém, ve kterém jsou procesy služeb na různých počítačích propojených v síti, se nazývá \uv{síťový systém}. Zmíníme dva důvody, proč procesy takto rozmístit. Prvním může být záměr \uv{integrace} více existujících systémů. Například se v průběhu života software zjistí, že neposkytuje všechny potřebné služby. Mohou se změnit požadavky nebo se rozšíří uživatelská základna o skupinu, se kterou se původně nepočítalo. Pokud tuto službu poskytuje jiný systém na jiném počítači, můžeme oba systémy spojit. Druhým důvodem může být \uv{expanze}, kdy jeden počítač nesplňuje požadavky na výkon.
% Síťové systémy můžeme dále rozdělit na \uv{decentralizované} a \uv{distribuované}. Decentralizované jsou většinou ty, které se rozrostly přes více počítačů kvůli integraci. Distribuovaný systém se snaží být dostatečně rozprostřen přes více počítačů tak, aby dokázal plnit svůj úkol. Například aby umožňil snadno přidávat do systému služby, měl dostatečně nízkou odezvu nebo aby bylo možné ho škálovat pro velké množství požadavků.
Příkladem distribuovaného systému je World Wide Web, zkráceně WWW. Jedná se o informační systém, který umožňuje prohlížet, ukládat a odkazovat dokumenty umístěné na internetu. Dokumenty mohou být například webové stránky, obrázky nebo videa a jsou uloženy na webových serverech. Odkazy na ně jsou ve formátu URL. Distribuovanost systému umožňuje snadné rozšíření, protože každý může snadno přidat svůj server se svými dokumenty, které se tak stanou dostupné v systému. To zároveň rozloží zátěž přes více počítačů a systém tak zvládá miliardy požadavků denně. Zároveň se celý systém jeví jako jeden celek, který z URL adresy vyhledá server a vrátí dokument.
\subsection{Architektury}
V praktické části jsme navrhli síťový systém. V návrhu jsme využívali známé vzory, které představíme. Návrh systému rozdělíme na dvě části: softwarovou a systémovou architekturu. V softwarové architektuře řešíme komponenty a konektory mezi nimi. Druhá část architektury, která řeší role jednotlivých služeb, se nazývá \uv{systémová architektura}. Mezi příklady patří peer-to-peer nebo klient-server.
Pro ilustraci rozdílu představíme známý příklad třívrstvé softwarové architektury: databázová, výpočetní a frontendová vrstva. Systémová architektura definuje, že databáze jako služba pro výpočetní vrstvu má roli serveru. Naopak služba pro replikaci ve skupině databázových serverů využívající model peer-to-peer má roli jak serveru, tak klienta. Typy si rozebereme podrobněji v této kapitole.
\subsubsection{Softwarová architektura}
Nejprve se zaměříme na softwarovou architekturu. V ní řešíme komponenty a konektory mezi nimi. Představíme tři známé vzory: vrstvená architektura, architektura orientovaná na služby a publish-subscribe architektura.
Pokud komponenty organizujeme do vrstev, kde komponenta ve vrstvě $N$ může volat rozhraní vrstvy $N-1$, říkáme tomu \uv{vrstvená architektura}. Příkladem je vrstva operačního systému, nad kterým je vrstva uživatelského prostoru. Vrstva $N-1$ nemá možnost volat rozhraní vrstvy $N$. Díky tomu lze na sebe vrstvy snadno skládat.
Občas je možné, aby nižší vrstva volala vyšší, ale mělo by se dít přes rozhraní definované nižší vrstvou, které vyšší vrstva pouze implementuje. Tomuto principu se říká \uv{obrácení závislostí}. Udržíme tak závislost $N$ na $N-1$ a $N-1$ zůstane nezávislá. Příkladem je operační systém, který oznamuje událost aplikaci. Aplikace proto registruje funkci, která se v případě události zavolá. Rozhraní funkce ale určuje vrstva pod ní: operační systém.
Nevýhodou vrstvené architektury je silná provázanost mezi vrstvami. Možnost je software organizovat do nezávislých entit, kde každá zapouzdřuje službu. Ty pak mezi sebou mohou volně komunikovat. Takovým entitám se říká: služba, objekt nebo mikroslužba. Na komponenty se můžeme dívat jako na objekty a konektory mezi nimi jsou volání metod neboli posílání zpráv. Tento přístup je relevantní pro distribuované systémy, protože instance objektů mohou být rozmístěny na více počítačích. K tomu lze použít například RPC, které jsme zmínili.
V případě služeb musí služba znát adresu nebo jméno jiné služby, kterou chce využívat. Někdy říkáme, že služby jsou \uv{referenčně vázané}. Tuto závislost lze odstranit pomocí publish-subscribe architektury. V ní každá služba publikuje \uv{události} do \uv{témat}. Služby mohou témata odebírat, a to znamená, že budou dostávat všechny události, které jsou publikované do daného tématu. Tuto službu distribuce události a správy témat zajišťuje \uv{broker}, který má všem známou adresu. Odesílatel události neví, kdo na jeho událost zareaguje a jak.
Tento princip lze využít u systémů pro hry více hráčů pro komunikační kanály. Klient hráče chce například napsat do lokálního kanálu města, ve kterém se v herním světě nachází. Komponenta pro chatovou službu tuto zprávu zařadí do správného kanálu a rozešle klientům, kteří tento kanál také odebírají.
\subsubsection{Systémové architektury} \label{sec:system_architecture}
Pro systémové architektury představíme a později využijeme dva modely: asymetrickou klient-server a symetrickou peer-to-peer.
Asymetrickou architekturou, kde je komponenta buď server, nebo klient, se nazývá \uv{klient-server}. Pouze klienti mohou serverům posílat dotazy a dostávat od nich odpovědi. Vztah je tedy asymetrický. Příkladem jsou webové servery a webové prohlížeče, které fungují jako klienti. Tento model se hodí například pro autoritativní server, který určuje stav hry a pouze jej replikuje klientům. Usnadňuje synchronizaci jednotlivých klientů a zvyšuje efektivitu, protože se účastníci nemusí shodovat, ale pouze přijmout fakt ze serveru.
Symetrická architektura, kdy obě strany jsou si rovny, se nazývá \uv{peer-to-peer}. Znamená to, že obě strany mohou posílat požadavky a zprávy na druhou stranu. Využívá se například při replikaci, kdy máme několik replik, které jsou si rovny. Pouze řešíme, která vlastní jaký zdroj tak, aby nedošlo ke konfliktu dvou replik při psaní konkrétního záznamu. Libovolná replika má ale možnost odeslat svůj stav jiné, protože jsou si rovny. Tento model je vhodný například pro horizontální škálování stavových serverů, které si rozdělují část stejné služby. Například vícero serverů může zpracovávat různé části herního světa a předávají si mezi sebou entity, které mají na starost.
\subsection{Protokoly}
V této části představíme jak je implementována komunikace v síti. Aby si dva počítače, které si posílají rámce, navzájem rozuměly, musejí se shodnout na významu jednotlivých bitů rámců. K takové definici slouží \uv{komunikační protokol}: soubor pravidel pro výměnu informací mezi počítači. Definuje syntaxi, sémantiku a synchronizaci zpráv.
Každý protokol poskytuje komunikační služby. Tyto služby rozdělujeme na dvě skupiny: ty co před komunikací navážou spojení a ty co ne. V prvním případě musejí obě strany přijmout a navázat spojení a potencionálně se domluvit na jeho dalších parametrech. Jakmile jejich komunikace skončí, spojení se ukončí. Příkladem takové služby je telefoní linka. V druhém případě může odeslat zprávu kdykoliv a bez předchozího upozornění druhé strany. Příkladem takové komunikace je posílání emailu.
Protokoly jsou často organizovány do vrstev, které se liší svou zodpovědností. Každá vrstva poskytuje komunikační službu přes své rozhraní. TODO
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/layer_architecture.pdf}
\end{center}
\caption{Vrstvená architektura}
\label{fig:layer_architecture}
\end{figure}
Protokoly jsou často organizovány do vrstev, které se liší svou zodpovědností. Každá vrstva poskytuje komunikační službu přes své rozhraní. Příklad vidíme na obrázku \ref{fig:layer_architecture}. Vidíme dvě vrstvy. Každá vrstva definuje nějakou komunikační službu a má své specifické rozhraní. Toto rozhraní využívá implementace služby nad ní.
\subsubsection{Rodina protokolů TCP/IP}
Rodina protokolů pro komunikaci v síti Internet je TCP/IP. Jedná se o více protokolů organizovaných do vrstev, kde každá může používat jen tu pod ní. Vrstvenou architekturu vidíme na obrázku \ref{fig:layer_architecture}. Vrstva $N$ používá rozhraní vrstvy $N-1$. Každá vrstva poskytuje komunikační služby. Počítač A i B tak vidí stejnou službu. Představme si, že rozhraní má dvě funkce: pro čtení a pro zápis. Aplikace do vrstvy $N$ zapíše zprávu, kterou chce, aby si proces využívající stejnou službu, ale na druhém počítači, mohl přečíst. Je potřeba, aby vrstva zapsala zprávu ve formátu, kterému bude rozumnět strana A i strana B. Tento formát je právě protokol, jak vidíme na obrázku \ref{fig:layer_architecture}.
Rodina protokolů pro komunikaci v síti Internet se nazývá TCP/IP. Jedná se o více protokolů organizovaných do vrstev. Každá vrstva poskytuje komunikační služby. Počítač A i B tak vidí stejnou službu. Představme si, že rozhraní má dvě funkce: pro čtení a pro zápis. Aplikace do vrstvy $N$ zapíše zprávu, kterou chce, aby si proces využívající stejnou službu, ale na druhém počítači, mohl přečíst. Je potřeba, aby vrstva zapsala zprávu ve formátu, kterému bude rozumnět strana A i strana B. Tento formát je právě protokol, jak vidíme na obrázku \ref{fig:layer_architecture}.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/layer_architecture.png}
\end{center}
\caption{Vrstvená architektura TODO předělat}
\label{fig:layer_architecture}
\end{figure}
Název se skládá ze dvou důležitých protokolů: IP (Internet Protocol) a TCP (Transmission Control Protocol). IP slouží pro směrování paketů a TCP pro řízení přenosu. IP umožňuje komunikaci libovolných dvou uzlů počítačů v propojených sítích. TCP zajišťuje spolehlivý obousměrný přenos dat mezi procesy na dvou počítačích (ne nutně různých).
Protokol IP má za úkol doručit paket od odesílatele na příjemce pouze podle IP adresy, která je v hlavičce paketu. IP nenavazuje spojení a nezaručuje doručení. Důvodem je princip \uv{end-to-end}, který říká, že body mezi odesílatelem a příjemcem, jako routery a přepínače, by měli být co nejjednodušší. Spolehlivost musejí zaručit až dva koncové body, například číslováním paketů a sledováním stavu doručení. Případné ztráty paketu musí odesílatel tento fakt zjistit a ztracené pakety odeslat znovu.
Protokol IP má za úkol doručit paket od odesílatele na příjemce pouze podle IP adresy, která je v hlavičce paketu. IP nenavazuje spojení a nezaručuje doručení. Důvodem je princip \uv{end-to-end}, který říká, že body mezi odesílatelem a příjemcem, jako směrovače a přepínače, by měli být co nejjednodušší. Spolehlivost musejí zaručit až dva koncové body, například číslováním paketů a sledováním stavu doručení. Případné ztráty paketu musí odesílatel zjistit a ztracené pakety odeslat znovu.
Ztráta paketu nastává, když je některý z přepínačů na cestě mezi odesílatelem a příjemcem, zahlcený. Přepínač si přijaté pakety ukládá do fixně velké fronty, ze které také postupně odebírá a snaží se najít další vhodný uzel, kam každý paket poslat. Pro případ přehlcení fronty má přepínač definovanou politiku. Běžná je politika \uv{tail-drop}, která nově příchozí paket, který se nevejde do fronty, zahodí. V tento moment se paket ztrácí.
@@ -333,16 +336,16 @@ Konkrétně architektura TCP/IP je rozdělena do čtyř vrstev: aplikační, tra
\begin{description}
\item[{Aplikační}] \hfill \\
Nejvyšší je \uv{aplikační} vrstva, ve které jsou aplikace. Příkladem protokolů jsou FTP, SMTP, HTTP nebo gRPC.
Nejvyšší je \uv{aplikační} vrstva, ve které jsou aplikace. Příkladem protokolů jsou FTP, SMTP, HTTP nebo gRPC. Tato vrstva je rozbalena až na koncovém bodu, protože neobsahuje žádné podstatné informace pro směrování.
\item[{Transportní}] \hfill \\
Druhá vrstva je \uv{transportní}. Tato vrstva, stejně jako aplikační, je rozbalena až na koncových bodech, jak vidíme na obrázku \ref{fig:tcpip}. Proto se jim někdy říká end-to-end protokoly. Není totiž důležitá pro směrování paketů. Stará se o to, jaké přišli, v jakém pořadí a jestli nejsou poškozené. Příkladem protokolů jsou TCP, UDP nebo QUIC.
Druhá vrstva je \uv{transportní}. Tato vrstva, stejně jako aplikační, je rozbalena až na koncových bodech, jak vidíme na obrázku \ref{fig:tcpip}. Proto se jim někdy říká end-to-end protokoly. Není totiž důležitá pro směrování paketů. Stará se o to, jaké pakety přišli, v jakém pořadí a jestli nejsou poškozené. Příkladem protokolů jsou TCP, UDP nebo QUIC.
\item[{Síťová}] \hfill \\
Pro adresaci je síťová vrstva. Ta směruje a předává jednotlivé datagramy. Příkladem protokolů jsou IP, ARP, RARP nebo IPSEC. Je nutné, aby stejně jako vrstva síťového rozhraní, byla implementována ve všech vrcholech na cestě mezi dvěma počítači, které chtějí komunikovat přes internet.
Pro adresaci slouží síťová vrstva. Ta směruje a předává jednotlivé datagramy. Příkladem protokolů jsou IP, ARP, RARP nebo IPSEC. Je nutné, aby stejně jako vrstva síťového rozhraní, byla implementována ve všech vrcholech na cestě mezi dvěma počítači, které chtějí komunikovat přes internet.
\item[{Síťové rozhraní}] \hfill \\
Nejnižší vrstva, která se stará o přenos přes fyzické médium. Pro různé média bude vyžadovat různé protokoly. Příkladem jsou Ethernet, Token ring, apod.
Nejnižší vrstva, která se stará o přenos přes fyzické médium. Pro různé média bude vyžadovat různé protokoly. Příkladem jsou Ethernet, Token ring a další.
\end{description}
Na obrázku \ref{fig:tcpip} vidíme, jak mezi sebou jednotlivé vrstvy komunikují. Aplikace na počítači $A$ zapíše do transportní vrstvy, kterou počítač $D$ ze stejné vrsvy přečte. Vrstva zná pouze vrstvu pod sebou. Plnou čarou vidíme datový tok zprávy, jak putuje přes jednotlivé vrstvy. Šrafovaná čára reprezentuje abstrahovaný datový tok tak, jak ho vidí vrstva. Počítače B a C jsou propojovací body. Všimněme si, že se nepoužívají transportní nebo aplikační vrstvy, pouze si rozbalí IP paket a zjistí, kam mají pakety posílat dál. Vrstva síťového rozhraní pracuje s různými médii, jak také vidíme na obrázku.
@@ -359,7 +362,7 @@ Na obrázku \ref{fig:tcpip} vidíme, jak mezi sebou jednotlivé vrstvy komunikuj
\subsection{Protokoly v aplikační vrstvě}
Nejvyšší v rodině protokolů TCP/IP je aplikační vrstva s protokoly jako HTTP, gRPC nebo SMTP. Aplikačním protokolům, které nejsou specifické pro konkrétní aplikaci, se říká middleware. Mezi takové řadíme právě HTTP, gRPC nebo DNS, které jsou pro obecné posílání zpráv.
Nejvyšší v rodině protokolů TCP/IP je aplikační vrstva s protokoly jako HTTP, gRPC nebo SMTP. Aplikačním protokolům, které nejsou specifické pro konkrétní aplikaci, se říká middleware. Mezi takové řadíme právě HTTP a gRPC, které jsou pro obecné posílání zpráv a usnadňují aplikacím komunikaci.
\subsubsection{HTTP}
@@ -438,38 +441,53 @@ Je vhodný jako základ pro vlastní transportní protokol. Například protokol
\subsubsection{QUIC}
QUIC je spolehlivý protokol transportní vrstvy, který poskytuje multiplexní komunikaci založenou na TLS 1.3. Autorem protokolu je společnost Google. Mezi jeho hlavní výhody patří redukce ahead-of-line blokování. Tento protokol je pro nás důležitý, protože popisuje implementaci spolehlivosti, handshake a dalších věcí nad protokolem UDP. V pozdější kapitole představíme náš protokol, který je protokolem QUIC inspirovaný a dále ho upravuje. Mezi úpravy patří možnost odeslání zpráv nespolehlivě a s různým seřazením. V této části podrobněji popíšeme části protokolu QUIC, které jsou pro náš protokol důležité.
Výhoda QUIC oproti TCP je možnost vytvořit více nezávislých proudů dat v jednom navázaném spojení, mezi dvěma koncovými body. TCP má vždy právě jeden proud.
Mezi dvěma koncovými body se posílají pakety. Ty obsahují rámce, které se rozdělují na ovládací a proudové. Ovládací slouží pro ovládání koncových bodů a úprava navázaného spojení: otevírání a zavírání proudů, změna stavu nebo udržování spojení naživu. Proudové obsahují aplikační data. Stejně jako TCP, i QUIC přenáší data jako proud bytů a oddělení jednotlivých zpráv je nutné implementovat zvlášť.
\begin{description}
\item[{Pakety}] \hfill \\
Dvě strany komunikující přes QUIC protokol mezi sebou posílají sekvenční Pakety různých typů. Příkladem jsou: \texttt{Initial}, \texttt{0-RTT}, \texttt{Handshake} a \texttt{1-RTT}. Liší se v síle šifrování, které používají, každý typ má svůj číselný prostor a liší se i hlavička. Každý paket má své unikátní pořadové číslo, které se v rozumném čase nesmí použít znova, a to ani při opakovaném poslání stejného paketu z důvodu ztráty. Různé typy paketů mají ale čítač nezávislý. Pakety typu \texttt{Initial} a \texttt{Handshake} mají dlouhou hlavičku a \texttt{0-RTT} a \texttt{1-RTT} mají krátkou hlavičku.
\item[{Spolehlivost}] \hfill \\
Protokol QUIC zajišťuje spolehlivost jednotlivých rámců. Příjemce musí odeslat zpět odesílateli rámec typu \texttt{ACK} se zakódovaným číslem paketu, ve kterém rámce získal. Tento rámec může obsahovat i více paketů zároveň a protokol toho využívá tak, že neposílá \texttt{ACK} tak často.
\item[{Šifrování}] \hfill \\
QUIC už podporuje šifrování přes TLS 1.3 přímo v transportní vrstvě. To znamená dvě výhody: protokol autentizuje klienta, který nám posílá zprávy a tajný klíč lze domluvit už při navazování spojení. TCP naváže spojení pomocí handshake a následně pokračuje další handshake pro TLS. QUIC je v tomto ohledu schopný navázat spojení rychleji.
\item[{Unikátní identifikátory koncových bodů}] \hfill \\
Protokol UDP směřuje datagramy do portů a identifikovat klienty umožňuje pomocí zdrojové IP adresy. Protokol QUIC přidává další vrstvu směrování pomocí \uv{unikátních identifikátorů koncových bodů}. Před začátkem komunikace se oba koncové body domluví na svých identifikátorech a odesílatel do hlavičky paketu zapíše identifikátor cílového spojení. Toto číslo je náhodně vygenerované a s délkou až 62 bitů. Díky šifrování nemůže potenciální útočník toto číslo podvrhnout a vydávat se za někoho jiného, protože kvůli neznalosti klíče by nebyl schopný správně zašifrovat zprávu.
Výhoda je, že klient může změnit IP adresu, např. z důvodu přepnutí z Wi-Fi na mobilní data, není třeba spojení znova navazovat. V případě TCP se často stává, že spojení musí vypršet, a pak znova navázat.
QUIC je spolehlivý protokol transportní vrstvy od společnosti Google, který poskytuje multiplexní šifrovanou komunikaci založenou na TLS 1.3. Multiplexní komunikace znamená, že v jednom navázaném spojení můžeme vytvořit více proudů bytů, ať už jednosměrných nebo obousměrných. To značně redukuje problém ahead-of-line blokování. TCP má vždy právě jeden obousměrný proud. Tento protokol je pro nás důležitý, protože popisuje implementaci spolehlivosti, handshake a dalších vlastností nad protokolem UDP. V pozdější kapitole představíme náš protokol, který je protokolem QUIC inspirovaný a dále ho upravuje. Mezi naše úpravy patří možnost odeslání zpráv nespolehlivě a s různým seřazením. V této části podrobněji popíšeme části protokolu QUIC, které jsou pro náš protokol důležité.
\end{description}
% \begin{description}
% \item[{Pakety}] \hfill \\
% Dvě strany komunikující přes QUIC protokol mezi sebou posílají sekvenční Pakety různých typů. Příkladem jsou: \texttt{Initial}, \texttt{0-RTT}, \texttt{Handshake} a \texttt{1-RTT}. Liší se v síle šifrování, které používají, každý typ má svůj číselný prostor a liší se i hlavička. Každý paket má své unikátní pořadové číslo, které se v rozumném čase nesmí použít znova, a to ani při opakovaném poslání stejného paketu z důvodu ztráty. Různé typy paketů mají ale čítač nezávislý. Pakety typu \texttt{Initial} a \texttt{Handshake} mají dlouhou hlavičku a \texttt{0-RTT} a \texttt{1-RTT} mají krátkou hlavičku.
% \item[{Spolehlivost}] \hfill \\
% Protokol QUIC zajišťuje spolehlivost jednotlivých rámců. Příjemce musí odeslat zpět odesílateli rámec typu \texttt{ACK} se zakódovaným číslem paketu, ve kterém rámce získal. Tento rámec může obsahovat i více paketů zároveň a protokol toho využívá tak, že neposílá \texttt{ACK} tak často.
% \item[{Šifrování}] \hfill \\
% QUIC už podporuje šifrování přes TLS 1.3 přímo v transportní vrstvě. To znamená dvě výhody: protokol autentizuje klienta, který nám posílá zprávy a tajný klíč lze domluvit už při navazování spojení. TCP naváže spojení pomocí handshake a následně pokračuje další handshake pro TLS. QUIC je v tomto ohledu schopný navázat spojení rychleji.
% \item[{Unikátní identifikátory koncových bodů}] \hfill \\
% Protokol UDP směřuje datagramy do portů a identifikovat klienty umožňuje pomocí zdrojové IP adresy. Protokol QUIC přidává další vrstvu směrování pomocí \uv{unikátních identifikátorů koncových bodů}. Před začátkem komunikace se oba koncové body domluví na svých identifikátorech a odesílatel do hlavičky paketu zapíše identifikátor cílového spojení. Toto číslo je náhodně vygenerované a s délkou až 62 bitů. Díky šifrování nemůže potenciální útočník toto číslo podvrhnout a vydávat se za někoho jiného, protože kvůli neznalosti klíče by nebyl schopný správně zašifrovat zprávu.
% Výhoda je, že klient může změnit IP adresu, např. z důvodu přepnutí z Wi-Fi na mobilní data, není třeba spojení znova navazovat. V případě TCP se často stává, že spojení musí vypršet, a pak znova navázat.
Než popíšeme, jak funguje proces handshake pro navázání spojení, popíšeme na čem se dvě strany budou domlouvat. V navázaném spojení má každá strana unikátní ID. Když chce odesílatel poslat paket, musí do jeho hlavičky definovat ID příjemce. Je to z toho důvodu, že koncový bod v QUIC může mít více navázaných spojení pod stejným portem a tímto mezi nimi rozlišuje. V TCP je unikátní identifikátor síťová adresa. Ta se ale může snadno změnit, například když přepneme z mobilních dat na Wi-Fi. V ten moment by v TCP nastal proces time-out, kdy obě strany zjišťují, že už se nevidí a spojení by ukončili. Následně by se původní iniciátor komunikace, nyní s novou IP adresou, pokusil spojení opět navázat. To by znamenalo zopakovat celý proces handshake. V případě QUIC je možné se opakovanému navazování spojení lze vyhnout. Jakmile příjemci dorazí paket na původní ID, ale z nové IP adresy, provede authentizaci a pokud projde, tak si IP adresu druhé strany přenastaví.
% \end{description}
Dostáváme se k šifrování, které QUIC podporuje už v základu. Před tím, než může začít šifrovaná komunikace, musí se obě strany shodnout na tajném klíči, kterým budou zprávy šifrovat. Příkladem protokolu pro šifrovanou komunikaci je TLS. V případě TCP by TLS nebo jiný šifrovací protokol stál ještě nad TCP protokolem. QUIC ale implementuje TLS už v základu, konkrétně verzi 1.3. V původní implementaci by po handshake v TCP bylo potřeba udělat druhý handshake a shodnout se na tajném klíči. V případě QUIC se tajný klíč vytváří už při hlavním
Koncové body komunikují posíláním paketů. Pakety obsahují rámce, které dělíme na ovládací a proudové. Ovládací slouží pro ovládání koncových bodů a vlastností navázaného spojení: otevírání a zavírání proudů, změna stavu nebo udržování spojení naživu. Proudové obsahují aplikační data. Stejně jako TCP, i QUIC přenáší data jako proud bytů a oddělení jednotlivých zpráv je nutné implementovat zvlášť.
Pro navázání spojení je nutné se v QUIC shodnout na ID obou stran a tajném klíči procesem zvaný handshake. Diagram vidíme na obrázku \ref{fig:quic_handshake}. V procesu si dvě strany, neboli koncové body, posílají konkrétní ovládací rámce.
% Unikátní ID
Popíšeme charakteristiky navázaného spojení v QUIC. Obě strany mají unikátní ID, které je specifické pro navázané spojení. Posílané pakety obsahují ID příjemce i ID odesílatele. Tyto unikátní ID používají koncové body k autentizaci. V protokolu TCP se ke stejnému účelu využívá IP adresa.
Problém nastává, když se IP adresa jednoho koncového bodu změní. To se stane například když přepneme z mobilních dat na Wi-Fi. V ten moment by u TCP nastal proces vypršení relace, kdy obě strany zjišťují, že už se nevidí a spojení by ukončili. Následně by se původní iniciátor komunikace, nyní s novou IP adresou, pokusil spojení opět navázat. To by znamenalo zopakovat proces handshake.
V případě QUIC je možné se opakovanému navazování spojení vyhnout. Jakmile příjemci dorazí paket na původní ID, ale z nové IP adresy, provede authentizaci a pokud je úspěšná, tak si IP adresu druhé strany přenastaví.
Nejprve začíná strana, která se chce připojit, posláním paketu typu \texttt{Initial} s rámcem CRYPTO s ClientHello. Server odpoví několika rámci: \texttt{Initial} s \texttt{CRYPTO} rámcem se ServerHello společně s ACK rámcem a paketem typu \texttt{Handshake} ve kterém je \texttt{CRYPTO} rámec s potřebnými informacemi pro TLS. Aplikační data jsou v paketu typu \texttt{1-RTT} a \texttt{0-RTT}. Jakmile klient dostane tyto informace, mohou si strany posílat šifrovaná data. Toho QUIC využívá a první odpověď ze serveru už může obsahovat paket \texttt{1-RTT} se \texttt{STREAM} rámci s šifrovanými daty, jak vidíme na obrázku \ref{fig:quic_handshake}. Dále si všimněme, že každý typ paketu má vlastní prostor čísel. QUIC používá UDP a proto posílá datagramy. Do jednoho datagramu spojuje více paketů. Tři pakety ze serveru, které přijdou jako odpověď, se tak mohou odeslat jako jeden datagram.
% Šifrování
Aby bylo možné v protokolu provést autentizaci, využívá QUIC kryptografii. Konkrétně už v základu implementuje TLS 1.3 pro šifrovanou komunikaci. V případě TCP by TLS nebo jiný šifrovací protokol stál ještě nad TCP protokolem. Po handshake v TCP je potřeba udělat druhý handshake a shodnout se na tajném klíči. V případě QUIC je navázání spojení a domluva na tajném klíči jedna výměna. Další zajímavostí je, že ve verzi TLS 1.3 je handshake zkrácen, protože se není třeba domlouvat na použitém šifrovacím algoritmu, jako tomu bylo v předešlích verzích. Nová verze má definovaných pouze pár možných a iniciátor rovnou posílá svou část veřejného klíče pro každý možný algoritmus. Druhá strana si pak jeden algoritmus vybere.
% Paket
Paket v QUIC se skládá z hlavičky a těla. Pakety mají různé typy, které popíšeme později. Prozatím předpokládejme, že v hlavičce je ID odesílatele a ID příjemce. Taktéž je každý paket očíslovaný. Pokud dva pakety v jedné instanci spojení od stejného odesílatele mají stejné číslo, tak jsou povážovány za identické. To znamená, že každý další příchozí s již zpracovaným číslem může příjemce zahodit. Každý paket obsahuje rámce. Ty mají také typ. Nejčastěji bude v proudu rámec typu STREAM, který obsahuje data odeslaná aplikací. Příjemce si ze STREAM rámců lokálně skládá proud bytů. Každý takový rámec totiž obsahuje informace o který úsek v odeslaném proudu, se jedná. Příjemce tak může snadno zjistit, která část proudu mu ještě chybí.
%Takový rámec zároveň definuje úsek proudu, který je v těle obsažený. Příjemce si tak postupně skládá celý proud, podobně jako TCP.
Popíšeme jak celý proces handshake vypadá. Diagram můžeme vidět na obrázku \ref{fig:quic_handshake}. Vidíme dva koncové body vyjádřené svislými čarami. Ty se mezi sebou domlouvají na svých ID a tajném klíči.
Nejprve popíšeme domluvu na unikátních ID. Iniciátor si vygeneruje svoje ID a posílá rámec, kde v hlavičce je jeho ID a ID příjemce zvolí dočasně náhodně. Jakmile rámec dorazí a příjemce zjistí, že tohle ID odesílatele nemá v registru, vytvoří novou instanci spojení ve stavu ReceivedHello. Přiřadí mu dvě ID, první to, co vybral iniciátor a druhé si vybere sám. Od té doby všechny pakety, které ve spojení odešle, budou mít ID odesílatele právě jeho zvolené ID. I tak si dočasně ponechává ID, které zvolila druhá strana. Je to řešení případu, kdy druhá strana odeslala více paketů ještě před tím, než se dozvěděla zvolené ID.
Všimněme si teď různých typů paketů, jako: Initial, Handshake, 0-RTT a 1-RTT. Liší se především v síle šifrovaní. Pakety typu Initial a 0-RTT se používají, když ještě není domluvený tajný klíč a jsou snadněji dešifrovatelné. Handshake a 1-RTT používají plné šifrování. Význam Initial je zřejmý a 0-RTT se používá pro rychlé sdělení informací druhé straně ještě před navázáním spojení. Není vhodné ale do takového paketu ukládat tajné informace, které nechceme, aby četla třetí strana. Zároveň QUIC umožňuje poslat více paketů v jednom datagramu. Proto v diagramu vidíme, že iniciátor posílá paket Initial i 0-RTT najednou.
% První paket je typu \bold{Initial} a obsahuje rámec \bold{CRYPTO} s parametrem \uv{Client Hello} neboli CH.
% Nejprve začíná strana, která se chce připojit, posláním paketu typu \texttt{Initial} s rámcem CRYPTO s ClientHello. Server odpoví několika rámci: \texttt{Initial} s \texttt{CRYPTO} rámcem se ServerHello společně s ACK rámcem a paketem typu \texttt{Handshake} ve kterém je \texttt{CRYPTO} rámec s potřebnými informacemi pro TLS. Aplikační data jsou v paketu typu \texttt{1-RTT} a \texttt{0-RTT}. Jakmile klient dostane tyto informace, mohou si strany posílat šifrovaná data. Toho QUIC využívá a první odpověď ze serveru už může obsahovat paket \texttt{1-RTT} se \texttt{STREAM} rámci s šifrovanými daty, jak vidíme na obrázku \ref{fig:quic_handshake}. Dále si všimněme, že každý typ paketu má vlastní prostor čísel. QUIC používá UDP a proto posílá datagramy. Do jednoho datagramu spojuje více paketů. Tři pakety ze serveru, které přijdou jako odpověď, se tak mohou odeslat jako jeden datagram.
\begin{figure}
@@ -480,50 +498,50 @@ Nejprve začíná strana, která se chce připojit, posláním paketu typu \text
\label{fig:quic_handshake}
\end{figure}
Všimněme si speciálního typu paketu \texttt{0-RTT}, který slouží pro poslání aplikačních dat ještě před samotným navázáním spojení, ale pouze se základním šifrováním. Pro tento paket se využívá první Destination Connection ID, které ale vygeneroval iniciátor komunikace. Jedno spojení může mít přiřazeno více ID. Spojení, které si založí druhá strana, si přiřadí jak ID vygenerované touto stranou, tak ID, které zvolil iniciátor. Když přijde později paket \texttt{0-RTT}, bude správně nasměrován na instanci spojení.
% Všimněme si speciálního typu paketu \texttt{0-RTT}, který slouží pro poslání aplikačních dat ještě před samotným navázáním spojení, ale pouze se základním šifrováním. Pro tento paket se využívá první Destination Connection ID, které ale vygeneroval iniciátor komunikace. Jedno spojení může mít přiřazeno více ID. Spojení, které si založí druhá strana, si přiřadí jak ID vygenerované touto stranou, tak ID, které zvolil iniciátor. Když přijde později paket \texttt{0-RTT}, bude správně nasměrován na instanci spojení.
\subsection{Sokety}
% \subsection{Sokety}
Populární rozhraní pro použití protokolů v transportní vrstvě jsou tzv. \uv{Berkeley sokety}. Soket je komunikační koncový bod, do kterého aplikace zapisuje data, která chce poslat přes síť druhému procesu, a ze kterého zároveň může číst příchozí data. Jedná se o abstrakci nad konkrétním otevřeným portem. Nelze vytvořit dva sokety se stejným portem.
% Populární rozhraní pro použití protokolů v transportní vrstvě jsou tzv. \uv{Berkeley sokety}. Soket je komunikační koncový bod, do kterého aplikace zapisuje data, která chce poslat přes síť druhému procesu, a ze kterého zároveň může číst příchozí data. Jedná se o abstrakci nad konkrétním otevřeným portem. Nelze vytvořit dva sokety se stejným portem.
\subsection{Asynchroní vstupně výstupní operace}
% \subsection{Asynchroní vstupně výstupní operace}
Čtení a zápis na socket je běžně blokující operace. To znamená, že při systémovém volání pro čtení 10 bytů, bude volání blokovat, dokud na socket nepřijde 10 bytů. V případě serveru pro online hru je to nevhodné, protože pokud nám nic nepřišlo, můžeme mezitím vykonávat jinou logiku hry. Socket lze ale nastavit tak, aby vracel hned a počet bytů neznamenal konkrétní počet, ale pouze maximum. Je ale poté třeba zprávu opět sestavit z postupně přečtených částí v aplikaci.
% Čtení a zápis na socket je běžně blokující operace. To znamená, že při systémovém volání pro čtení 10 bytů, bude volání blokovat, dokud na socket nepřijde 10 bytů. V případě serveru pro online hru je to nevhodné, protože pokud nám nic nepřišlo, můžeme mezitím vykonávat jinou logiku hry. Socket lze ale nastavit tak, aby vracel hned a počet bytů neznamenal konkrétní počet, ale pouze maximum. Je ale poté třeba zprávu opět sestavit z postupně přečtených částí v aplikaci.
Podobnému přístupu se říká \uv{asynchronní sockety}. Jinými slovy to znamená oddělení volání a samotného vykonání. V tomto případě sice zavoláme operaci čtení, ale toto volání se vloží do fronty, a jiné samostatné vlákno ho vykoná asynchroně později. Protějšek z reálného světa je hození dopisu do schránky a pokračování v jiné práci. Doručení se stane v nejbližších dnech a to někým jiným, protějšek jiného vlákna. Pro lepší představu si pár existujících implementací představíme.
% Podobnému přístupu se říká \uv{asynchronní sockety}. Jinými slovy to znamená oddělení volání a samotného vykonání. V tomto případě sice zavoláme operaci čtení, ale toto volání se vloží do fronty, a jiné samostatné vlákno ho vykoná asynchroně později. Protějšek z reálného světa je hození dopisu do schránky a pokračování v jiné práci. Doručení se stane v nejbližších dnech a to někým jiným, protějšek jiného vlákna. Pro lepší představu si pár existujících implementací představíme.
\subsubsection{ZeroMQ}
% \subsubsection{ZeroMQ}
Při použití knihovny ZeroMQ vytváříme objekt kontextu pomocí \inlcpp{ctx=zmq\_context(num\_threads)}. Ten obsahuje konkrétní počet vláken specifikovaný parametrem \inlcpp{num\_thread}. Když následně zavoláme \inlcpp{zmq\_send(ctx, x)}, protějšek klasického \inlcpp{send(x)}, tak nedojde k blokování. Místo toho se zpráva $x$ umístí do fronty, ze které pak vlákna z \inlcpp{zmq\_context} tzv. \uv{kradou} a odesílají v pozadí.
% Při použití knihovny ZeroMQ vytváříme objekt kontextu pomocí \inlcpp{ctx=zmq\_context(num\_threads)}. Ten obsahuje konkrétní počet vláken specifikovaný parametrem \inlcpp{num\_thread}. Když následně zavoláme \inlcpp{zmq\_send(ctx, x)}, protějšek klasického \inlcpp{send(x)}, tak nedojde k blokování. Místo toho se zpráva $x$ umístí do fronty, ze které pak vlákna z \inlcpp{zmq\_context} tzv. \uv{kradou} a odesílají v pozadí.
To samé platí o \inlcpp{zmq\_receive}, které si v pozadí skládá celou zprávu. TCP totiž nemá žádnou strukturu zprávy, a proto když zavoláme operaci pro čtení ze soketu, můžeme dostat jen část. ZeroMQ pracuje v proudu s celými zprávami, které za nás skládá.
% To samé platí o \inlcpp{zmq\_receive}, které si v pozadí skládá celou zprávu. TCP totiž nemá žádnou strukturu zprávy, a proto když zavoláme operaci pro čtení ze soketu, můžeme dostat jen část. ZeroMQ pracuje v proudu s celými zprávami, které za nás skládá.
\subsubsection{Work stealing}
% \subsubsection{Work stealing}
Běžnou strategií pro využití dynamického počtu vláken je \uv{work stealing}. Jiné strategie jsou třeba \uv{work sharing}. Implementace obsahuje synchronizovanou frontu, do které vkládáme popisy úkolů, které se mají vykonat. Vlákno, které se snaží z této fronty krást, je \uv{worker} neboli pracovník. Pokud je fronta správně synchronizovaná, může z ní krást libovolný počet vláken. Jsou různé možnosti, co může být popis úkolu. Například anonymní funkce nebo ID. Zajímavou vlastností tohoto přístupu je, že součást úkolu může být vložení
% Běžnou strategií pro využití dynamického počtu vláken je \uv{work stealing}. Jiné strategie jsou třeba \uv{work sharing}. Implementace obsahuje synchronizovanou frontu, do které vkládáme popisy úkolů, které se mají vykonat. Vlákno, které se snaží z této fronty krást, je \uv{worker} neboli pracovník. Pokud je fronta správně synchronizovaná, může z ní krást libovolný počet vláken. Jsou různé možnosti, co může být popis úkolu. Například anonymní funkce nebo ID. Zajímavou vlastností tohoto přístupu je, že součást úkolu může být vložení
\subsubsection{Async/Await}
% \subsubsection{Async/Await}
Populární implementací, kterou vidíme například v Rust nebo C\#, je \uv{async/await}. V programu označíme funkci jako asynchronní pomocí klíčového slova \inlcpp{async}. Zavoláním takové funkce speciálním \inlcpp{await} voláním způsobí, že se celý aktuální kontext vloží jako úkol do fronty, ze které pracovníci kradou. Tento přístup vyžaduje, aby měly prvky ve frontě definované závislosti mezi sebou, protože úkol s aktuálním kontextem bude závislý na dokončení právě funkce, kterou jsou zavolali pomocí \inlcpp{await}. Toto volání tak do fronty vložíme taky. Pro definice závislostí se používají ukazatele na čítače. Pokud úkol $A$ závisí na úkolu $B$, nastaví si $A$ čítač $C_A$ na hodnotu $1$ a $B$ dostane na čítač $C_A$ ukazatel. Po dokončení tento čítač dekrementuje. Pracovník může krást z fronty jen ty úkoly, které mají hodnotu čítače roven nule.
% Populární implementací, kterou vidíme například v Rust nebo C\#, je \uv{async/await}. V programu označíme funkci jako asynchronní pomocí klíčového slova \inlcpp{async}. Zavoláním takové funkce speciálním \inlcpp{await} voláním způsobí, že se celý aktuální kontext vloží jako úkol do fronty, ze které pracovníci kradou. Tento přístup vyžaduje, aby měly prvky ve frontě definované závislosti mezi sebou, protože úkol s aktuálním kontextem bude závislý na dokončení právě funkce, kterou jsou zavolali pomocí \inlcpp{await}. Toto volání tak do fronty vložíme taky. Pro definice závislostí se používají ukazatele na čítače. Pokud úkol $A$ závisí na úkolu $B$, nastaví si $A$ čítač $C_A$ na hodnotu $1$ a $B$ dostane na čítač $C_A$ ukazatel. Po dokončení tento čítač dekrementuje. Pracovník může krást z fronty jen ty úkoly, které mají hodnotu čítače roven nule.
Tento přístup je často používán v kontext asynchronních vstupně výstupních operací. Vlákno, které čeká na blokující operaci může v mezičase pracovat na jiném úkolu v aplikaci namísto čekání. V základu metoda neslouží k paralelismu, k tomu je potřeba další operace zvaná \uv{počkej na všechny}, která vloží do fronty vícero úkolů a aktuální kontext, který závisí právě na všech těchto úkolech. Ty tak mají šanci běžet paralelně.
% Tento přístup je často používán v kontext asynchronních vstupně výstupních operací. Vlákno, které čeká na blokující operaci může v mezičase pracovat na jiném úkolu v aplikaci namísto čekání. V základu metoda neslouží k paralelismu, k tomu je potřeba další operace zvaná \uv{počkej na všechny}, která vloží do fronty vícero úkolů a aktuální kontext, který závisí právě na všech těchto úkolech. Ty tak mají šanci běžet paralelně.
Příklad z reálného světa je poslat dopis s otázkou. Opět stačí hodit dopis do schránky. Až si ho někdo přečte, může nám poslat odpověď. Když dostaneme odpověď, vzpomeneme si, kde jsme skončili, když jsem práci přerušili a odeslali dopis s otázkou, a když už máme odpověď, tak pokračujeme.
% Příklad z reálného světa je poslat dopis s otázkou. Opět stačí hodit dopis do schránky. Až si ho někdo přečte, může nám poslat odpověď. Když dostaneme odpověď, vzpomeneme si, kde jsme skončili, když jsem práci přerušili a odeslali dopis s otázkou, a když už máme odpověď, tak pokračujeme.
\subsubsection{Boost Asio}
% \subsubsection{Boost Asio}
Velmi podobná ZeroMQ je Boost ASIO. Ta ale nechává vytváření vláken na nás. Pouze vytvoříme objekt kontextu \inlcpp{asio\_context}, který má frontu úkolů a metodu \inlcpp{run}. Když z vlákna zavoláme tuto metodu, stane se vlákno pracovníkem, který krade práci z fronty, která je v objektu kontextu.
% Velmi podobná ZeroMQ je Boost ASIO. Ta ale nechává vytváření vláken na nás. Pouze vytvoříme objekt kontextu \inlcpp{asio\_context}, který má frontu úkolů a metodu \inlcpp{run}. Když z vlákna zavoláme tuto metodu, stane se vlákno pracovníkem, který krade práci z fronty, která je v objektu kontextu.
Tento přístup je intuitivnější, protože se jedná přesně o to, jak pracovníci fungují. Jedná se o funkci, která se opakovaně snaží odebrat z fronty úkolů. Pokud fronta není prázdná a pracovník se dostane z ní úkol, začne na něm pracovat. Jakmile práci dokončí, vrací se ke kroku odebírání z fronty.
% Tento přístup je intuitivnější, protože se jedná přesně o to, jak pracovníci fungují. Jedná se o funkci, která se opakovaně snaží odebrat z fronty úkolů. Pokud fronta není prázdná a pracovník se dostane z ní úkol, začne na něm pracovat. Jakmile práci dokončí, vrací se ke kroku odebírání z fronty.
Důvod, proč nevytvořit thread pro každou odeslanou zprávu je, že vyžaduje systémové volání, které může způsobit zpomalení. Proto se často používají tzv. green thready, fibery, user thready, ... což jsou vlákna kompletně v uživatelském prostoru. Není tak třeba žádné systémové volání.
% Důvod, proč nevytvořit thread pro každou odeslanou zprávu je, že vyžaduje systémové volání, které může způsobit zpomalení. Proto se často používají tzv. green thready, fibery, user thready, ... což jsou vlákna kompletně v uživatelském prostoru. Není tak třeba žádné systémové volání.
% \subsubsection{Stack pointer}
@@ -587,7 +605,7 @@ Důvod, proč nevytvořit thread pro každou odeslanou zprávu je, že vyžaduje
\section{Hra}
V této kapitole představíme hru, kterou jsem vyvinuli pro implementaci různých technik a jejich následného měření. Ve hře má každý hráč svou postavu, se kterou může volně pohybovat ve 3D prostoru. Hra simuluje na postavách hráčů realistickou fyziku. Pokud se do hry připojí více hráčů, tak se navzájem vidí. Každý hráč spustí program klienta, který zobrazuje stav hry a postavy hráčů v 3D prostoru. V další kapitole porovnáme plynulost pohybu a rychlost odezvy, které jsou pro hratelnost důležité.
V této kapitole představíme hru, kterou jsem vyvinuli pro demonstraci různých technik a jejich měření. Ve hře má každý hráč svou postavu, se kterou může volně pohybovat ve 3D prostoru. Hra simuluje na postavách hráčů realistickou fyziku. Pokud se do hry připojí více hráčů, tak se navzájem vidí. Každý hráč spustí program klienta, který zobrazuje stav hry a postavy hráčů v 3D prostoru. V další kapitole porovnáme plynulost pohybu a rychlost odezvy, které jsou pro hratelnost důležité.
V první části popíšeme architekturu hry a našeho enginu. Následně rozšíříme a jinak upravíme tento model pro hru více hráčů. Vytvoříme tak distribuovaný systém.
@@ -602,7 +620,7 @@ Nakonec představíme i architekturu peer-to-peer, kdy umožníme, aby v systém
\subsection{Engine}
Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do hloubky upravovat. Implementace je v jazyce C++, protože je v tomto jazyce napsáno spousty nástrojů a knihoven právě pro vývoj her. Díky tomu se vývoj značně akceleroval. Zároveň je to vhodný jazyk pro práci na nižší úrovni, a to je důležité pro některé metody optimalizace. Engine je implementovaný jako modulární monolit.
Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do hloubky upravovat. Implementace je v jazyce C++, protože je v tomto jazyce napsáno spousty nástrojů a knihoven právě pro vývoj her. Díky tomu se vývoj značně akceleroval. Zároveň je to vhodný jazyk pro práci na nižší úrovni, a to je důležité pro některé metody optimalizace. Engine je implementovaný jako modulární monolit. Dosavadní architekturu vidíme na obrázku \ref{fig:single_player_game}. Jednotlivé komponenty si popíšeme.
% Vstupy od hráče -> derivace
% Derivace + Stav -> integrace
@@ -612,7 +630,7 @@ Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do
% Vstup od hráče -> akce
% Co je herní stav, jak probíhá kolo?
Program hry jsme rozdělili na \uv{stav} a \uv{řídící logiku}. Stav obsahuje množinu entit, které jsou ve hře a jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, nepřátele nebo interaktivní prvky jako truhla s pokladem. Entita má přiřazené vlastnosti, které ji dávají stav. Entita nepřítele může mít vlastnost "množství životů" a truhla vlastnost "poklad", která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
Mezi hlavní komponenty patří \uv{stav} hry a \uv{řídící logika}. Stav obsahuje množinu entit, které jsou ve hře a jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, nepřátele nebo interaktivní prvky jako truhla s pokladem. Entita má přiřazené vlastnosti, které ji dávají stav. Entita nepřítele může mít vlastnost "množství životů" a truhla vlastnost "poklad", která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
% Detaily k implementaci, ale stále dost abstrahované.
% Zmínit svět, ve kterém držíme stav hry. Zmínit derivaci (proces sbírání vstupů, prozatím jen od hráče). Zmínit integraci jako aplikaci derivace na stav.
@@ -621,9 +639,16 @@ Program hry jsme rozdělili na \uv{stav} a \uv{řídící logiku}. Stav obsahuje
Druhá část je řídící logika, která iterativně mění stav hry. Tato změna může být pouze na základě stavu světa, například posune objekt, který má nenulový vektor zrychlení. Mimo to může řídící logika reagovat na údalosti. Například stisk tlačítka W je událost, který vyvolá změnu vektoru zrychlení hráče, který tlačítko stiskl. V důsledku toho se postava hráče pohne.
Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou 1/60 sekundy nebo 1/24 sekundy. Vyšší frekvence znamená nižší odezvu a lepší plynulost. Nižší frekvence znamená menší výpočetní náročnost. Pro pomalejší hry bez rychlých akčních pasáží se využívá frekvence 24Hz a u kompetentních her i 120Hz.
Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou 1/60 sekundy nebo 1/24 sekundy. Vyšší frekvence znamená nižší odezvu a lepší plynulost. Nižší frekvence znamená menší výpočetní náročnost. Pro pomalejší hry bez rychlých akčních pasáží se využívá frekvence 24Hz a u kompetentních her i 120Hz
\footnote{Článek od Riot Games ukazuje, jak důležitá je odezva u kompetetivních her. U profesionálních hráčů je poznat i rozdíl mezi 120Hz a 240Hz. https://www.riotgames.com/en/news/peeking-valorants-netcode}.
https://www.riotgames.com/en/news/peeking-valorants-netcode
\begin{figure}
\begin{center}
\includegraphics[width=0.5\textwidth]{graphics/single_player_game.pdf}
\end{center}
\caption{Architektura hry pro jednoho hráče}
\label{fig:single_player_game}
\end{figure}
\subsubsection{Fyzický engine}
@@ -649,9 +674,9 @@ Motivací této architektury je jednoduché skládání různých entit, které
https://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, přiřazování komponent a definici systémů. Entita je v této knihovně pouze unikátně identifikační číslo a komponenta je libovolný typ. V registru pak můžeme vytvářet \uv{pohledy} na n-tici typů komponent, které jsou seznam právě všech entit v registru, které všechny tyto komponenty mají. Ten můžeme procházet a libovolně měnit atributy komponent. Příklad použití vidíme na TODO, kde nejprve vytvoříme registr do kterého přidáme novou entity a přiřadíme ji komponentu typu Transform. Nakonec definujeme pohled na všechny entity, které mají komponentu obou typů: Transform i CharacterBody. Před tento pohled iterujeme a v každé iteraci kopírujeme.
\begin{kicode}{cpp}{}{Příklad použití knihovny Entt}
\begin{kicode}{cpp}{code:entt}{Příklad použití knihovny Entt}
entt::registry registry;
entt::entity entity = registry.create();
@@ -667,7 +692,7 @@ Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, při
});
\end{kicode}
Představíme komponenty, které jsme pro hru definovali a proč:
Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, přiřazování komponent a definici systémů. Entita je v této knihovně pouze unikátně identifikační číslo a komponenta je libovolný typ. V registru pak můžeme vytvářet \uv{pohledy} na n-tici typů komponent, které jsou seznam právě všech entit v registru, které všechny tyto komponenty mají. Ten můžeme procházet a libovolně měnit atributy komponent. Příklad použití vidíme v \ref{code:entt}, kde nejprve vytvoříme registr do kterého přidáme novou entity a přiřadíme ji komponentu typu Transform. Nakonec definujeme pohled na všechny entity, které mají komponentu obou typů: Transform i CharacterBody. Před tento pohled iterujeme a v každé iteraci kopírujeme. Představíme komponenty, které jsme pro hru definovali a proč:
\begin{description}
@@ -683,9 +708,15 @@ Představíme komponenty, které jsme pro hru definovali a proč:
\end{description}
\subsubsection{ImGui}
Některé metriky jsme chtěli zobrazit přímo v klientovi pro hru. Jsou to například příchozí a odchozí množství dat klienta. Tyto data neukládáme nikam do databáze a musíme si je spravovat lokálně. Proto jsme v klientovi potřebovali zobrazit základní uživatelské rozhraní. Zvolili jsme knihovnu ImGui a ImPlot, které se integrují přímo do vykreslovacího enginu. Pro knihovnu jsme přidali jednu novou úlohu do vykreslovacího grafu.
S knihovnou se pracuje procedurálně, nikoliv objektově. Každý snímek je třeba definovat celé rozhraní znova. Pro definici voláme různé funkce, kde každá definuje v rozhraní některý z možných prvků. Například funkce \inlcpp{InputText} zobrazí vstup pro text. Důležitá je funkce \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
\newcommand{\inlcpp}[1]{\kiinlinecode{cpp}{!}{#1}}
@@ -706,21 +737,20 @@ Druhá varianta je model peer-to-peer. Ten je složitější z hlediska konziste
Druhá komplikace je, že výsledek každé aplikace akce být všude stejný. Problém nastává u generování pseudo-náhodných čísel nebo u integrace. Například fyzický engine postupně integruje pozice entit podle derivace, která je reprezentována vektorem zrychlení. Každá integrace musí definovat, o jak velký časový krok se jedná (tzv. delta-time) a všichni účastníci se na něm musejí shodnout. Různé délky by rychle způsobily desynchronizaci. Zároveň všechny pseudonáhodné generátory musejí mít stejný počáteční seed. Je třeba si dát pozor na aritmetriku s plovoucí desetinou čárkou, která na různých platformách může dopadnout trochu jinak. I malé rozdíly se mohou rychle projevit.
Řídící logiku jsme rozdělili na Server World Controller a Client World Controller. Toto rozdělení nás motivovalo dále oddělit integraci světa do vlastní třídy tak, aby logika mohla být sdílená mezi ovladačem pro jednoho hráče a pro více hráčů.
% Každá akce, která přijde na server, musí být autorizována. Například ověřit, že se hráč nestaží interagovat s objektem, od kterého je moc daleko. Pokud vše proběhne v pořádku, bude přidána do fronty pro aktuální iteraci, kterou pak celou aplikuje na stav podle definované logiky. V případě, že autorizace selže, může server, s určitou tolerancí, klienta odpojit. Svůj stav průběžně replikuje klientům. Frekvence závisí na typu hry a pohybuje se od 20Hz pro pomalejší nekompetentní hry, až po 120Hz pro e-sport hry, jako například hra Valorant TODO ODKAZ.
Rozšířenou architekturu vidíme na obrázku \ref{fig:multi_player_game}. Hned si všimneme, že se svět rozdvojil na instanci na serveru a instanci na klientovi. Jsou to právě tyto dvě instance, které se snažíme posíláním zpráv synchronizovat. Řídící logiku jsme rozdělili na Server World Controller a Client World Controller. Všimněme si, že ovladač na klientovi ne nutně obsahuje systémy, které by měnili stav hry, ale pouze kopíruje to, co mu server poslal ve zprávě pro snapshot. Na druhou stranu posílá akce, které přečetl od hráče. Oba ovladače ale zapisují do své instance světa.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/client-server-architecture.pdf}
\includegraphics[width=0.5\textwidth]{graphics/multi_player_game.pdf}
\end{center}
\caption{Softwarová architektura hry}
\label{fig:client_server_architecture}
\caption{Architektura hry pro více hráčů}
\label{fig:multi_player_game}
\end{figure}
% Každá akce, která přijde na server, musí být autorizována. Například ověřit, že se hráč nestaží interagovat s objektem, od kterého je moc daleko. Pokud vše proběhne v pořádku, bude přidána do fronty pro aktuální iteraci, kterou pak celou aplikuje na stav podle definované logiky. V případě, že autorizace selže, může server, s určitou tolerancí, klienta odpojit. Svůj stav průběžně replikuje klientům. Frekvence závisí na typu hry a pohybuje se od 20Hz pro pomalejší nekompetentní hry, až po 120Hz pro e-sport hry, jako například hra Valorant TODO ODKAZ.
\subsection{Server}
Představíme, jak vypadá architektura pro server a komponenty, ze kterých se skládá. Stejně jako hra jednoho hráče si ukládá stav hry, tedy instanci \inlcpp{World}. Navíc pro hru více hráčů jsou komponenty \uv{replikátor} a \uv{manažer zájmu}. Replikátor posílá snapshoty a replikuje tak stav na serveru. Může posílat i jednorázové události.
Představíme, jak vypadá architektura pro server a komponenty, ze kterých se skládá. Stejně jako hra jednoho hráče si ukládá stav hry, tedy instanci \inlcpp{World}. Navíc pro hru více hráčů jsou komponenty \uv{replikátor}. Ten posílá snapshoty a replikuje tak stav na serveru. Může posílat i jednorázové události.
Replikátor pracuje pouze s entitami a komponentami. Proto můžeme snapshot zjednoduššit na seznam entit s komponentami. Dále bude obsahovat seznam entit, které jsou nové a které naopak už mají zmizet. Stará se jen o to, jak tento stav synchronizovat pomocí posílání zpráv.
@@ -777,23 +807,21 @@ Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo
% Měl by poskytovat možnost, jak posílat zprávy nespolehlivě.
% Zpráva přijde vždy buď celá, nebo vůbec.
V aplikační vrstvě jsme definovali middleware protokol, který umožňuje obousměrné posílání typovaných zpráv. Typ zprávy je definován čtyř bytovým kladným číslem. Protokol jsme umístili do modulu \inlcpp{message_protocol}. Protokol využívá TCP, ale později implementaci změníme tak, aby používal náš protokol.
Pro navázání spojení musejí obě strany vytvořit objekt
V aplikační vrstvě jsme definovali middleware protokol, který umožňuje obousměrné posílání typovaných zpráv. Typ zprávy je definován čtyř bytovým kladným číslem. Protokol jsme umístili do modulu \inlcpp{message_protocol}. Protokol využívá TCP, ale později implementaci změníme tak, aby používal náš protokol. Koncové body v protokolu se chovají jako fronta příchozích a fronta odchozích zpráv. Pro koncový bod můžeme definovat tzv. \uv{dispečer}, definovaný typem zprávy a anonymní funkci, která každou příchozí zprávu tohoto typu zpracuje.
% Popíšeme náš middleware pro posílání zpráv a jeho protokol založený na TCP. Poskytuje službu oboustranného peer-to-peer posílání zpráv na různé koncové body, které jsou identifikované čtyř bytovým číslem. Strana může pro libovolný identifikátor definovat handler, který se po získání takové zprávy spustí. Protokol zajišťuje spolehlivost na úrovni zpráv. To znamená, že zpráva dorazí buď celá, nebo vůbec. Později v kapitole \ref{sec:quicr} představíme náš protokol v transportní vrstvě, který umožňuje posílat zprávy spolehlivě i nespolehlivě.
\subsubsection{Kódování zpráv}
Middleware využívá TCP, které na rozhraní při čtení a zápisu pracuje s proudem bytů, který není logicky rozdělený. Jediné pevné body jsou začátek a konec proudu. UDP na druhou stranu zaručuje, že celý buffer dat odeslaný přes \texttt{write} operaci bude přečtený vždy právě jedním voláním \texttt{read} operace. Náš protokol definuje oddělení zpráv tak, aby šli v proudu najít.
Middleware využívá TCP, které na rozhraní při čtení a zápisu pracuje s proudem bytů, který není logicky rozdělený. Jediné pevné body jsou začátek a konec proudu. UDP na druhou stranu zaručuje, že celý buffer dat odeslaný přes \inlcpp{write} operaci bude přečtený vždy právě jedním voláním \inlcpp{read} operace. Náš protokol definuje oddělení zpráv tak, aby šli v proudu najít.
První čtyři byty každé zprávy jsou tzv. MAGIC číslo. Konstanta, která nemá jiný význam než záchytný bod při čtení. Dekodér v počátečním stavu hledá v proudu tuto hodnotu. Pokud ji do určitého počtu bytů nenajde, ukončí spojení z důvodu narušení protokolu. Když konstantu najde, přečte další čtyři byty, které reprezentují délku těla a další čtyři byty reprezentující ID koncového bodu.
Vlastnost, kterou jsme v průběhu testování potřebovali, byla možnost request-reply modelu. Zároveň jsme ale chtěli mít možnost posílat zprávy stylem fire-and-forget. Nemohli jsme tedy použít způsob, jaký používá HTTP/2. Místo toho lze při odeslání zprávy definovat, že čeká na odpověď a její identifikační číslo. Druhá strana naopak může poslat odpověď, když zprávu definuje jako odpověď pomocí příznaku a identifikačního čísla zprávy, na kterou odpovídá.
Vlastnost, kterou jsme v průběhu testování potřebovali, byla možnost request-reply modelu. Zároveň jsme ale chtěli mít možnost posílat zprávy stylem fire-and-forget. To znamená, že zprávu odešleme a nečekáme odpověď. Nemohli jsme tedy použít způsob, jaký používá HTTP/2. Místo toho lze při odeslání zprávy definovat, že čeká na odpověď a její identifikační číslo. Druhá strana naopak může poslat odpověď, když zprávu definuje jako odpověď pomocí příznaku a identifikačního čísla zprávy, na kterou odpovídá.
\subsubsection{Implementace}
Vytvořili jsme třídu \inlcpp{MessagingSession}, která má na rozhraní metody \inlcpp{set\_handler(endpoint\_id)}, \inlcpp{send} a \inlcpp{request}. První metoda nastaví pro koncový bod \inlcpp{endpoint\_id} handler lambdu. Druhá pošle zprávu stylem fire-and-forget. To znamená, že se nestaráme o odpověď a synchronizace je v moment, kdy si zprávu převezme middleware. Poslední metoda umožňuje poslat požadavek a nastavit handler pro odpověď.
Vytvořili jsme třídu \inlcpp{MessagingSession}, která má na rozhraní metody \inlcpp{set\_handler(endpoint\_id)}, \inlcpp{send} a \inlcpp{request}. První metoda nastaví pro koncový bod \inlcpp{endpoint\_id} handler, který je definovaný anonymní funkcí. Druhá pošle zprávu stylem fire-and-forget. To znamená, že se nestaráme o odpověď a synchronizace je v moment, kdy si zprávu převezme middleware. Poslední metoda umožňuje poslat požadavek a nastavit handler pro odpověď.
\subsubsection{Detekce a náprava chyb}
@@ -804,9 +832,11 @@ Občas mohou nastat v proudu chyby, kdy zprávu nelze dekódovat, nebo nastane c
\subsection{Serializace}
Zpráva je v programu reprezentovaná objektem. Proces, který ji převede na n-tici bytů se říká \uv{serializace}. Existují různé knihovny, které umí objekty serializovat. Některé umí serializovat přímo třídy definované v konkrétním programovacím jazyce. Jazyk C++ ale nemá runtime reflexi jako C\# nebo silná makra jako Rust, a tento způsob není možný. Druhá varianta je definovat tyto třídy ve speciálním jazyce pro definici schémat. Před sestavením programu z této definice vygenerujeme třídy v jazyce, který potřebujeme. Do tříd se vygenerují i metody pro serializaci. Tento přístup umožňuje například ProtoBuf, Cap'n'Proto a další. Jeho výhoda je možnost vygenerovat třídy v různých programovacích jazycích. Pokud máme architekturu orientovanou na služby, kde každá je implementována v jiném jazyce, nemusíme definice lokalizovat.
Většinou nechceme používat middleware protokol, který na rozhraní používá n-tice bytů. Lepší je postavit obal, který umožní poslat zprávy reprezentované strukturou. Procesu, který ji převede na n-tici bytů se říká \uv{serializace}. Existují různé knihovny, které umí objekty serializovat. Některé umí serializovat přímo třídy definované v konkrétním programovacím jazyce. Jazyk C++ ale nemá runtime reflexi jako C\# nebo silná makra jako Rust, a tento způsob není možný. Druhá varianta je definovat tyto třídy ve speciálním jazyce pro definici schémat. Před sestavením programu z této definice vygenerujeme třídy v jazyce, který potřebujeme. Do tříd se vygenerují i metody pro serializaci. Tento přístup umožňuje například ProtoBuf, Cap'n'Proto a další. Velká motivace pro použití tohoto přístupu byla možnost reflexe, kterou tyto knihovny umožňují. Další výhoda je pro architekturu orientovanou na služby, kde každá služba je implementována v jiném jazyce, tak nemusíme definice lokalizovat.
Hned na začátku jsme se rozhodli nepoužít JSON nebo XML, protože jsou to textové formáty a jejich forma je často větší než binárních formátů. Například číslo 1 000 000 se v JSON zakóduje do 7 bytů, i když binární reprezentace stejného čísla se vleze do 4 bytů. Rozdíl je téměř dvojnásobný. Každý atribut objektu se v JSONu reprezentuje řetězcem, namísto identifikačním číslem o 2 bytech, které by bylo menší. Výhody formátu jsou především liberalní zpracování, kdy se schémata dvou koncových bodů mohou i trochu lišit, ale pokud má zpráva všechny potřebné atributy, tak se strany domluví. Pokud v binárním formátu je atribut navíc, nemusí se druhé straně podařit zprávu deserializovat. Proto se někdy JSON používá jako záložní formát, kdy dvě strany provedou handshake a domluví se na formátu. Pokud zjistí, že jedna strana používá starší definici schématu, mohou použít záložní JSON.
Hned na začátku jsme se rozhodli nepoužít JSON nebo XML, protože jsou to textové formáty a jejich forma je často větší než binárních formátů. Například číslo 1 000 000 se v JSON zakóduje do 7 bytů, i když binární reprezentace stejného čísla se vleze do 4 bytů. Rozdíl je téměř dvojnásobný. Každý atribut objektu se v JSONu reprezentuje řetězcem, namísto identifikačním číslem o 2 bytech, které by bylo menší. Výhody formátu jsou především liberalní zpracování, kdy se schémata dvou koncových bodů mohou i trochu lišit, ale pokud má zpráva všechny potřebné atributy, tak se strany domluví.
Binární formáty tuto problematiku také řeší, například číslováním atributů, ale stále není řešení tak volné, jako u textových formátů. Obecně hrozí, že v binárním formátu je atribut navíc, nemusí se druhé straně podařit zprávu deserializovat. Proto se někdy JSON používá jako záložní formát, kdy dvě strany provedou handshake a domluví se na formátu. Pokud zjistí, že jedna strana používá starší definici schématu, mohou použít záložní JSON.
Rozhodli jsme se začít velmi rozšířeným ProtoBuf formátem. Začneme definicí zpráv mezi serverem a klientem. Vytvořili jsme WorldServerMessages.proto soubor, do kterého budeme zprávy definovat. Trochu formát \inlcpp{.proto} představíme. V kódu \ref{code:entity_spawn_message} vidíme definici zprávy, která říká, že si příjemce má do svého stavu přidat novou entitu. Obsahuje tři atributy: ID pro navázání budoucích zpráv o entitě, příznak, jestli se jedná o hráče a jméno.
@@ -836,13 +866,13 @@ Posledním příkladem je Cap'n'Proto, čteno Captain Proto. Je to volně dostup
\subsection{Protokol QUICr}
Naše hra používala ke komunikaci mezi vrcholy protokol TCP. Zmínili jsme ale, že ten pro hry nemusí být vhodný. Vytvořili jsme vlastní protokol inspirovaný QUIC, který využívá UDP, ale uvolnili jsme podmínky pro spolehlivost, konkrétně jistotu doručení a uspořádání zpráv. Spolehlivost a uspořádání lze definovat pro každou zprávu zvlášť. V další kapitole TCP a QUICr porovnáme a ukážeme, jak se výhody QUICr projeví.
Naše hra používala ke komunikaci mezi vrcholy protokol TCP. Zmínili jsme ale, že ten pro hry nemusí být vhodný. Vytvořili jsme vlastní protokol inspirovaný QUIC, který také využívá UDP, ale uvolnili jsme podmínky pro spolehlivost, konkrétně jistotu doručení a uspořádání zpráv. Spolehlivost a uspořádání lze definovat pro každou zprávu zvlášť. V další kapitole TCP a QUICr porovnáme a ukážeme, jak se výhody QUICr projeví.
Protokol je obousměrný proud paketů se spolehlivými a nespolehlivými rámci využívající UDP. Jeden poslaný UDP datagram může mít více rámců. Rámce jsme rozdělili na dva typy: datové a ovládací. Ovládací slouží pro handshake, ukončení spojení nebo nastavení jiných parametrů spojení a budou vždy doručené spolehlivě. Datové rámce obsahují aplikační data a mohou definovat svou spolehlivost. Ty, které budou obsahovat pozice hráčů, tak budeme moct odesílat nespolehlivě, zatímco změny stavu, jako změna barvy postavy, posíláme spolehlivě. Implementace se skládá ze dvou tříd: \uv{koncový bod} a \uv{spojení}.
Upustili jsme od QUIC paketů a definovali jsme právě jeden typ, který má v hlavičce ID příjemce a ID odesílatele. Každý paket obsahuje rámce. Rámce jsme také rozdělili na dva typy: datové a ovládací. Ovládací slouží pro handshake, ukončení spojení nebo nastavení jiných parametrů spojení a budou vždy doručené spolehlivě. Datové rámce obsahují aplikační data a mohou definovat svou spolehlivost. Ty, které budou obsahovat pozice hráčů, tak budeme moct odesílat nespolehlivě, zatímco změny stavu, jako změna barvy postavy, posíláme spolehlivě. Implementace se skládá ze dvou tříd: \uv{koncový bod} a \uv{spojení}.
Objekt navázaného spojení je stavový stroj a fronta příchozích a fronta odchozích zpráv, podobně jako TCP spojení. Stavy se mění v reakci na příchozí ovládací rámce. Každý objekt spojení má přiřazeno alespoň jedno ID reprezentované osmi bytovým číslem. Tento objekt přímo nepracuje se socketem, ale poskytuje rozhraní, kterým dostává získané zprávy, které odeslala druhá strana. Právě tento objekt překládá n-tici bytů na rámce a postupně je zpracovává. Stavový stroj je důležitý hlavně v procesu handshake, který definujeme níže.
Objekt pro koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr objektů spojení. Při získání datagramu ze socketu ověří, že má správný formát. Podle protokolu by každý datagram měl obsahovat hlavičku s magickým číslem a ID spojení. Koncový bod přečte ID spojení a podle svého registru vyhledá objekt spojení, kterému tělo zprávy předá. Pokud v registru klíč pro získané ID není, koncový bod si objekt spojení vytvoří v počátečním stavu a začíná proces zvaný handshake. Tento proces popíšeme v kapitole TODO
Objekt pro koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr objektů spojení. Při získání datagramu ze socketu ověří, že má správný formát. Podle protokolu by každý datagram měl obsahovat hlavičku s magickým číslem a ID spojení. Koncový bod přečte ID spojení a podle svého registru vyhledá objekt spojení, kterému tělo zprávy předá. Pokud v registru klíč pro získané ID není, koncový bod si objekt spojení vytvoří v počátečním stavu a začíná proces zvaný handshake. Tento proces popíšeme v podkapitole \ref{sec:quicr_handshake}.
Nechtěli jsme, aby si implementace QUICr spravovala vlastní asynchronní kontext. Namísto toho jsme definovali metodu pro aktualizaci, která posbírá zprávy od jednotlivých navázaných spojení a pošle je. Následně přečte všechna data ze soketu a roztřídí je do navázaných spojení.
@@ -860,7 +890,7 @@ Rámec je n-tice bytů, která se skládá z hlavičky a těla. V hlavičce mám
\subsubsection{Handshake}
\subsubsection{Handshake} \label{sec:quicr_handshake}
Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy přechází. Počáteční stav je \inlcpp{Closed}. Jedna strana musí začít a odeslat paket s \inlcpp{Hello} rámcem. Po obdržení se stavový stroj druhé strany přesune do \inlcpp{ReceivedHello} a spolehlivě odešle \inlcpp{Hello}. Když strana dostane rámec \inlcpp{Hello} tak ví, že v hlavičce paketu je cílové i lokální ID. Proto už touto výměnou se strany shodli na ID navázaného spojení, které budou používat. Poté už si vymění rámec \inlcpp{HandshakeDone} a spojení je navázané a připravené k posílání.C elý stavový diagram vidíme na obrázku \ref{fig:quicr_handshake}.
@@ -955,19 +985,19 @@ Při implementaci jsme zjistili, že je dobré začít testy, které definují j
% Metodu, kterou jsem viděl například u síťového protokolu pro hru World Of Warcraft je SRP-6. Jedná se o protokol, který nevyžaduje, aby server znal heslo klienta, ale měl u sebe pouze validátor, a klient mu díky němu dokáže, že heslo zná. Pro tento přístup je třeba udělat handshake.
\subsubsection{Congestion control}
% \subsubsection{Congestion control}
\subsubsection{Bandwidth control}
% \subsubsection{Bandwidth control}
Entity, které jsou od hráče daleko, není třeba aktualizovat tak často jako ty, které jsou k němu blízko. Již jsme nastínili, že můžeme můžeme spočítat důležitost jednotlivých entit pro klienta a omezit tak počet entit, které musí replikátor synchronizovat. Například můžeme vzdálenější entity synchronizovat méně často. Důležité je, aby se i ty dostali někdy na řadu.
% Entity, které jsou od hráče daleko, není třeba aktualizovat tak často jako ty, které jsou k němu blízko. Již jsme nastínili, že můžeme můžeme spočítat důležitost jednotlivých entit pro klienta a omezit tak počet entit, které musí replikátor synchronizovat. Například můžeme vzdálenější entity synchronizovat méně často. Důležité je, aby se i ty dostali někdy na řadu.
\subsection{Sharding}
% \subsection{Sharding}
Proces, při kterém hráče rozdělíme do skupin, které se navzájem nevidí, i když jsou na stejném serveru blízko sebe, se říká sharding. Podobný princip funguje i v databázích.
% Proces, při kterém hráče rozdělíme do skupin, které se navzájem nevidí, i když jsou na stejném serveru blízko sebe, se říká sharding. Podobný princip funguje i v databázích.
\subsection{Horizontální škálování}
Další z metod podobná shardování, je \uv{horizontální škálování}, kdy do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Při nárustu počtu hráčů už nemusí stačit jeden výpočetní server. Poté je nutné využít výkon více počítačů technikou zvanou \uv{horizontální škálování}. To znamená, že do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Představíme, jak spolu zone servery komunikují. Využijeme k tomu už existující komponenty: replikátor a manažera zájmu. Nejprve jsme stav hry, manažera zájmu a fyzický svět do třídy \inlcpp{ZoneManager}. Tuto třídu obalíme \inlcpp{ZoneServer} třídou. Ta bude obsahovat replikátor a \inlcpp{ZoneCoordinatorClient}. Manažer zón si bude udržovat registr sousedních zón a bude se k ním chovat jako klasickým klientům. Rozdíl bude ten, že klient má jako zájem definovaný pouze bod a manažer zájmu klientovi přiřadí do zájmu entity, které jsou od bodu v dostatečné vzdálenosti. Sousedi budou mít jako zájem definovanou celou jejich plochu. Manažer zájmu má nyní na rozhraní dvě metody: \inlcpp{register\_client\_interest(interest\_id, entity)} a \inlcpp{register\_zone\_interest(interest\_id, area)}. Každý zájem je definovaný unikátním ID. O to, jaké entity pak konkrétní zájem zajímají získáme voláním \inlcpp{get_interest(interest_id)}.
@@ -985,30 +1015,53 @@ Systémovou architekturu vidíme na obrázku \ref{fig:zone_cluster_architecture}
\section{Výsledná hra}
V této kapitole představíme hru.
\subsection{Výsledná hra}
V této části výslednou hru popíšeme. Po spuštění klienta dostaneme možnost zadat IP adresu serveru. V tento moment je aplikace ve stavu \inlcpp{lobby}. Hlavní třída, která řídí chod včetně nekonečné smyčky, se nazývá \inlcpp{Runtime}. Ta se chová jako stavový stroj a umožňuje stavům vracet zprávy, podle kterých mezi stavy přechází. Po kliknutí na \uv{connect} se klient pokusí připojit na server.
V případě že uspěje, přejde \inlcpp{Runtime} do stavu \inlcpp{game}. V něm už vidíme stav hry a uživatelské rozhraní, které se skládá z oken. Okna je možné skládat do sebe. TODO: Otevírání různých oken pro přehlednost.
Po připojení je možné se volně pohybovat pomocí WASD. Do hry se může připojit více hráčů. Například je možné použít program \inlcpp{tw_mock_client}.
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/lobby_ui.png}
\label{fig:lobby_ui}
\caption{Uživatelské rozhraní v lobby}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/ui_showcase.png}
\label{fig:ui_showcase}
\caption{Uživatelské rozhraní v klientovi}
\end{figure}
\newpage
\section{Měřění}
V této kapitole popíšeme, jaké testy jsme provedli a jejich výsledky. Nejprve představíme jak samotné metriky můžeme sbírat. Implementovali jsme jednoduchý systém pro sběr metrik, který je schopný je různě agregovat do oken dlouhých například jednu sekundu. Data jsme různě vizualizovali ve webovém rozhraní, tak i přímo v aplikaci klienta.
\subsection{Metriky}
Představíme metody měřění a metriky v systému, které jsme využili pro hledání potenciálních míst pro optimalizaci. Pro sbírání metrik je třeba mít úložistě, kam budeme metriky ukládat a rozhraní, přes které je budeme vizualizovat. Úložiště může být například CSV soubor nebo relační databáze. Existují optimalizované databáze pro vkládání dat s časovou známkou, kterým se říká \uv{timescale}. Jsou ideální právě pro metriky nebo logy, protože narozdíl od klasických databází jsou optimalizované pro rychlé vkládání. Rozhodli jsme se použít relační databázi \uv{PostgreSQL} s rozšířením \uv{TimescaleDB}. Pro vizualizaci jsme použili službu \uv{Grafana}, která umí z TimescaleDB číst. Všechny tyto služby popíšeme v následujících částech.
Představíme metody měřění a metriky v systému, které jsme využili pro hledání potenciálních míst pro optimalizaci. Problém jde rozdělit na tří úlohy: jak metriky sbírat, jak je ukládat a jak je zobrazit. Pro sběr jsme definovali třídy \inlcpp{NetworkMetricsReporter}, který obsahuje metody pro přidávání nových vzorků a různé možnosti čtení daných metrik. Každá lze přečíst jako celá série s určitou historií. Příkladem metod jsou \inlcpp{report\_outbound} a \inlcpp{get\_outbound}.
Implementace si data ukládá pouze do paměti RAM a po ukončení programu jsou nenávratně ztracena. Druhý problém šel ale řešit i perzistentně. Existují databáze, které jsou pro rychlé vkládání vzorků s časovou známkou vhodné. Mezi využití takových databází patří logy nebo právě metriky. Náš výběr představíme.
Nakonec zbývalo metriky zobrazit. Rozhodli jsme se použít webové rozhraní pro rychlou inspekci stavu. Umožní rychle se podívat na množství hráčů nebo velikost datového toku. Metriky, které sbírá klient, zobrazujeme přímo v klientovi. Obě řešení ukážeme.
\subsubsection{PostgreSQL}
Populární relační databáze je PostgreSQL. Rozhodli jsme se právě pro tu, protože je to otevřený a svobodný software zdarma. Lze si ho snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat podporu a optimalizace pro různé použití. V našem případě se chceme ukládat informace o hráčích a stav světa pro perzistenci a metriky. Informace o hráčích a stav světa zvládne bez problémů v základní verzi. Pro metriky použijeme zmíněné rozšíření.
Pro perzistentní úložiště jsme vybrali populární relační databázový server PostgreSQL. Rozhodli jsme se právě pro ten, protože je to otevřený a svobodný software, který je zdarma. Databázi si lze snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat optimalizace pro rychlé vkládání dat o metrikách.
\subsubsection{TimescaleDB}
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, nemusíme spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet tzv. hypertables, které jsou optimalizované pro rychlé vkládání. Vytvořili jsme komponentu \inlcpp{NetworkMetricsReporter}, která má na rozhraní různé metody pro získávání metrik. Např. \inlcpp{report\_outbound} a \inlcpp{report\_inbound}. Tyto údaje posílá do komponenty \inlcpp{TimescaleDbWriter}. To je konkrétní implementace pro TimescaleDB, které má na rozhraní metodu \inlcpp{report(metric\_name, value)}. V rámci optimalizace si \inlcpp{NetworkMetricsReporter} metriky ukládá do bufferu, který až pomocí metody \inlcpp{flush} odešle do databáze. To se neděje nutně po každé metrice, ale v našem případě si reportér ukládá hodnoty do bufferu a po intervalech je vkládá do databáze.
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, nemusíme spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet \uv{hypertables}, které jsou rychlé vkládání optimalizované. Vytvořili jsme komponentu \inlcpp{TimescaleDbMetricsWriter}, která čte z \inlcpp{NetworkMetricsReporter} a postupně zapisuje metriky do databáze. Jedná se o konkrétní implementace pro TimescaleDB. Komponenty jsou tak oddělené a snadno lze přidat rozšíření pro další typy úložišť, jako CSV nebo jiný databázový server.
\subsubsection{Grafana}
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit svůj dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu.
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit svůj dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu. Na obrázku \ref{fig:grafana} vidíme tři grafy. Horní graf ukazuje více metrik najednou, konkrétně množství odchozích a příchozích dat a počet hráčů. V tomto konkrétním případě jsme připojili 300 hráčů. Vidíme, že množství příchozích a odchozích dat se zvýšil. Množství odchozích dat se zvýšil očekávaně daleko více.
\begin{figure}
\begin{center}
@@ -1018,23 +1071,9 @@ Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizual
\label{fig:grafana}
\end{figure}
\subsubsection{Orchestrace}
Popíšeme, jak jsme všechny služby zprovoznili a nastavili. Podrobněji se na orchestraci podíváme později.
\subsubsection{ImGui}
Některé metriky jsme chtěli zobrazit přímo v klientovi pro hru. Jsou to například příchozí a odchozí množství dat klienta. Tyto data neukládáme nikam do databáze a musíme si je spravovat lokálně. Pro zobrazení uživatelského rozhraní jsme zvolili knihovnu ImGui a ImPlot, které se integrují přímo do vykreslovacího enginu. Pro knihovnu jsme přidali jednu novou úlohu do vykreslovacího grafu.
S knihovnou se pracuje procedurálně, nikoliv objektově. Každý snímek je třeba definovat celé rozhraní znova. Pro definici voláme různé funkce, kde každá definuje v rozhraní některý z možných prvků. Například funkce \inlcpp{InputText} zobrazí vstup pro text. Důležitá je funkce \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
\subsubsection{Tracy}
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používáme profiler Tracy. Tento program umožňuje v našem programu definovat tzv. zóny: úsek po sobě jdoucích instrukcí, u kterých měří dobu jejich běhu.
Je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k programu, který měří, vzdáleně. Případně sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používáme profiler Tracy. Program je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k programu, který měří, vzdáleně. Případně sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímky. Následně umožňuje definovat tzv. \uv{zóny}, které následně měří. Zóna může být průběh funkce nebo její konkrétní část. Na obrázku \ref{fig:frame_in_tracy} vidíme, jak taková analýza vypadá. Vidíme právě jeden snímek. V něm máme označené části replikátoru a manažera zájmu. Také vidíme dole zóny.
@@ -1046,34 +1085,33 @@ V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímk
\label{fig:frame_in_tracy}
\end{figure}
\subsubsection{Konkrétní metriky}
% \subsubsection{Konkrétní metriky}
Vyjmenujeme metriky, které budeme měřit. Je dobré zmínit, že místo, ze kterého budeme metriky sbírat, je server.
% Vyjmenujeme metriky, které budeme měřit. Je dobré zmínit, že místo, ze kterého budeme metriky sbírat, je server.
\begin{description}
% \begin{description}
\item[{Inbound/Outbound bandwidth}] \hfill \\
Nejpřirozenější metrika je příchozí a odchozí množství dat v bytech. Už zde pro mě bylo nutné si uvědomit důležitost oddělit vrstvu, která kóduje a dekóduje zprávy, od zbytku. Přesně na tomto místě totiž budu metriky dělat. Metriku budu sčítat.
% \item[{Inbound/Outbound bandwidth}] \hfill \\
% Nejpřirozenější metrika je příchozí a odchozí množství dat v bytech.
\item[{Odezva}] \hfill \\
Budu měřit odezvu mezi odesláním vstupu od klienta pro snímek x a odpovědí od serveru pro snímek x. Tuto metriku budu průměrovat.
% \item[{Odezva}] \hfill \\
% Budeme měřit odezvu mezi odesláním vstupu od klienta pro snímek $i$ a odpovědí od serveru pro snímek $i$.
\item[{Počet snímků za vteřinu}] \hfill \\
Ze začátku se mi stávalo, že uzké hrdlo nebyla síť, ale síťová vrstva v aplikaci, která třeba dlouho skládala zprávy. Proto si udržuju i přehled o počtu snímků, které server stíhá. Podle toho se lze orientovat při výběru hardware pro server.
\end{description}
% \item[{Počet snímků za vteřinu}] \hfill \\
% Ze začátku se stávalo, že uzké hrdlo nebyla síť, ale síťová vrstva v aplikaci, která dlouho serializovala zprávy. Proto si udržujeme přehled o počtu snímků, které server vypočítává. Podle toho se lze orientovat při výběru hardware pro server.
% \end{description}
\subsubsection{Sbírání v reálném čase}
Přímo v hráčově klientské aplikaci jsme chtěli mít možnost vidět metriky v reálném čase. Do síťové vrstvy jsme přidali komponentu pro reportování událostí a jejich metrik zvanou \inlcpp{NetworkMetricReporter}, která obsahuje metody jako \inlcpp{report\_inbound} a \inlcpp{report\_outbound}. První metoda hlásí příchozí byty a druhá odchozí.
\subsubsection{Klientská aplikace}
Přímo v hráčově klientské aplikaci jsme chtěli mít možnost vidět metriky v reálném čase. K implementaci grafického uživatelského rozhraní jsme použili knihovnu ImGui představenou dříve. Komponenty pro zobrazení různých metrik opět čtou z \inlcpp{NetworkMetricsReporter}.
\subsection{QUICr}
Protokol měl za cíl snížit odezvu na nespolehlivé síti a neblokovat zprávy. Vytvořili jsme test, který simuluje program hry. V testu jsou dvě vlákna, jedno pro klienta a druhé pro server. Oba mají svou vlastní smyčku, ve kterém iterují. Klient odesílá hodnotu derivace typu double. Server si udržuje stav hodnoty, nazvěme ji \uv{pozice}. Při obdržení derivace ji přičte k aktuálnímu stavu. Každý snímek server odesílá na klienta stav pozice, kterou si klient aplikuje.
Pro nasimulování nespolehlivosti sítě jsme využili Linuxový nástroj \uv{tc}. Ten obsahuje \uv{network emulator}, který obsahuje různá nastavení spolehlivosti sítě. Například kolik procent paketů má ztratit, jaká má být odezva nebo jak moc náhodné bude pořadí paketů. Budeme simulovat odezvu 200 milisekund s rozptylem 20ms, ztrátu 3\% paketů a 1\% paketů bude duplikovaných. Celý příkaz pro nastavení můžeme vidět v příkladu . Vidíme, že používáme pouze rozhraní \inlcpp{lo}, tedy loopback, které se týká posílání mezi programy na lokální adrese.
Pro nasimulování nespolehlivosti sítě jsme využili Linuxový nástroj \uv{tc}. Ten obsahuje \uv{network emulator} s různými nastaveními spolehlivosti sítě. Například kolik procent paketů má ztratit, jaká má být odezva nebo jak moc náhodné bude pořadí paketů. Budeme simulovat odezvu 200 milisekund s rozptylem 20ms, ztrátu 3\% paketů a 1\% paketů bude duplikovaných. Celý příkaz pro nastavení můžeme vidět v příkladu \ref{kod:tc}. Vidíme, že používáme pouze rozhraní \inlcpp{lo}, tedy loopback, které se týká posílání mezi programy na lokální adrese.
\begin{kicode}{cpp}{}{Příklad volání TC}
\begin{kicode}{cpp}{kod:tc}{Příklad volání TC}
# tc qdisc add dev lo root netem \
delay 200ms 20ms 25% \
loss 3% \
@@ -1082,7 +1120,6 @@ Pro nasimulování nespolehlivosti sítě jsme využili Linuxový nástroj \uv{t
\end{kicode}
V prvním testu jsme pouze měřili odezvu mezi odesláním vstupu od klienta pro snímek $n$ a získáním jeho integrovaného stavu ze serveru. Na obrázku \ref{fig:latencycomparison} vidíme, že TCP obsahuje skoky a QUICr je stabilnější.
\begin{figure}
\begin{center}
@@ -1092,12 +1129,14 @@ V prvním testu jsme pouze měřili odezvu mezi odesláním vstupu od klienta pr
\label{fig:latencycomparison}
\end{figure}
V prvním testu jsme pouze měřili odezvu mezi odesláním vstupu od klienta pro snímek $n$ a získáním jeho integrovaného stavu ze serveru. Na obrázku \ref{fig:latencycomparison} vidíme, že TCP obsahuje skoky a QUICr je stabilnější.
\begin{figure}
\begin{center}
\includegraphics[width=0.8\textwidth]{graphics/integrationcomparison.pdf}
\end{center}
\label{fig:integrationcomparison}
\caption{Porovnání integrace TCP a QUICr}
\label{fig:integrationcomparison}
\end{figure}
Následně jsme zkusili, jak se nespolehlivost sítě a skoky odezvy z prvního měření projeví v integraci proměnné. Pro derivaci jsme použili sinusoidu, abychom ji mohli zreplikovat snadno v TCP i QUICr. Na obrázku \ref{fig:integrationcomparison} vidíme, že TCP při ztrátě paketů způsobuje skoky, které nemusí být pro hráče příjemné. Naopak náš protokol má integraci plynulejší.
@@ -1107,14 +1146,13 @@ Nakonec jsme integrovali protokol přímo do replikátoru. Vytvořili jsme simul
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{graphics/playerbenchmark.png}
\label{fig:playerbenchmark}
\caption{301 připojených hráčů}
\label{fig:playerbenchmark}
\end{figure}
\subsection{Optimalizace replikátoru}
Test s 301 hráči odhalil nedostatečný výkon serveru. Pomocí Tracy jsme začali program analyzovat. Na obrázku \ref{fig:tracyreplicator} vidíme, že pouze aktualizace replikátoru trvá každý snímek kolem 100ms. Pro představu, pokud bychom chtěli, aby server integroval 20 krát za sekundu, museli bychom všechno, nejen aktualizaci replikátoru, stihnout do 50 milisekund. Proto je aktuální stav nepřijatelně dlouhá doba. Úzké hrdlo najednou nebyla síť, ale příprava smysluplných dat, kterými síť zatížíme. Soustředili jsme další optimalizace právě na replikátor.
\subsection{Optimalizace replikátoru}
\begin{figure}
\centering
@@ -1123,6 +1161,10 @@ Test s 301 hráči odhalil nedostatečný výkon serveru. Pomocí Tracy jsme za
\caption{Analýza replikátoru}
\end{figure}
Test s 301 hráči odhalil nedostatečný výkon serveru. Pomocí Tracy jsme začali program analyzovat. Na obrázku \ref{fig:tracyreplicator} vidíme, že pouze aktualizace replikátoru trvá každý snímek kolem 100ms. Pro představu, pokud bychom chtěli, aby server integroval 20 krát za sekundu, museli bychom všechno, nejen aktualizaci replikátoru, stihnout do 50 milisekund. Proto je aktuální stav nepřijatelně dlouhá doba. Úzké hrdlo najednou nebyla síť, ale příprava smysluplných dat, kterými síť zatížíme. Soustředili jsme další optimalizace právě na replikátor.
Z analýzy vyšlo najevo, že problém je při skládání zpráv. Tedy kódování pozic entit, o které se klient zajímá, do objektu. Je to právě tento objekt, který se serializuje přes ProtoBuf a odesílá přes soket klientům.
Replikátor pro každého klienta zjistil jeho zájem a pro každou entitu v něm vyhledával jeho komponenty. Vyhledávání je v případě Entt implementováno hashovací tabulkou a časová složitost je v $O(1)$. Začali jsme měřit i jiná řešení. Primárně nás zajímali metody, které jsou vhodné pro ECS architekturu. První řešení, které jsme zkusili, bylo vytvořit buffer instancí zpráv pro každého klienta najednou. Přes komponentu, kterou jsme chtěli replikovat, např. Transform, jsme vytvořili Entt pohled a iterovali. Pro každý prvek jsem komponentu zapsali do zprávy pro každého klienta, kterého zajímala. Výslednou analýzu vidíme na obrázku \ref{fig:ecs_optimization_tracy_01}. Tato optimalizace, která jen změnila pořadí, v jakém nahlížíme na data, snížila dobu, kterou trvá aktualizace replikátoru, na polovinu.
@@ -1152,9 +1194,9 @@ Replikátor jsme začali analyzovat do větších detailů. Na obrázku \ref{fig
Čas (s) & 9.455691762 & 10.345692894 & 0.754350866 \\
\hline
\end{tabular}
\label{table:serialization_comparison}
\caption{Porovnání serializátorů}
\end{center}
\label{table:serialization_comparison}
\end{figure}
Zjistili jsme, že problémem byl ProtoBuf a FlatBuffers by nám nepomohl. Nepřekvapilo nás, že memcpy byl nejrychlejší. Rozhodli jsme se, že pro serializaci a deserializaci snapshotů světa budeme používat vlastní serializaci.
@@ -1171,8 +1213,6 @@ Všimli jsme si, že replikátor trval každou iteraci kolem 60 milisekund. Nejp
Jedna s datových struktur, která má nízkou složitost pro dotaz na seznam entit ve vzdálenosti maximálně, je klasická mřížka. Charakteristika hráčů ve hrách je, že se hodně pohybují. Mřížka nepotřebuje žádný přepočet, ale pouze vložit do předem alokovaného bufferu, nebo z něj naopak odebrat.
Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní přístup. Simulovali jsme pohyb 100 000 různých entit po dobu 100 snímků. Všechny možnosti představíme. Naivní přístup využívá pouze Pythagorovu větu, aby získal vzdálenost dvou bodů. Jediná optimalizace je vynechat odmocninu a umocnit místo toho vzdálenost. Druhá a třetí implementace využívá mřížku a entity rozděluje do svých polí. První je fixní mřížka, která je vhodná pro světy, které nemění svou velikost, jako např. World of Warcraft. Naopak hashovací mřížka přiřazuje entity do polí pomocí hashe jejich pozice. Jsou tak ideální pro dynamické a potenciálně nekonečné světy, jako např. Minecraft. Poslední je quad tree. Jedná se o obdobu binárního stromu rozšířenou o rozměr. V tabulce \ref{table:range_query_comparison} vidíme výsledky testu. Celkový čas je milisekundách. Ve třetím a čvrtém sloupci je změřená část vkládání a dotazování. Díky tomu vidíme, že Quad tree má rychlejší dotazování, ale delší vkládání. Nejrychlejší je fixní mřížka. Má ale vysokou paměťovou náročnost a při použití je tak nutné zvážit, jestli není hashovací mřížka vhodnější. Quad tree implementace se ukázala jako nevhodná. S přibývající hloubkou je navíc pomalejší. Ideální se ukázali varianty s fixní a hashovací mřížkou.
\begin{figure}
\begin{center}
\begin{tabular}{ | m{5em} | m{3cm} | m{3cm} | m{3cm} | }
@@ -1188,27 +1228,45 @@ Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní př
Quad tree & 1830 & 1560 (85.45\%) & 30.29 (1.66\%) \\
\hline
\end{tabular}
\label{table:range_query_comparison}
\caption{Porovnání algoritmů}
\label{table:range_query_comparison}
\end{center}
\end{figure}
Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní přístup. Simulovali jsme pohyb 100 000 různých entit po dobu 100 snímků. Všechny možnosti představíme. Naivní přístup využívá pouze Pythagorovu větu, aby získal vzdálenost dvou bodů. Jediná optimalizace je vynechat odmocninu a umocnit místo toho vzdálenost. Druhá a třetí implementace využívá mřížku a entity rozděluje do svých polí. První je fixní mřížka, která je vhodná pro světy, které nemění svou velikost, jako např. World of Warcraft. Naopak hashovací mřížka přiřazuje entity do polí pomocí hashe jejich pozice. Jsou tak ideální pro dynamické a potenciálně nekonečné světy, jako např. Minecraft. Poslední je quad tree. Jedná se o obdobu stromu, kde vrcholy mají právě 4 potomky nebo žádného potomka. V tabulce \ref{table:range_query_comparison} vidíme výsledky testu. Celkový čas je milisekundách. Ve třetím a čvrtém sloupci je změřená část vkládání a dotazování. Díky tomu vidíme, že Quad tree má rychlejší dotazování, ale delší vkládání. Nejrychlejší je fixní mřížka. Má ale vysokou paměťovou náročnost a při použití je tak nutné zvážit, jestli není hashovací mřížka vhodnější. Quad tree implementace se ukázala jako nevhodná. S přibývající hloubkou je navíc pomalejší. Ideální se ukázali varianty s fixní a hashovací mřížkou.
\subsection{Peer-to-peer}
\subsection{Závěry}
Závěr práce by se měl poskytnout jak v původním jazyce práce, tak v jazyce anglickém. Pro sazbu závěru jsou k dispozici příslušná makra. Berte na vědomí, že v anglickém závěru se aktivuje plně anglická sazba se všemi konvencemi. Tedy je třeba používat anglické uvozovky a další správné typografické prvky.
Chtěli jsme změřit i hru s modelem peer-to-peer. Zároveň jsme chtěli dokázat, že náš protokol QUICr pomáhá i v tomto modelu. Vytvořili jsme proto program, který simuluje jednoho účastníka peer-to-peer systému, tzv. \uv{peer}. Na začátku program čeká, až se připojí a autentizují ostatní peer. Proto jsme definovali číslo hráčů, v základu rovno 2.
\begin{kicode}{TeX}{}{Sazba závěrů}
% Tiskne český závěr práce.
\begin{kiconclusions}
Závěr práce v \uv{českém} jazyce.
\end{kiconclusions}
Hry peer-to-peer fungují podobně jako v modelu klient-server. Každý účastník si udržuje svůj svět a chová se jako server. Tedy pro něj je zdroj pravdy právě jeho stav. Následně je hra rozdělena na iterace. V každé iteraci všichni odešlou všem svou akci, kterou učinili. Jakmile peer v iteraci $i$ získá akce od všech ostatních pro iteraci $i$, tak si je lokálně aplikuje na svůj stav. Poté se posune do iterace $i+1$ a proces se opakuje. Tento způsob má nevýhodu v tom, že hra je stejně rychlá jako nejpomalejší peer. Pokud někomu bude dlouho trvat, než odešle svou akci, všichni ostatní jsou nuceni na něj čekat. Je totiž třeba žádnou akci nevynechat, jinak dojde k desynchronizaci.
% Tiskne anglický závěr práce.
\begin{kiconclusions}[english]
Thesis conclusions written in \uv{English}.
\end{kiconclusions}
\end{kicode}
Optimalizaci, kterou jsme implementovali, byl rollback. Ten umožňil, aby nebylo nutné čekat na všechny akce. Pokud peer $A$ v iteraci $i$ chybí akce pro peer $B$, tak peer $A$ zkusí udělat pro peer $B$ predikci. Pokud eventuélně akce od $B$ do $A$ pro iteraci $i$ dorazí a liší se od predikce, tak se peer $A$ vrátí v historii, akci změní a aplikuje znova.
Zde je nutné, aby peer posílal ne pouze poslední akci, ale celou historii svých akcí. Představme si, že akce pro iteraci $i$ chybí, takže peer iteraci predikuje a přejde do $i+1$. Akce pro iteraci $i$ se ztratila a už nedorazí. Jakmile ale dorazí akce pro $i+1$, tak obsahuje i akci pro $i$. Peer si tak může historii vrátit, nasimulovat správně a tím se synchronizovat. Díky tomu je synchronizace daleko plynulejší.
Účastníci nemusejí vždy posílat celou svou historii, ale pouze tu část, kterou druhá strana ještě nemá. To lze zjistit tak, že příjemce posílá zprávu o tom, které iterace už obdržel. Tento přístup sice stále iteruje rychlostí nejpomalejšího účastníka, ale alespoň řeší lehké záseky při ztrátě paketu. Používá se často v bojových hrách, kde je odezva hráčových vstupů kritická.
V testu jsou tedy dva hráči, každý má svou postavu s pozicí ve 3D prostoru. Výše zmíněným způsobem provedou $X$ iterací. Postupně v čase jsme pozice obou postav exportovali do CSV pro oba hráče. Udělali jsme dvě měření, jedno pro TCP a druhé pro QUICr. Na obrázku \ref{fig:peer_to_peer} vidíme naměřené hodnoty pozice postavy hráče 1 jak ji viděl hráč 2. V případě TCP hráč silně skákal, právě kvůli ahead-of-line blokování. To snižuje hratelnost. Protokol QUICr je plynulejší a tedy i hratelnější.
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{graphics/peer_to_peer.pdf}
\caption{Porovnání TCP a QUICr v peer-to-peer}
\label{fig:peer_to_peer}
\end{figure}
% \begin{kicode}{TeX}{}{Sazba závěrů}
% % Tiskne český závěr práce.
% \begin{kiconclusions}
% \end{kiconclusions}
% % Tiskne anglický závěr práce.
% \begin{kiconclusions}[english]
% Thesis conclusions written in \uv{English}.
% \end{kiconclusions}
% \end{kicode}
%% Závěry práce. V jazyce práce a anglicky. Text pro jiný než
@@ -1216,7 +1274,13 @@ Thesis conclusions written in \uv{English}.
%% \documentclass, výchozí český) se zadává použitím makra s uvedením
%% jazyka jako nepovinného parametru.
\begin{kiconclusions}
Závěr práce v \uv{českém} jazyce.
V práci jsme představili problematiku distribuovaných systémů a soustředili jsme se na konkrétní využití pro hry více hráčů. Popsali jsme různé modely a architektury nejen systému, ale i programů v něm. Jednotlivé atributy, které systémy nebo komunikace mohou mít, jsme identifikovali a přenesli na náš konkrétní případ.
Vytvořili jsme si vlastní herní engine, který umožňuje vytvářet hry pro více hráčů. Programy jsme skládali jako modulární monolity a popisovali jejich architekturu a implementaci. Ukázali jsme, že náš přístup umožnil snadno herní engine rozšiřovat. Pro distribuovaný systém jsme vytvořili hned dva protokoly: jeden v transportní a druhý v aplikační vrstvě. První protokol zrychluje tempo, jakým se zprávy dostanou ke zpracování, oproti TCP. Jinými slovy eliminuje ahead-of-line blokování. Implementovali jsme různé vlastnosti jako handshake a spolehlivost. Druhý protokol umožňuje zprávy rozdělovat podle typu. Na koncových bodech je tak možné pro typ definovat funkci, která každou příchozí zprávu tohoto typu zpracuje. Pro snadnější práci se zprávami jsme přidali serializaci objektů. To znamená, že ve vrstvě, kde implementujeme herní logiku, nepracujeme se zprávami jako n-ticemi bytů, ale objekty.
Na konci jsme definovali, jaké metriky chceme měřit a jaké chceme optimalizovat. Představili jsme nástroje a možnosti měření, které jsme využili. Naše metriky se netýkali jen komunikace v síti, ale i výkonu jednolivých programů. Například jsme naměřili, že v případě stovek hráčů začala být problém serializace a obecně sestavení smysluplných zpráv, nikoliv samotné odesílání. Implementovali a popsali jsme naše řešení. Zároveň jsme dokázali, že implementované optimalizace jsou vhodné nejen pro model klient-server ale i peer-to-peer.
Do budoucna by bylo dobré dokončit další vlastnosti QUICr protokolu, jako například sekvenční číslo zprávy. Bylo by nutné se zamyslet, do jaké hloubky by pořadí zpráv měl řešit QUICr. Aplikace sama nejlépe ví, jestli musí čekat na předchozí zprávu nebo ne, jako v našem případě snapshoty ze serveru. Možnost je definovat předchůdce pro kompletní odstranění ahead-of-line blokování. Protokol také neimplementuje dynamické změny datového toku. Ten je nutné snížit, když je síť zatížená.
\end{kiconclusions}
\begin{kiconclusions}[english]
@@ -1301,7 +1365,7 @@ nebo souboru \texttt{README.*}.
%% -------------------------------------------------------------------
%% Sazba volitelného seznamu zkratek, za přílohami.
\printglossary
% \printglossary
%% Sazba povinné bibliografie, za přílohami (případně i za seznamem
%% zkratek). Při použití BibLaTeXu použijte makro
@@ -1323,7 +1387,7 @@ nebo souboru \texttt{README.*}.
% \end{thebibliography}
%% Sazba volitelného rejstříku, za bibliografií.
\printindex
% \printindex
\end{document}
+60 -73
View File
@@ -1,79 +1,66 @@
\babel@toc {czech}{}\relax
\contentsline {section}{\numberline {1}Úvod}{8}{section.1}%
\contentsline {section}{\numberline {2}Síťové systémy}{9}{section.2}%
\contentsline {section}{\numberline {3}Distribuované systémy}{9}{section.3}%
\contentsline {subsection}{\numberline {3.1}Architektury}{9}{subsection.3.1}%
\contentsline {subsubsection}{\numberline {3.1.1}Softwarová architektura}{10}{subsubsection.3.1.1}%
\contentsline {subsubsection}{\numberline {3.1.2}Systémové architektury}{10}{subsubsection.3.1.2}%
\contentsline {subsection}{\numberline {3.2}Komunikace}{11}{subsection.3.2}%
\contentsline {subsubsection}{\numberline {3.2.1}Modely pro komunikaci}{12}{subsubsection.3.2.1}%
\contentsline {subsection}{\numberline {3.3}Počítačová Síť}{12}{subsection.3.3}%
\contentsline {subsection}{\numberline {3.4}Komunikace v síti}{13}{subsection.3.4}%
\contentsline {subsubsection}{\numberline {3.4.1}Rodina protokolů TCP/IP}{13}{subsubsection.3.4.1}%
\contentsline {subsection}{\numberline {3.5}Protokoly v aplikační vrstvě}{16}{subsection.3.5}%
\contentsline {subsubsection}{\numberline {3.5.1}HTTP}{16}{subsubsection.3.5.1}%
\contentsline {subsubsection}{\numberline {3.5.2}HTTP/3}{16}{subsubsection.3.5.2}%
\contentsline {subsection}{\numberline {3.6}Protokoly v transportní vrstvě}{17}{subsection.3.6}%
\contentsline {subsubsection}{\numberline {3.6.1}TCP}{17}{subsubsection.3.6.1}%
\contentsline {subsubsection}{\numberline {3.6.2}UDP}{18}{subsubsection.3.6.2}%
\contentsline {subsubsection}{\numberline {3.6.3}QUIC}{18}{subsubsection.3.6.3}%
\contentsline {subsection}{\numberline {3.7}Sokety}{21}{subsection.3.7}%
\contentsline {subsection}{\numberline {3.8}Asynchroní vstupně výstupní operace}{21}{subsection.3.8}%
\contentsline {subsubsection}{\numberline {3.8.1}ZeroMQ}{22}{subsubsection.3.8.1}%
\contentsline {subsubsection}{\numberline {3.8.2}Work stealing}{22}{subsubsection.3.8.2}%
\contentsline {subsubsection}{\numberline {3.8.3}Async/Await}{22}{subsubsection.3.8.3}%
\contentsline {subsubsection}{\numberline {3.8.4}Boost Asio}{23}{subsubsection.3.8.4}%
\contentsline {section}{\numberline {4}Hra}{24}{section.4}%
\contentsline {subsection}{\numberline {4.1}Engine}{24}{subsection.4.1}%
\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{25}{subsubsection.4.1.1}%
\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{25}{subsubsection.4.1.2}%
\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{25}{subsubsection.4.1.3}%
\contentsline {section}{\numberline {5}Hra více hráčů}{28}{section.5}%
\contentsline {subsection}{\numberline {5.1}Server}{28}{subsection.5.1}%
\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{29}{subsubsection.5.1.1}%
\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{30}{subsubsection.5.1.2}%
\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{30}{subsubsection.5.1.3}%
\contentsline {subsection}{\numberline {5.2}Klient}{30}{subsection.5.2}%
\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{30}{subsubsection.5.2.1}%
\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{30}{subsubsection.5.2.2}%
\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{31}{subsubsection.5.2.3}%
\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{31}{subsection.5.3}%
\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{31}{subsubsection.5.3.1}%
\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{32}{subsubsection.5.3.2}%
\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{32}{subsubsection.5.3.3}%
\contentsline {subsection}{\numberline {5.4}Serializace}{32}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{33}{subsection.5.5}%
\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{34}{subsubsection.5.5.1}%
\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{34}{subsubsection.5.5.2}%
\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{35}{subsubsection.5.5.3}%
\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{36}{subsubsection.5.5.4}%
\contentsline {subsubsection}{\numberline {5.5.5}Testování}{37}{subsubsection.5.5.5}%
\contentsline {subsubsection}{\numberline {5.5.6}Congestion control}{37}{subsubsection.5.5.6}%
\contentsline {subsubsection}{\numberline {5.5.7}Bandwidth control}{37}{subsubsection.5.5.7}%
\contentsline {subsection}{\numberline {5.6}Sharding}{37}{subsection.5.6}%
\contentsline {subsection}{\numberline {5.7}Horizontální škálování}{37}{subsection.5.7}%
\contentsline {section}{\numberline {6}Výsledná hra}{38}{section.6}%
\contentsline {section}{\numberline {7}Měřění}{39}{section.7}%
\contentsline {subsection}{\numberline {7.1}Metriky}{39}{subsection.7.1}%
\contentsline {subsubsection}{\numberline {7.1.1}PostgreSQL}{39}{subsubsection.7.1.1}%
\contentsline {subsubsection}{\numberline {7.1.2}TimescaleDB}{39}{subsubsection.7.1.2}%
\contentsline {subsubsection}{\numberline {7.1.3}Grafana}{39}{subsubsection.7.1.3}%
\contentsline {subsubsection}{\numberline {7.1.4}Orchestrace}{40}{subsubsection.7.1.4}%
\contentsline {subsubsection}{\numberline {7.1.5}ImGui}{40}{subsubsection.7.1.5}%
\contentsline {subsubsection}{\numberline {7.1.6}Tracy}{40}{subsubsection.7.1.6}%
\contentsline {subsubsection}{\numberline {7.1.7}Konkrétní metriky}{41}{subsubsection.7.1.7}%
\contentsline {subsubsection}{\numberline {7.1.8}Sbírání v reálném čase}{41}{subsubsection.7.1.8}%
\contentsline {subsection}{\numberline {7.2}QUICr}{42}{subsection.7.2}%
\contentsline {subsection}{\numberline {7.3}Optimalizace replikátoru}{44}{subsection.7.3}%
\contentsline {subsection}{\numberline {7.4}Optimalizace manažera zájmů}{46}{subsection.7.4}%
\contentsline {subsection}{\numberline {7.5}Závěry}{47}{subsection.7.5}%
\contentsline {section}{Z\'av\v er}{48}{section*.3}%
\contentsline {section}{\numberline {2}Počítačová síť}{9}{section.2}%
\contentsline {subsection}{\numberline {2.1}Komunikace}{9}{subsection.2.1}%
\contentsline {subsubsection}{\numberline {2.1.1}Modely pro komunikaci}{10}{subsubsection.2.1.1}%
\contentsline {section}{\numberline {3}Distribuované systémy}{11}{section.3}%
\contentsline {subsection}{\numberline {3.1}Architektury}{11}{subsection.3.1}%
\contentsline {subsubsection}{\numberline {3.1.1}Softwarová architektura}{11}{subsubsection.3.1.1}%
\contentsline {subsubsection}{\numberline {3.1.2}Systémové architektury}{12}{subsubsection.3.1.2}%
\contentsline {subsection}{\numberline {3.2}Protokoly}{13}{subsection.3.2}%
\contentsline {subsubsection}{\numberline {3.2.1}Rodina protokolů TCP/IP}{14}{subsubsection.3.2.1}%
\contentsline {subsection}{\numberline {3.3}Protokoly v aplikační vrstvě}{15}{subsection.3.3}%
\contentsline {subsubsection}{\numberline {3.3.1}HTTP}{15}{subsubsection.3.3.1}%
\contentsline {subsubsection}{\numberline {3.3.2}HTTP/3}{16}{subsubsection.3.3.2}%
\contentsline {subsection}{\numberline {3.4}Protokoly v transportní vrstvě}{17}{subsection.3.4}%
\contentsline {subsubsection}{\numberline {3.4.1}TCP}{17}{subsubsection.3.4.1}%
\contentsline {subsubsection}{\numberline {3.4.2}UDP}{18}{subsubsection.3.4.2}%
\contentsline {subsubsection}{\numberline {3.4.3}QUIC}{18}{subsubsection.3.4.3}%
\contentsline {section}{\numberline {4}Hra}{21}{section.4}%
\contentsline {subsection}{\numberline {4.1}Engine}{22}{subsection.4.1}%
\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{22}{subsubsection.4.1.1}%
\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{23}{subsubsection.4.1.2}%
\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{23}{subsubsection.4.1.3}%
\contentsline {subsubsection}{\numberline {4.1.4}ImGui}{25}{subsubsection.4.1.4}%
\contentsline {section}{\numberline {5}Hra více hráčů}{26}{section.5}%
\contentsline {subsection}{\numberline {5.1}Server}{26}{subsection.5.1}%
\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{27}{subsubsection.5.1.1}%
\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{28}{subsubsection.5.1.2}%
\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{28}{subsubsection.5.1.3}%
\contentsline {subsection}{\numberline {5.2}Klient}{28}{subsection.5.2}%
\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{28}{subsubsection.5.2.1}%
\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{28}{subsubsection.5.2.2}%
\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{29}{subsubsection.5.2.3}%
\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{29}{subsection.5.3}%
\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{29}{subsubsection.5.3.1}%
\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{30}{subsubsection.5.3.2}%
\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{30}{subsubsection.5.3.3}%
\contentsline {subsection}{\numberline {5.4}Serializace}{30}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{31}{subsection.5.5}%
\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{32}{subsubsection.5.5.1}%
\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{32}{subsubsection.5.5.2}%
\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{34}{subsubsection.5.5.3}%
\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{34}{subsubsection.5.5.4}%
\contentsline {subsubsection}{\numberline {5.5.5}Testování}{35}{subsubsection.5.5.5}%
\contentsline {subsection}{\numberline {5.6}Horizontální škálování}{35}{subsection.5.6}%
\contentsline {subsection}{\numberline {5.7}Výsledná hra}{36}{subsection.5.7}%
\contentsline {section}{\numberline {6}Měřění}{38}{section.6}%
\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}%
\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}%
\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}%
\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{39}{subsubsection.6.1.3}%
\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{39}{subsubsection.6.1.4}%
\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{39}{subsubsection.6.1.5}%
\contentsline {subsection}{\numberline {6.2}QUICr}{40}{subsection.6.2}%
\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{42}{subsection.6.3}%
\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{44}{subsection.6.4}%
\contentsline {subsection}{\numberline {6.5}Peer-to-peer}{45}{subsection.6.5}%
\contentsline {section}{Z\'av\v er}{47}{section*.3}%
\babel@toc {czech}{}\relax
\babel@toc {czech}{}\relax
\contentsline {section}{Conclusions}{49}{section*.5}%
\contentsline {section}{Conclusions}{48}{section*.5}%
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\contentsline {section}{\numberline {A}První příloha}{50}{appendix.A}%
\contentsline {section}{\numberline {B}Druhá příloha}{50}{appendix.B}%
\contentsline {section}{\numberline {C}Obsah elektronických dat}{50}{appendix.C}%
\contentsline {section}{Seznam zkratek}{52}{section*.7}%
\contentsline {section}{\numberline {A}První příloha}{49}{appendix.A}%
\contentsline {section}{\numberline {B}Druhá příloha}{49}{appendix.B}%
\contentsline {section}{\numberline {C}Obsah elektronických dat}{49}{appendix.C}%