<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Блог Давыдова Blog</title>
        <link>https://davy.page/</link>
        <description>Блог Давыдова Blog</description>
        <lastBuildDate>Sun, 14 Sep 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>ru</language>
        <item>
            <title><![CDATA[Балансировка DNS-трафика и активные health-check'и апстримов — как и почему мы начали использовать DNSdist]]></title>
            <link>https://davy.page/dnsdist-in-sberdevices</link>
            <guid>https://davy.page/dnsdist-in-sberdevices</guid>
            <pubDate>Sun, 14 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Коллеги, всем привет!]]></description>
            <content:encoded><![CDATA[<p>Коллеги, всем привет!</p>
<p>Долгое время в нашей внутренней сети для обработки DNS-трафика мы использовали только BIND, и нам с ним было хорошо. Но в какой-то момент его возможностей перестало хватать. В статье расскажу, что именно с BIND не так и почему теперь весь DNS-трафик у нас проходит через DNSdist. И что это вообще такое...</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/dnsdist-8ce572513bbe81985e1091d819216b95.jpeg" width="1168" height="784" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/companies/sberdevices/articles/966638/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/companies/sberdevices/articles/966638/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="жизнь-с-bind">Жизнь с BIND<a href="https://davy.page/dnsdist-in-sberdevices#%D0%B6%D0%B8%D0%B7%D0%BD%D1%8C-%D1%81-bind" class="hash-link" aria-label="Прямая ссылка на Жизнь с BIND" title="Прямая ссылка на Жизнь с BIND">​</a></h2>
<p><img decoding="async" loading="lazy" alt="life-with-bind" src="https://davy.page/assets/images/life-with-bind-aec1548cb4dcdf49b75c0cd3085267fd.png" width="1560" height="849" class="img_ev3q"></p>
<p>Прежде чем говорить о DNSdist, нужно знать, почему мы вообще начали в его сторону думать. А для этого необходимо понимать, как была устроена наша DNS-инфраструктура до его прихода. Итак, начнём.</p>
<p>Мы живём в трех разных облаках. В каждом из них у нас поднято по два DNS-сервера BIND, которые реплицируются от «мастера», который также поднят в одном из этих облаков. Все сервера хранят одни и те же зоны, одну и ту же информацию.</p>
<p>Клиентами этих серверов у нас выступают все наши виртуальные машины, АРМ и K8S кластера. Для отказоустойчивости на всех ВМ мы указываем DNS-сервера из всех облаков. Например: ВМ из облака А будет в /etc/resolv.conf иметь DNS-сервера из облаков A, B и C. Никакого DNS-клиента (типа systemd-resolved) на этих ВМ не установлено (к сожалению), поэтому DNS-запросы летят вразнобой. Это станет нашей проблемой номер ноль.</p>
<p>В конфигурации самих BIND'ов у нас, помимо наших зон, в которые мы записываем адреса виртуальных машин, сервисов, балансиров и так далее, есть зоны, которые, по сути, обслуживаются не нами, а, к примеру, провайдерами облачных сервисов, которые мы используем.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">zone zona IN {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">     type forward;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">     forward only;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">     forwarders { 172.17.20.22; 172.17.20.23;};</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">};</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Тут у нас появляется одна, но серьёзная проблема – умершие апстримы не выпадают из балансировки. Это значит, что если один из серверов, который мы указали в списке forwarders, упадет, BIND продолжит пытаться слать ему запросы. Это нам не нравится, клиенты начинают получать лишние timeout'ы, а лучше бы не получали.</p>
<p>Помимо этого, у некоторых апстримов есть специфичная особенность – они по-хорошему должны обслуживать только DNS-запросы тех клиентов, которые находятся с ними в одном и том же облаке. К таким апстримам у нас, например, относятся Consul (решение от компании HashiCorp) сервера, которые возвращают клиенту адреса живых инстансов запрашиваемого сервиса. Всё, что нам нужно, это, по сути, редиректить DNS-запрос на нужный DNS-сервер (который указан в forwarders) в зависимости от ip-адреса клиента и при этом иметь возможность указать fallback апстримы. К сожалению, распределение запросов по форвардам, основываясь на source ip в BIND, невозможно, и это наша последняя проблема.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="выход-на-сцену-dnsdist">Выход на сцену DNSdist<a href="https://davy.page/dnsdist-in-sberdevices#%D0%B2%D1%8B%D1%85%D0%BE%D0%B4-%D0%BD%D0%B0-%D1%81%D1%86%D0%B5%D0%BD%D1%83-dnsdist" class="hash-link" aria-label="Прямая ссылка на Выход на сцену DNSdist" title="Прямая ссылка на Выход на сцену DNSdist">​</a></h2>
<p>Теперь давайте поговорим наконец-то о том, что же такое DNSdist. Если по-простому, то это Load Balancer для DNS-запросов. Он не содержит информации о зонах (кроме той, что закешировал), он просто берёт запрос и перенаправляет его самому подходящему, основываясь на политике балансировки, DNS-серверу (если предыдущий ответ на такой же запрос не закешировался или кеш «протух»).</p>
<p>Конфигурацию DNSdist принимает либо в формате Lua-скрипта, либо в формате обычной и всем знакомой YAML-конфигурации. В нашем понимании Lua намного гибче, чем YAML (так как это, блин, скриптовый язык), поэтому, если инструмент из коробки даёт возможность сконфигурировать себя чем-то таким, то надо хотя бы попробовать! Мы попробовали, и получилось очень даже неплохо :).</p>
<p>По конфигурации важно отметить один не очень приятный момент: DNSdist не может «на ходу» перечитать конфигурацию из файла, который вы ему указали. То есть нет никакого <code>systemctl reload dnsdist</code>, и вы не можете отправить ему SIGHUP, чтобы он что-то там перечитал в своей конфигурации (однако это не значит, что вы не можете заставить dnsdist переоткрыть файл, в который он пишет логи. Об этом будет ниже).</p>
<p>Но это не означает, что вы вообще не можете настраивать DNSdist без перезагрузки. DNSdist имеет <a href="https://www.dnsdist.org/guides/webserver.html" target="_blank" rel="noopener noreferrer">встроенный веб-сервер</a>, который помимо того, что может выводить метрики сервера в Prometheus формате и отображать их на простенькой веб-страничке (скриншот ниже), также позволяет частично манипулировать конфигурацией. Но под манипуляцией, к сожалению или к счастью, имеется в виду только <a href="https://www.dnsdist.org/guides/webserver.html?highlight=api#delete--api-v1-cache?pool=-pool-name-&amp;name=-dns-name-%5B&amp;type=-dns-type-%5D%5B&amp;suffix=%5D" target="_blank" rel="noopener noreferrer">сброс кеша</a> и <a href="https://www.dnsdist.org/guides/webserver.html?highlight=api#put--api-v1-servers-localhost-config-allow-from" target="_blank" rel="noopener noreferrer">добавление адресов, которые могут обращаться к серверу</a>.</p>
<p><img decoding="async" loading="lazy" alt="dnsdist-webui" src="https://davy.page/assets/images/dnsdist-webui-c126b724b282206462a63ad3e13b58ee.png" width="1379" height="778" class="img_ev3q"></p>
<p>Ещё вы можете вносить изменения в конфигурацию через консольный доступ к DNSdist. Всё, что вам нужно сделать — это прописать вот эти две строчки в конфиге:</p>
<div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">controlSocket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'127.0.0.1:8899'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">setKey</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"ENCODED KEY"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>И дальше вот таким образом подключиться к консоли: <code>dnsdist -k "ENCODED KEY" -c 127.0.0.1:8899</code>, если вы не рут, и без указания ключа, если выполняете команду от рута. Это не очень удобно, и нормально такое автоматизировать будет достаточно геморройно, но это можно использовать, как ручник, когда вам <strong>ну вот вообще нельзя ребутать DNSdist</strong>, а внести изменения в конфигурацию надо. Подробнее об этом <a href="https://www.dnsdist.org/guides/console.html" target="_blank" rel="noopener noreferrer">тут</a>.</p>
<p>Если вам нужно менять конфигурацию периодически, и факторы, по которым вам нужно это делать, вы знаете, а такжесчитаете, что можете легко описать их в коде, то DNSDist предоставляет вам следующие возможности: создавать <a href="https://www.dnsdist.org/advanced/timedipsetrule.html" target="_blank" rel="noopener noreferrer">динамические блоки временных IP-адресов</a>, на которые вы сможете «завязаться» в своих политиках, описывать какой-либо код в <a href="https://www.dnsdist.org/reference/config.html#maintenance" target="_blank" rel="noopener noreferrer">функции maintenance()</a>, которая запускается автоматически раз в секунду, использовать <a href="https://www.dnsdist.org/guides/dynblocks.html" target="_blank" rel="noopener noreferrer">блоки динамических правил</a> и так далее. Вы можете написать почти любую логику для динамического изменения политик балансировки. Например, сделать так, чтобы в случае, если часть серверов в одном пуле вдруг начала периодически отдавать ServFail, перевести трафик на другой пул. Главное, чтобы ваши Lua-функции работали достаточно быстро и не блокировали выполнение других. Мы такими вещами у себя не пользуемся, наша конфигурация достаточно проста.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="наша-конфигурация-dnsdist">Наша конфигурация DNSdist<a href="https://davy.page/dnsdist-in-sberdevices#%D0%BD%D0%B0%D1%88%D0%B0-%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%86%D0%B8%D1%8F-dnsdist" class="hash-link" aria-label="Прямая ссылка на Наша конфигурация DNSdist" title="Прямая ссылка на Наша конфигурация DNSdist">​</a></h2>
<p>Давайте теперь посмотрим, на то как выглядит наша конфигурация DNSdist. Полностью, конечно, не покажем, но самые интересные моменты подсветим :).</p>
<p>Начинается всё с файла <code>dnsdist.conf</code>, который и указывается при запуске DNSdist.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><code>dnsdist.conf</code></summary><div><div class="collapsibleContent_i85q"><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Импорт других файлов конфигурации</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">dofile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"/etc/dnsdist/preps.lua"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">dofile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"/etc/dnsdist/secrets.lua"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">dofile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"/etc/dnsdist/pools.lua"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">dofile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"/etc/dnsdist/logging.lua"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">dofile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"/etc/dnsdist/pool_actions.lua"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Политика балансировки по умолчанию</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">setServerPolicy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">roundrobin</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Сокет для DNS принятия запросов</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">setLocal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'0.0.0.0:53'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Настройка сокета для изменения конфигурации из терминала</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">controlSocket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'127.0.0.1:8899'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">setKey</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">terminalPass</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Настройка веб сервера</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">webserver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.0.0.0:8080"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">setWebserverConfig</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  password</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">webServerPass</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  apiKey</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">webServerPass</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Из интересного в этом файле:</p>
<ol>
<li>Возможность импорта других файлов конфигураций, которую предоставляет Lua.</li>
<li>Переопределение дефолтной политики балансировки трафика.</li>
</ol>
<p>По первому пункту, я думаю, всё понятно, а вот про второй давайте поподробнее. По дефолту для всех пулов апстримов используется политика <code>leastOutstanding</code>, которая отправляет запрос серверу либо с меньшим количеством запросов «в очереди», либо, если таких нет, то серверу с наименьшим порядковым значением, либо, если и таких нет, то с наименьшим средним latency. Нам такая стратегия не подходила, потому что при ней у нас в каждом пуле большая часть запросов летела в один сервер (потому что у него на 1-2мс latency был ниже, чем у других). Поэтому мы решили использовать для балансировки стандартный roundrobin. Подробнее про политики балансировки можно почитать <a href="https://www.dnsdist.org/guides/serverselection.html" target="_blank" rel="noopener noreferrer">тут</a>.</p>
<p>Далее у нас идет <code>preps.lua</code> файл, в нём лежат константы и функция создания новых пулов.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><code>preps.lua</code></summary><div><div class="collapsibleContent_i85q"><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">geoProdZone </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"geo.zona."</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Селектор запросов определённой зоны</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">geoProdZoneSelector </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">QNameSuffixRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">geoProdZone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Селектор запросов только от определённых source ip</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">cloud1SubnetsSelector </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">OrRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">NetmaskGroupRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.18.0.0/16"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">NetmaskGroupRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.19.0.0/16"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">NetmaskGroupRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.20.0.0/16"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">newPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> v </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">ipairs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">servers</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">local</span><span class="token plain"> server </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      address</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Основной пул для сервера</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      pool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">primaryPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      checkType</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"SOA"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">--- Сервер обязан ответить что-то, что не NXDomain, ServFail или Refused чтобы пройти хелс чек</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      mustResolve</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">--- Выводим сервер из балансировки после трех неудачных проверок</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      maxCheckFailures</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Две успешные проверки чтобы ввести сервер обратно в балансировку</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      rise</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">checkName </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">zone</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">local</span><span class="token plain"> newServer </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">newServer</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Определяем вторичный пул для сервреа</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">secondaryPool </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">then</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        newServer</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token function" style="color:hsl(207, 82%, 66%)">addPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">secondaryPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">end</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>В целом для констант всё описано в комментариях, поэтому на них не будем заострять внимание. С функцией чуть поинтереснее. DNSdist из коробки даёт <a href="https://www.dnsdist.org/reference/config.html?highlight=newserver#newServer" target="_blank" rel="noopener noreferrer">функцию на создание нового сервера</a> (по сути, на определение апстрима), но использовать только её нам не очень понравилось из-за дублирования кода, поэтому пришлось смастерить свою небольшую функцию <code>newPool</code>, которая и определяет сервер с правильными хелсчеками, и добавляет его в основной пул и вторичный (если такой передан).</p>
<p>Теперь посмотрите, как удобно ей создавать пулы апстримов в файле <code>pools.lua</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><code>pools.lua</code></summary><div><div class="collapsibleContent_i85q"><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">newPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  servers </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">address</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.23.1.2"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cloud1_prod_consul1"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">address</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.23.1.3"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cloud1_prod_consul2"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">address</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"172.23.1.4"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cloud1_prod_consul3"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Передаём основной пул для серверов</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  primaryPool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_prod_cloud1"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Передаём вторичный пул для серверов</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  secondaryPool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_prod_default"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Передаём зону для корректных хелсчеков</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  zone </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> consulProdZone</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Далее у нас идет небольшой, но интересный файлик logging.lua.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><code>logging.lua</code></summary><div><div class="collapsibleContent_i85q"><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">forLogsSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">dq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">not</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    dq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">qname</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token function" style="color:hsl(207, 82%, 66%)">isPartOf</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">newDNSName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"domain1.ru"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">or</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    dq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">qname</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token function" style="color:hsl(207, 82%, 66%)">isPartOf</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">newDNSName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"domain2.ru"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">and</span><span class="token plain"> dq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">qname</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token function" style="color:hsl(207, 82%, 66%)">countLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">addAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">LuaRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">forLogsSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">LogAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Имя файла, куда писать лог</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string" style="color:hsl(95, 38%, 62%)">"/var/log/dnsdist/queries.log"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Бинарный формат логов</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Добавлять (append) строчки логов к файлу или каждый раз очищать его</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- Буферизация для логов перед записью в файл</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>В нём мы настраиваем логгирование запросов к DNSdist-серверу. Само логгирование включается через добавление действия <a href="https://www.dnsdist.org/reference/actions.html?highlight=logaction#LogAction" target="_blank" rel="noopener noreferrer">LogAction</a>, которое записывает логи в файл. Подробнее про действия поговорим в следующем файле. В этом же для нас основной интерес представляет функция <code>forLogsSelector</code>, которая по сути обозначает запросы каких доменов нужно логгировать, а каких нет. В наши DNS-сервера летит куча запросов доменов, о которых нам не интересно знать, что их кто-то когда-то запрашивал, и, соответственно забивать этим еластик не очень хочется. И наоборот, есть домены, про резолв которых интересно было бы знать (в основном безопасникам). Поэтому в этом файлике мы отсекаем лог запроса большого количества ненужных зон и оставляем только те, которые нам нужны.</p>
<p>Если вы ротейтите логфайл (меняете текущему имя и создаете рядом новый), вам надо сказать DNSdist, чтобы он файлик переоткрыл. Для этого нужно воспользоваться терминалом и следующим образом «релоаднуть» LogAction:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">echo "getAction(0):reload()" | dnsdist -c 127.0.0.1:8899 </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Только учтите, что такой вызов работает только в случае, если действие с LogAction идёт в вашем списке первым. О порядке выполнение действий чуть ниже.</p>
<p>Ну и последнее – это файлик с действиями: <code>pool_actions.lua</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><code>pool_actions.lua</code></summary><div><div class="collapsibleContent_i85q"><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">-- consul cloud 1 action</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">addAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">AndRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  cloudOneSubnetsSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  consulDevZoneSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">PoolAvailableRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_dev_cloud1"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">PoolAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_dev_cloud1"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- consul fallback action</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">addAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">AndRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  consulDevZoneSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">PoolAvailableRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_dev_default"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">PoolAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"consul_dev_default"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">-- default fallback</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">addAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">AllRule</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">PoolAction</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"bind_default"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Тут важно немного объяснить, как работают действия (actions).</p>
<ul>
<li><strong>Во-первых</strong>, синтаксис у них следующий: первым аргументом идет селектор, который выбирает, на какие запросы распространяется действие. Вторым идет само действие (есть ещё третий аргумент – хешмапа с опциями, но мы ей не пользуемся).</li>
<li><strong>Во-вторых</strong>, последовательность, в которой вы эти действия в коде прописываете, имеет значение. То есть если вы самым первым определили действие с селектором <a href="https://www.dnsdist.org/reference/selectors.html?highlight=addaction#AllRule" target="_blank" rel="noopener noreferrer">AllRule</a>, то никакие действия дальше работать не будут просто потому, что первое действие по итогу будет обрабатывать все запросы. Исключениями тут являются действия, которые выполняются и пропускают запрос дальше – например, LogAction, про который говорили выше.</li>
<li><strong>В-третьих</strong>, вы можете менять последовательность действий на запущенном сервере DNSdist с помощью терминала, про который я говорил выше.</li>
</ul>
<p>Полный список селекторов и действий можно найти <a href="https://www.dnsdist.org/reference/selectors.html" target="_blank" rel="noopener noreferrer">тут</a> и <a href="https://www.dnsdist.org/reference/actions.html" target="_blank" rel="noopener noreferrer">тут</a>.</p>
<p>В нашем файле сверху у нас три действия.</p>
<ul>
<li>Первое отбирает только запросы от клиентов из облака Cloud1 и «нацеленные» на DEV зону consul. В случае, если dev консулы в Cloud1 живы, мы перенаправим туда трафик. Если хотя бы одно из условий не истинно, действие не выполнится, и запрос пойдет к следующему.</li>
<li>Второе – это уже фолбек для консулов. Оно проверяет, что пользователь запрашивает DEV зону consul и в дефолтном пуле консулов (то есть где находятся все консулы из всех облаков) есть хотя бы один живой сервер.</li>
<li>Ну и последнее – это фолбек для всех действий: если ничего выше не сработало, то трафик пойдет на дефолтные BIND-сервера.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="итог">Итог<a href="https://davy.page/dnsdist-in-sberdevices#%D0%B8%D1%82%D0%BE%D0%B3" class="hash-link" aria-label="Прямая ссылка на Итог" title="Прямая ссылка на Итог">​</a></h2>
<p>Подытожим: DNS-сервис, который мы предоставляем нашим клиентам, стал работать надёжнее после внедрения DNSdist за счёт его хелсчеков для апстрим DNS-серверов и гибкой настройки политик распределения DNS-трафика. Мы продолжим сопровождать DNSdist и в будущем, возможно, даже включим у него кеширование запросов на некоторых пулах для увеличения производительности.</p>
<p>Спасибо за чтение!</p>]]></content:encoded>
            <category>dns</category>
            <category>dnsdist</category>
            <category>bind</category>
            <category>sberdevices</category>
        </item>
        <item>
            <title><![CDATA[BPF CPU Scheduler: не нравится стандартный планировщик в Linux? Напиши свой]]></title>
            <link>https://davy.page/sched-ext</link>
            <guid>https://davy.page/sched-ext</guid>
            <pubDate>Sun, 14 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Всем привет! В статье расскажу про относительно новую возможность написания собственных CPU планировщиков для Linux с помощью BPF. Разберёмся, для чего это нужно, как работает, а также посмотрим на примеры уже написанных планировщиков.]]></description>
            <content:encoded><![CDATA[<p>Всем привет! В статье расскажу про относительно новую возможность написания собственных CPU планировщиков для Linux с помощью BPF. Разберёмся, для чего это нужно, как работает, а также посмотрим на примеры уже написанных планировщиков.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/sched_ext-88e50ddf7cb9477322af83969e192f40.png" width="1523" height="836" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/946822/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/946822/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="зачем-это-нужно">Зачем это нужно<a href="https://davy.page/sched-ext#%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D1%8D%D1%82%D0%BE-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE" class="hash-link" aria-label="Прямая ссылка на Зачем это нужно" title="Прямая �ссылка на Зачем это нужно">​</a></h2>
<p>Давайте перед тем, как говорить про BPF CPU Scheduler, немного обсудим имеющиеся во встроенном cpu планировщике линукс проблемы, из-за которых собственно и появилась идея создания возможности для разработчиков писать свои собственные шедулеры.</p>
<p><strong>Первая проблема</strong> – каким бы "Completely Fair" не был дефолтный планировщик, он все равно останется планировщиком общего назначения, и поэтому никогда не будет покрывать специфичные кейсы (гейминг, некоторые highload web сервисы и так далее).</p>
<p><strong>Вторая проблема</strong> – невероятная сложность устройства подсистемы CPU шедулинга в линукс. Если вам нужно внести туда какие-то свои правки или не дай бог написать какой-то дополнительную политику планирования, вам нужно полностью разбираться в этой системе, а она очень сложная и не то чтобы полностью задокументированная.</p>
<p><strong>Третья проблема</strong> – достаточно медленная разработка. Если вы всё-таки решились вносить какие-то правки в kernel scheduler, сразу приготовьтесь, что для каждой проверки, для каждого фикса вам нужно будет пересобирать ядро и перезапускать систему, а на это нужно время.</p>
<p><strong>Четвертая проблема</strong> – вероятно ваши правки, которые нужны только вам, в апстрим не попадут. Соответственно каждый раз, когда ядро будет обновляться, вам придется пулить изменения с апстрима в вашу ветку, и всегда есть большая вероятность, что придется править мердж конфликты, а когда мы говорим про ядро, это может быть достаточно нетривиально.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="что-такое-extensibe-cpu-scheduler-sched_ext">Что такое Extensibe CPU Scheduler (SCHED_EXT)<a href="https://davy.page/sched-ext#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-extensibe-cpu-scheduler-sched_ext" class="hash-link" aria-label="Прямая ссылка на Что такое Extensibe CPU Scheduler (SCHED_EXT)" title="Прямая ссылка на Что такое Extensibe CPU Scheduler (SCHED_EXT)">​</a></h2>
<p>Extensible Scheduler – это функционал ядра линукс, который даёт возможность пользователям создавать свои собственные политики распределения CPU времени. Делается это посредством написания BPF приложения и его последующей загрузки в ядро. После этого контролировать выделение цпу времени всем процессам (или только процессам с классом <code>SCHED_EXT</code>, об этом подробнее ниже) будет ваш планировщик.</p>
<p>В linux есть ряд классов планирования помимо <code>SCHED_EXT</code>, о которых можно почитать в другой моей статье :). Касательно этой темы важно знать, что при запуске extensibe шедулера все <code>SCHED_NORMAL</code>, <code>SCHED_IDLE</code> и <code>SCHED_EXT</code> задачи <a href="https://github.com/torvalds/linux/blob/dfd4b508c8c6106083698a0dd5e35aecc7c48725/kernel/sched/ext.c#L5736" target="_blank" rel="noopener noreferrer">перейдут под его контроль</a>, если не передан флаг <a href="https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_STRUCT_OPS/sched_ext_ops/#scx_ops_switch_partial" target="_blank" rel="noopener noreferrer">SCX_OPS_SWITCH_PARTIAL</a>. Если же флаг всё-таки передали, то наш кастомный планировщик будет управлять только задачами, которым мы руками выставим класс планирования <code>SCHED_EXT</code>. Это не особо рекомендуется, потому что приоритет <code>SCHED_EXT</code> ниже <code>SCHED_NORMAL</code> и ваш планировщик просто не сможет в полной мере "показать себя", если ему будут мешать задачки, управляемые дефолтным планировщиком. Проверить, управляется ли запущенный процесс extensible планировщиком, можно, посмотрев его <code>schedule</code> параметры в файле <code>/proc/$PID/sched</code>. Если вы видите там строчку <code>ext.enabled: 1</code>, значит процессорное время ему выделяет запущенный SCHED_EXT планировщик.</p>
<p>Примечательно, что в отличие от бага в модуле или подсистеме ядра, баг в BPF программе <code>SCHED_EXT</code> не приведет к <del>апокалипсису</del> kernel panic и необходимости перезагрузки системы. Если внутри вашего планировщика происходит ошибка, то BPF приложение завершается, а все процессы, ранее им управляемые, переходят обратно на дефолтный планировщик.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="внутреннее-устройство-sched_ext">Внутреннее устройство SCHED_EXT<a href="https://davy.page/sched-ext#%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B5%D0%BD%D0%BD%D0%B5%D0%B5-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%BE-sched_ext" class="hash-link" aria-label="Прямая ссылка на Внутреннее устройство SCHED_EXT" title="Прямая ссылка на Внутреннее устройство SCHED_EXT">​</a></h2>
<p>Начнем с самой базы – Сore CPU планировщика (<a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/core.c" target="_blank" rel="noopener noreferrer">kernel/sched/core.c</a>). Он определяет, какой класс планирования выставить потоку, вызывает функции шедулеров, принадлежащих конкретным классам планирования, реализует context switching и так далее. В мире ООП можно было бы назвать его родительским классом для всех остальных планировщиков.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/sched_ext_0-ebf36bc13953a18d9089eff0618abb4f.png" width="1244" height="1021" class="img_ev3q"></p>
<p>Далее у нас идет код класса планирования <code>SCHED_EXT</code> (<a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c" target="_blank" rel="noopener noreferrer">kernel/sched/ext.c</a>). В нём реализуется полный набор функций, которые требуются для функционирования отдельного класса планирования. Посмотреть их можно в вызове <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L4297" target="_blank" rel="noopener noreferrer">вот этого макроса</a>.</p>
<p>Если провалиться дальше в какую-нибудь функцию, например, в функцию <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L2365" target="_blank" rel="noopener noreferrer">enqueue_task_scx</a>, которая отвечает за добавление задачи в очередь, можно увидеть некоторое количество базовой логики, которая будет выполняться для всех пользовательских планировщиков. И если в этой же функции провалиться ещё глубже, в функцию <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L2246" target="_blank" rel="noopener noreferrer">do_enqueue_task</a>, то тут уже можно будет найти <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L2289" target="_blank" rel="noopener noreferrer">условие</a>, которое определяет, выполнять кастомную логику или дефолтную.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">/* Проверяется, реализована ли функция в вашем шедулере */</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">unlikely</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token function" style="color:hsl(207, 82%, 66%)">SCX_HAS_OP</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> enqueue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">goto</span><span class="token plain"> global</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">/* Вызывается функция кастомного шедулера */</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">SCX_CALL_OP_TASK</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> SCX_KF_ENQUEUE</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> enqueue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> p</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> enq_flags</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">/* ... */</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">/* Дефолтная реализация, на случай, если функция enqueue не реализована в вашем планировщике */</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">global</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token function" style="color:hsl(207, 82%, 66%)">touch_core_sched</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> p</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token function" style="color:hsl(207, 82%, 66%)">refill_task_slice_dfl</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">p</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token function" style="color:hsl(207, 82%, 66%)">dispatch_enqueue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">find_global_dsq</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">p</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> p</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> enq_flags</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Подобные дефолтные реализации есть для каждой функции, поэтому когда вы пишете свой планировщик, у вас нет функций, которые вам нужно обязательно реализовать, иначе ничего работать не будет. Есть только одно обязательное поле для пользовательского планировщика - его имя :). Все остальные поля, которые вы можете реализовать, вы найдете в структуре <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L253" target="_blank" rel="noopener noreferrer">sched_ext_ops</a>.</p>
<p>В самом низу файла можно найти <a href="https://github.com/torvalds/linux/blob/v6.16/kernel/sched/ext.c#L7656" target="_blank" rel="noopener noreferrer">фрагмент регистрации bpf_struct_ops</a>. <a href="https://docs.ebpf.io/linux/program-type/BPF_PROG_TYPE_STRUCT_OPS/sched_ext_ops/#scx_ops_switch_partial" target="_blank" rel="noopener noreferrer">"BPF Struct Ops"</a> - это специальный тип BPF программ, позволяющий реализовывать отдельный функционал ядра. Работает это таким образом – вы пишите функции (программы), кладете ссылки на них в специальную структуру, а потом, на этапе загрузки приложения в ядро, эта структура вместе с программами кладётся в определённое место в памяти ядра. И далее уже эти функции могут в качестве call-back'ов вызываться подсистемами ядра, например, как это было показано выше макросом <code>SCX_CALL_OP_TASK</code>.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/sched_ext_1-95a9bca30bf26a67be503992794d1eaa.png" width="1244" height="1021" class="img_ev3q"></p>
<p>На уровне выше идёт код BPF программы собственно вашего планировщика. Примеры, как они могут выглядеть, можно посмотреть в <a href="https://github.com/sched-ext/scx/tree/main/scheds/c" target="_blank" rel="noopener noreferrer">этой папке</a>. Вот самый простой из них - <a href="https://github.com/sched-ext/scx/blob/main/scheds/c/scx_simple.bpf.c" target="_blank" rel="noopener noreferrer">scx_simple.bpf.c</a>.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/sched_ext_2-06ccd756752744302ce41595214d8ffa.png" width="1778" height="1021" class="img_ev3q"></p>
<p>Ну и ещё выше остается только программа, которая вызывала syscall <code>bpf()</code>, загрузив тем самым BPF программу шедулера. Так же прилагаю самый простой пример - программу <a href="https://github.com/sched-ext/scx/blob/main/scheds/c/scx_simple.c" target="_blank" rel="noopener noreferrer">scx_simple.c</a>, запускающую планировщик scx_simple, на чей код уже была ссылка выше. Заметьте, что это единственная часть кода, которая запускается у нас в пространстве пользователя.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/sched_ext_3-9232693c213d16174ac456aceeaf7283.png" width="2590" height="1021" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="планировщик-в-user-space">Планировщик в User Space<a href="https://davy.page/sched-ext#%D0%BF%D0%BB%D0%B0%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D1%89%D0%B8%D0%BA-%D0%B2-user-space" class="hash-link" aria-label="Прямая ссылка на Планировщик в User Space" title="Прямая ссылка на Планировщик в User Space">​</a></h2>
<p>Вам может показаться, что единственное место, в котором вы можете описывать логику вашего шедулера - это код планировщика в пространстве ядра, но это не так. BPF приложение состоит из программ (считай функций), BPF Map (это может быть хеш-таблица, массив или более специфичные типы данных) и глобальных переменных, и последние два пункта доступны в том числе и из пространства пользователя. Поэтому у вас, например, может быть общая мапа, в которую BPF шедулер будет складывать задачи, запрашивающие процессорное время, а user-space шедулер будет решать, кому из этой мапы следующему дать доступ к процессору, и после этого перекладывать в другую мапу, из которой планировщик в ядре возьмёт задачу и сразу отправит выполняться. Примерно так поступили при реализации <a href="https://github.com/sched-ext/scx/blob/main/scheds/c/scx_userland.c" target="_blank" rel="noopener noreferrer">scx_userland</a>.</p>
<p>Вы можете справедливо задаться вопросом: "если у меня все основные решения по планированию задач принимаются в пространстве пользователя, не получится ли так, что теперь планировщик будет планировать сам себя?". Если процесс вашего "userland" планировщика имеет параметр ext.enabled: 1 (как этот параметр получается описано выше в разделе "Что такое Extensibe CPU Scheduler"), то да, получается ваш планировщик сам себе выписывает процессорное время. Эту ситуацию можно обыграть следующим образом: прописать логику в BPF коде так, чтобы часть планировщика, загруженная в ядро, относилась к своей "userland" части по-особенному. Например, BPF часть может выдать ей бесконечный доступ к процессорному времени, пока она не разберётся с накопленной очередью задач и не определит, на каких CPU они должны выполняться. Такой подход <a href="https://github.com/sched-ext/scx/blob/ce62059dd68c9a627e852de240b2f79c4a386514/rust/scx_rustland_core/assets/bpf/main.bpf.c#L886" target="_blank" rel="noopener noreferrer">применяется</a> в scx_rustland_core, фреймворке для написания "userland" планировщиков на rust.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="примеры-существующих">Примеры существующих<a href="https://davy.page/sched-ext#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D1%81%D1%83%D1%89%D0%B5%D1%81%D1%82%D0%B2%D1%83%D1%8E%D1%89%D0%B8%D1%85" class="hash-link" aria-label="Прямая ссылка на Примеры существующих" title="Прямая ссылка на Примеры существующих">​</a></h2>
<p>Примеров существующих SCHED_EXT планировщиков достаточно много, и почти со всеми вы можете ознакомиться в этом <a href="https://github.com/sched-ext/scx/tree/main/scheds" target="_blank" rel="noopener noreferrer">гит репозитории</a>. Ниже я перечислю несколько, по моему мнению, самых интересных.</p>
<ol>
<li>
<p><code>scx_rustland</code> – планировщик, приоритезирующий интерактивные процессы над фоновыми и просчитывающий все решения планирования в пространстве пользователя. Хорошо себя <a href="https://github.com/sched-ext/scx/assets/1051723/42ec3bf2-9f1f-4403-80ab-bf5d66b7c2d5" target="_blank" rel="noopener noreferrer">показал</a> на системе с запущенной Terraria, увеличив fps в игре с 30 кадров до 60. Весь код планировщика состоит из трёх частей: <a href="https://github.com/sched-ext/scx/blob/v1.0.16/rust/scx_rustland_core/assets/bpf/main.bpf.c" target="_blank" rel="noopener noreferrer">BPF код на C</a>, выполняющийся в ядре, <a href="https://github.com/sched-ext/scx/tree/v1.0.16/rust/scx_rustland_core" target="_blank" rel="noopener noreferrer">Rust фреймворк scx_rustland_core</a>, о котором уже писал выше, и <a href="https://github.com/sched-ext/scx/tree/v1.0.16/scheds/rust/scx_rustland" target="_blank" rel="noopener noreferrer">код на Rust</a>, реализующий правила политики с помощью фреймворка.</p>
</li>
<li>
<p><code>scx_layered</code> – планировщик, созданный в Meta (признана экстремистской и запрещена на территории РФ), позволяет делить процессы на "слои" и задавать каждому слою свою политику. Например, вы можете выделить все процессы в cgroup'е <code>system.slice</code> и указать, что процессам в ней выделяется от 1 до 4 ядер, и что выделение им новых ядер происходит только в случае высокой утилизации всех текущих. Подробнее можно почитать в этом <a href="https://github.com/sched-ext/scx/blob/case-studies/case-studies/scx_layered.md" target="_blank" rel="noopener noreferrer">исследовании</a> и в этом <a href="https://github.com/sched-ext/sched_ext/blob/case-studies/scx_layered/scx_layered-help.txt" target="_blank" rel="noopener noreferrer">мануале</a> по конфигурации scx_layered. <a href="https://lwn.net/Articles/974387/" target="_blank" rel="noopener noreferrer">Утверждается</a>, что в Meta (признана экстремистской и запрещена на территории РФ) этот планировщик используется для множества web сервисов, в которых важен точечный контроль над выделением CPU.</p>
</li>
<li>
<p><code>scx_lavd</code> – планировщик, <a href="https://lwn.net/Articles/974387/" target="_blank" rel="noopener noreferrer">как говорят</a>, разработанный специально для Steam Deck, и, как вы, наверное, уже поняли, для игр :). Код делится на BPF часть, написанную на С, и часть, написанную на Rust. Всё планирование задач происходит в C коде, а Rust предоставляет "высокоуровневую" информацию системе и загружает BPF код в ядро.</p>
</li>
</ol>
<p>__</p>
<p>Спасибо за чтение!</p>]]></content:encoded>
            <category>linux</category>
            <category>cpu</category>
            <category>ebpf</category>
        </item>
        <item>
            <title><![CDATA[Как мы сократили потребление памяти мониторингом на 75%, мигрируя с Prometheus на VictoriaMetrics Agent в OKD-кластерах]]></title>
            <link>https://davy.page/prometheus-to-vmagent-migration</link>
            <guid>https://davy.page/prometheus-to-vmagent-migration</guid>
            <pubDate>Sat, 12 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Расскажу про то, как устроен мониторинг в OKD-кластерах, какие у него есть минусы и как мы их побороли, мигрируя основную функциональность на VictoriaMetrics Agent.]]></description>
            <content:encoded><![CDATA[<p>Расскажу про то, как устроен мониторинг в OKD-кластерах, какие у него есть минусы и как мы их побороли, мигрируя основную функциональность на VictoriaMetrics Agent.</p>
<p><img decoding="async" loading="lazy" alt="prometheus-vmagent-migration" src="https://davy.page/assets/images/prometheus-vmagent-migration-67df15deb8a1cb7b04c2da7a4f89d006.png" width="1920" height="1080" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/929226/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/929226/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="про-кластерный-мониторинг-в-okd">Про кластерный мониторинг в OKD<a href="https://davy.page/prometheus-to-vmagent-migration#%D0%BF%D1%80%D0%BE-%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%BD%D1%8B%D0%B9-%D0%BC%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3-%D0%B2-okd" class="hash-link" aria-label="Прямая ссылка на Про кластерный мониторинг в OKD" title="Прямая ссылка на Про кластерный мониторинг в OKD">​</a></h2>
<p>В OKD всё управляется встроенными операторами, и, соответственно, кластерный мониторинг — не исключение. У вас есть openshift-monitoring оператор, который разворачивает всё, что касается мониторинга: prometheus-operator, kube-state-metrics, openshift-state-metrics, node-exporter и так далее. А так как он всё это разворачивает, то он же и обновляет, и вносит изменения в конфигурацию всех компонентов. По обновлению, я думаю, всё понятно — обновляется версия кластера = обновляется версия оператора = обновляются компоненты, которыми оператор управляет. Это в принципе очень удобно. Теперь про конфигурацию: все изменения в компоненты вносятся исключительно через оператор, вы не можете в обход него пойти и что-то там подправить в прометеусе — ваши изменения просто перезатрёт. На словах это очень круто и логично звучит, но реализация... Ниже в разделе "Почему решили переезжать на VMAgent" я подробнее опишу минусы этого.</p>
<p><img decoding="async" loading="lazy" alt="openshift-monitoring-deploys" src="https://davy.page/assets/images/openshift-monitoring-deploys-278347abbaaa4c922c6a6e678130831a.png" width="1920" height="1080" class="img_ev3q"></p>
<p>Основную нагрузку в этой схеме у нас принимает Prometheus, так как именно на него и сваливаются все метрики кластера. В OKD есть два типа инсталляций Prometheus: openshift-monitoring (далее по тексту "кластерный прометей") и openshift-user-workload-monitoring (далее по тексту "клиентский прометей"). Первый отвечает за снятие метрик самого кластера, то есть это метрики cAdvisor, node-exporter, kube-state-metrics и так далее. Второй отвечает за снятие метрик с приложений. Это разделение нужно для того, чтобы, например, толстые метрики какого-нибудь пользовательского приложения, убив прометей, не лишили при этом администраторов кластера доступа к "служебным" метрикам.</p>
<p>Развёртка этих двух прометеев в самом кластере — это деплой двух StatefulSet'ов в разных namespace'ах. Количество реплик этих SS не регулируется и в 99% случаев равно двум, подробнее про то, почему количество реплик нельзя регулировать, будет написано ниже в разделе "Почему решили переезжать на VMAgent". При этом сами эти реплики — это идентичные прометеи, которые скрепают в рамках SS одни и те же таргеты. То есть обе реплики кластерного прометея собирают ВСЕ кластерные метрики, а обе реплики клиентского прометея собирают ВСЕ пользовательские метрики :). То есть это не шарды, которые поделили между собой таргеты, и каждый собирает свои.</p>
<p><img decoding="async" loading="lazy" alt="prometheus-installations" src="https://davy.page/assets/images/prometheus-installations-2bfda5a63c2a212504e9a3460465f65d.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="как-был-настроен-у-нас">Как был настроен у нас<a href="https://davy.page/prometheus-to-vmagent-migration#%D0%BA%D0%B0%D0%BA-%D0%B1%D1%8B%D0%BB-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD-%D1%83-%D0%BD%D0%B0%D1%81" class="hash-link" aria-label="Прямая ссылка на Как был настроен у нас" title="Прямая ссылка на Как был настроен у нас">​</a></h2>
<p>Долгое время у нас была реализована следующая схема: есть "коммунальные" кластера VictoriaMetrics, и кластера OKD. В OKD кластерах были развёрнуты кластерный и клиентские инсталляции прометея. Обе эти инсталляции взаимодействовали с кластером VictoriaMetrics через компонент VMAuth, передавая свои метрики. Также у нас в каждом кластере была и есть OKD Console (веб-консоль кластера), которая ходит в прометей за кластерными метриками для отображения загруженности подов, метрик нод и так далее.</p>
<p>То есть у нас кластерные прометеусы выполняли две функции: все собранные метрики отправляли в VictoriaMetrics (основная функция) и также накапливали метрики для показа их в OKD Web Console (это касается только openshift-monitoring инсталляции Prometheus).</p>
<p><img decoding="async" loading="lazy" alt="OLD_Scheme" src="https://davy.page/assets/images/OLD_Scheme-d711f4e3b934d9715589e0c8c2df3d9a.png" width="1920" height="1080" class="img_ev3q"></p>
<p>На картинке выше описанная схема представлена чуть более подробнее. На ней видны четыре основных компонента кластера VictoriaMetrics, давайте по каждому вкратце.</p>
<ul>
<li>VMAuth: выше я сказал, что в качестве хоста для remoteWrite в прометеусах указывался VMAuth – это компонент кластера VictoriaMetrics, отвечающий за добавление слоя авторизации для нижележащих компонентов. При успешной авторизации он проксирует запрос далее на нужный сервис (VMInsert или VMSelect).</li>
<li>VMStorage: я думаю, по названию понятно, что это такое :). Это слой хранения, база данных для всех метрик кластера. Это может одна ВМка или несколько, репликация данных может быть включена, а может и нет, и так далее, возможностей для конфигурации много.</li>
<li>VMInsert и VMSelect — это, соответственно, пишущий и читающий компоненты. У каждого есть свои специфичные функции, например, у VMSelect'а есть дополнительный кеш для запросов, чтобы лишний раз не ходить в хранилище.</li>
</ul>
<p>Из представленной схемы кластера VictoriaMetrics, я думаю, уже понятен основной её плюс – гибкая микросервисная архитектура. Это позволяет быстро масштабировать кластер, а также добиваться максимальной отказоустойчивости. Например, "stateless" компоненты (VMAuth, VMInsert, VMSelect) вы можете увезти в Kubernetes, а VMStorage оставить на виртуальных машинах; вы можете отдельно скейлить «write» и «read» части кластера; вы можете выделить отдельные VMSelect для часто "читающего" сервиса, чтобы он не "зааффектил" остальных и так далее.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="что-такое-vmagent">Что такое VMAgent<a href="https://davy.page/prometheus-to-vmagent-migration#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-vmagent" class="hash-link" aria-label="Прямая ссылка на Что такое VMAgent" title="Прямая ссылка на Что такое VMAgent">​</a></h2>
<p>VMAgent по сути тот же самый Prometheus за одним исключением — вы не можете запрашивать метрики у VMAgent, потому что он на это не рассчитан. Он накапливает небольшое количество собранных им метрик и сразу отправляет в хранилище, которое поддерживает "Prometheus remote write" или "VictoriaMetrics remote write" протоколы.</p>
<blockquote>
<p>VictorieMetrics remote write протокол использует намного меньше сетевого трафика, чем аналогичный протокол от команды Prometheus (подробнее можно прочитать <a href="https://victoriametrics.com/blog/victoriametrics-remote-write/" target="_blank" rel="noopener noreferrer">тут</a>). VMAgent автоматически определяет, поддерживает ли хранилище протокол от VictoriaMetrics, и использует его для передачи данных.</p>
</blockquote>
<p><img decoding="async" loading="lazy" alt="vmagent" src="https://davy.page/assets/images/vmagent-ef70198fc816d85f55e15630584e5678.png" width="1560" height="1321" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="почему-решили-переезжать-на-vmagent">Почему решили переезжать на VMAgent<a href="https://davy.page/prometheus-to-vmagent-migration#%D0%BF%D0%BE%D1%87%D0%B5%D0%BC%D1%83-%D1%80%D0%B5%D1%88%D0%B8%D0%BB%D0%B8-%D0%BF%D0%B5%D1%80%D0%B5%D0%B5%D0%B7%D0%B6%D0%B0%D1%82%D1%8C-%D0%BD%D0%B0-vmagent" class="hash-link" aria-label="Прямая ссылка на Почему решили переезжать на VMAgent" title="Прямая ссылка на Почему решили переезжать на VMAgent">​</a></h2>
<p>Поговорим наконец, почему мы решили "съезжать" с Прометеуса в наших OKD-кластерах. На самом деле, мигрировали мы не полностью. Как я выше писал:</p>
<blockquote>
<p>То есть у нас кластерные прометеусы выполняли две функции: все собранные метрики отправляли в VictoriaMetrics (основная функция) и также накапливали метрики для показа их в OKD Web Console (это касается только openshift-monitoring инсталляции Prometheus).</p>
</blockquote>
<p>И вот если основную функцию мы ещё можем забрать у преметея и унести на VMAgent, то отображение метрик в web-консоли OKD мы реализовать через VictoriaMetrics, к сожалению, не можем. В консоли всё, что касается метрик, сильно "захардкожено", и работать оно может только с прометеем, находящимся внутри кластера. Но тем не менее функцию отправки кластерных метрик в VictoriaMetrics можно реализовать через VMAgent, и это очень хорошо.</p>
<p>Теперь давайте перейдем к причинам миграции:</p>
<ol>
<li>
<p>Урезанные возможности конфигурирования кластерного прометея в OKD. Список возможных настроек кластерных прометеев.</p>
<ul>
<li>Вы не можете точечно управлять списком таргетов, которые скрепает прометей, всё, что у вас есть, это поле <code>collectionProfile</code>, у которого есть два значения, "full" и "minimal", то есть "скрепай вообще всё что можно" и "скрепай только минимально необходимое". Причем эта настройка доступна только с версии 4.19 (самая последняя на момент написания статьи).</li>
<li>Вы не можете изменять количество реплик стейтфулсетов прометеусов. Если у вас кластер в HA-режиме (3 и более мастеров, подробнее <a href="https://docs.redhat.com/en/documentation/openshift_container_platform/4.14/html/operators/developing-operators#osdk-ha-sno-api_osdk-ha-sno" target="_blank" rel="noopener noreferrer">тут</a>), то количество реплик в стейтфулсетах кластерного и клиентского прометеев будет равно двум (в ином случае одной), и вы ничего не сможете с этим сделать. У вас просто будут дублироваться прометеи, и в случае, если у вас не маленький кластер (несколько тысяч подов), то одна реплика кластерного прометея может спокойно потреблять 15–20 ГБ оперативной памяти. Это при условии, что прометей отправляет метрики в удаленное хранилище и ещё накапливает их для OKD Web Console.</li>
<li>Вы не можете вносить изменения в конфигурацию kube-state-metrics, ограничивая количество и список ресурсов, который он выводит в метрики. Если у вас есть ресурс, который, например, очень часто пересоздаётся/обновляется, то это будет генерировать значительное количество метрик, которое вам, может быть, и не нужно. И вы также не можете поднять свою инсталляцию kube-state-metrics, сконфигурировать её как вам нужно и перенаправить прометеусы на неё.</li>
</ul>
</li>
<li>
<p>Высокое потребление ресурсов (в частности, RAM). В предыдущем пункте затронул эту тему.</p>
</li>
<li>
<p>Стабильность. Этот пункт тоже касается ресурсов :). У всех прометеев обязательно стояли лимиты на потребление RAM, но им его вечно не хватало, особенно если кластер резко рос по числу подов или в случае проведения тех работ. Из-за этого прометеи могли в цикле умирать по ООМу и, соответственно, ослеплять мониторинг. Чтобы это "полечить", нужно было тупо повышать им лимит на потребление оперативной памяти, так как давать ему безлимит на потребление RAM (или просто сильно завышать этот лимит) не очень хотелось. Мало ли что у него может заглючить и он съест всю оперативку на ноде.</p>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="процесс-миграции">Процесс миграции<a href="https://davy.page/prometheus-to-vmagent-migration#%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D0%BC%D0%B8%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D0%B8" class="hash-link" aria-label="Прямая ссылка на Процесс миграции" title="Прямая ссылка на Процесс миграции">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-установка-оператора-victoriametrics">1. Установка оператора VictoriaMetrics<a href="https://davy.page/prometheus-to-vmagent-migration#1-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%EF%BF%BD%D0%B0-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B0-victoriametrics" class="hash-link" aria-label="Прямая ссылка на 1. Установка оператора VictoriaMetrics" title="Прямая ссылка на 1. Установка оператора VictoriaMetrics">​</a></h3>
<p>Миграция начинается с установки <a href="https://docs.victoriametrics.com/operator/#features-of-vmoperator" target="_blank" rel="noopener noreferrer">VictoriaMetrics Operator</a>, через который мы будем разворачивать инсталляции VMAgent. VMAgent можно поставить и без оператора, напрямую. Есть даже <a href="https://github.com/VictoriaMetrics/helm-charts/tree/master/charts/victoria-metrics-agent" target="_blank" rel="noopener noreferrer">helm chart</a> для этого. Но у установки с помощью оператора есть существенные плюсы:</p>
<ul>
<li>позволяет разворачивать в кластере не только VMAgent, но и другие компоненты экосистемы VictoriaMetrics, типа VMAuth или VMSelect;</li>
<li>позволяет шардировать инсталляции VMAgent'а, то есть он может автоматически делить собираемые таргеты между шардами, количество которых вы также можете регулировать (вместе с этим вы можете управлять и количеством реплик шардов).</li>
</ul>
<p>Установка оператора производится через <a href="https://artifacthub.io/packages/helm/victoriametrics/victoria-metrics-operator" target="_blank" rel="noopener noreferrer">helm chart</a>, для деплоя в OKD каких-то особенных параметров не требуется. В чарт встроена проверка на то, что вы деплоите оператор в OpenShift/OKD кластер, и в таком случае в ресурсы чарта вносятся соответствующие изменения.</p>
<p>После установки оператора он автоматически для каждого ресурса ServiceMonitor (SM) создаст VictoriaMetricsServiceScrape (VMSS).</p>
<blockquote>
<p>Если у вас в кластере используется ArgoCD, то рекомендуется включать параметр чарта <code>operator.enable_converter_ownership</code>, чтобы для созданных автоматически ресурсов VMSS в <code>ownerReference</code> указывался SM, по которому они были созданы. Иначе ArgoCD может помечать их как "объекты на удаление".</p>
</blockquote>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-установка-инсталляций-vmagent">2. Установка инсталляций VMAgent<a href="https://davy.page/prometheus-to-vmagent-migration#2-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B8%D0%BD%D1%81%D1%82%D0%B0%D0%BB%D0%BB%D1%8F%D1%86%D0%B8%D0%B9-vmagent" class="hash-link" aria-label="Прямая ссылка на 2. Установка инсталляций VMAgent" title="Прямая ссылка на 2. Установка инсталляций VMAgent">​</a></h3>
<p>Нам необходимы две инсталляции VMAgent: для служебных метрик кластера и для метрик с клиентских приложений (по той же причине, по которой в OKD/Openshift существует это деление). Делается это через создание ресурсов с kind <code>VMAgent</code>. Но если просто взять и создать два таких ресурса, то оператор запустит эти две инсталляции, разобьёт на шарды и тд, но "скрепать" они будут одни и те же таргеты, нам такое не подходит. К счастью для ресурсов VMAgent можно прописывать селекторы для таргетов, ими мы и воспользовались.</p>
<p>VMAgent для клиентских метрик у нас настроен с такими селекторами:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">serviceScrapeNamespaceSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchExpressions</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">operator</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> DoesNotExist</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> openshift.io/cluster</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">monitoring </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Специальный лейбл на служебных неймспейсах</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">serviceScrapeSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchExpressions</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">operator</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> DoesNotExist</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> vmagent</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">cluster</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">metrics </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Специальный лейбл для VMSS, предназначенных инсталляции VMAgent собирающей служебные метрики</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>А VMAgent для кластерных метрик настроен с такими:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">serviceScrapeSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">vmagent-cluster-metrics</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"true"</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Специальный лейбл для VMSS, предназначенных инсталляции VMAgent собирающей служебные метрики</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">nodeScrapeNamespaceSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kubernetes.io/metadata.name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> openshift</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">monitoring </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Следит за VMNodeScrape только с конкретного namespace</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Таким образом у нас каждая инсталляция собирает только те таргеты, которые предназначены ей.</p>
<p>Из интересного ещё устанавливалось вот такое affinity правило для того, чтобы реплики одного и того же шарда по возможности не попадали на одну ноду:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">affinity</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">podAntiAffinity</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">		</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">preferredDuringSchedulingIgnoredDuringExecution</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">			</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">weight</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">100</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">			  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">podAffinityTerm</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">			  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labelSelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">				  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">						</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app.kubernetes.io/instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> vmoperator</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">vmagent</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">						</span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">shard-num</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'%SHARD_NUM%'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">			  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">topologyKey</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> kubernetes.io/hostname</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-правки-кластерных-прометеев">3. Правки кластерных прометеев<a href="https://davy.page/prometheus-to-vmagent-migration#3-%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%BD%D1%8B%D1%85-%D0%BF%D1%80%D0%BE%D0%BC%D0%B5%D1%82%D0%B5%D0%B5%D0%B2" class="hash-link" aria-label="Прямая ссылка на 3. Правки кластерных прометеев" title="Прямая ссылка на 3. Правки кластерных прометеев">​</a></h3>
<p>Теперь, когда VMAgent'ы установлены, нужно "отключить" прометеи. К сожалению, полностью отключить можно будет только один из них, но что поделать.</p>
<p>Удаляем configmap, включающий клиентский прометей. Выглядит он как-то так:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> ConfigMap</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">wokload</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">monitoring</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">config</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> openshift</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">workload</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">monitoring</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">config.yaml</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token scalar string" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">    enableUserWorkload: true # &lt;-- включение прометея для клиентских метрик</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">							 </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># ... далее все его настройки </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Удаляем поле <code>remoteWrite</code> из configmap "cluster-monitoring-config" в namespace "openshift-monitoring", тем самым отключая отправку метрик в VictoriaMetrics для кластерного прометея.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="проблемы-после-миграции">Проблемы после миграции<a href="https://davy.page/prometheus-to-vmagent-migration#%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D1%8B-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D0%BC%D0%B8%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D0%B8" class="hash-link" aria-label="Прямая ссылка на Проблемы после миграции" title="Прямая ссылка на Проблемы после миграции">​</a></h3>
<p>Разумеется не могло всё пройти без проблем. По порядку:</p>
<p>Первое: пропажа некоторых лейблов и агрегирующих метрик. По этому пункту основное — это отсутствие лейбла <code>prometheus_replica</code> на всех метриках, собираемых VMAgent'ами. <code>prometheus_replica</code> — это лейбл, вешавшийся на все метрики, отсылаемые в remoteWrite прометеями, и обозначавший, с какой конкретно реплики (prometheus-0 или prometheus-1) пришла метрика. На всех наших бордах в графане была завязка на этот лейбл, поэтому пришлось править их всех :). Так же кластерные прометеи на ходу создавали агрегирующие метрики (<a href="https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules" target="_blank" rel="noopener noreferrer">Recording rules</a>), и полностью повторить их с переходом на VMAgent у нас не получилось, поэтому ото всех таких метрик (полный список <a href="https://github.com/openshift/cluster-monitoring-operator/blob/main/assets/cluster-monitoring-operator/prometheus-rule.yaml#L44" target="_blank" rel="noopener noreferrer">тут</a>) пришлось отказаться.</p>
<p>Второе: не все ServiceMonitor'ы корректно переводились оператором в VMSS. Выше я писал, что VictoriaMetrics оператор автоматически транслирует ресурсы ServiceMonitor в VictoriaMetricsServiceScrape. В общем SM, нацеленные на служебные сервисы (типа etcd, kubelet и тд), он транслировал неправильно, все их приходилось ручками переделывать.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="результаты">Результаты<a href="https://davy.page/prometheus-to-vmagent-migration#%D1%80%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D1%8B" class="hash-link" aria-label="Прямая ссылка на Результаты" title="Прямая ссылка на Результаты">​</a></h2>
<p>После миграции у нас существенно снизилось потребление ресурсов у компонентов кластеров, отвечающих за мониторинг.</p>
<blockquote>
<p>К сожалению, у нас сохранились только метрики, на которых видно отключение remoteWrite у инсталляции кластерного прометея, а также установку VMAgent'ов, которые теперь будут слать метрики в кластер VictoriaMetrics. <strong>Этот момент выделен голубой линией на графиках.</strong></p>
<p>Отключение клиентского прометея мы совершили сильно раньше, поэтому метрик за этот период у нас не сохранилось :(. Потреблял он около 10-15% от того, что потребляет кластерный прометей.</p>
</blockquote>
<ul>
<li>Общее потребление памяти по нашим кластерам
<img decoding="async" loading="lazy" alt="results_ram" src="https://davy.page/assets/images/results_ram-ba5e35975a2a6c7d56fe53fa03774e3b.png" width="3234" height="1574" class="img_ev3q"></li>
<li>Общее потребление CPU по нашим кластерам
<img decoding="async" loading="lazy" alt="results_cpu" src="https://davy.page/assets/images/results_cpu-750d682c278e401c1638fceca9df098b.png" width="3238" height="1576" class="img_ev3q"></li>
<li>Потребление отдельных VMAgent'ов на одном из самых нагруженных кластеров
<img decoding="async" loading="lazy" alt="results_single_cluster" src="https://davy.page/assets/images/results_single_cluster-520cfa46775934e9e5b3b11975570c29.png" width="2772" height="964" class="img_ev3q"></li>
</ul>
<p>При том, что в целом общие показатели потребления сильно снизились, мы также заметили, что потребление отдельных VMAgent'ов не особо растет при резком увеличении количества метрик, которые они обрабатывают. Пока что за всё время, что у нас работают VMAgent'ы (чуть больше полугода), у нас <strong>ни разу не было такого, что они падали от резких скачков нагрузки</strong>.</p>]]></content:encoded>
            <category>kubernetes</category>
            <category>okd</category>
            <category>prometheus</category>
            <category>victoriametrics</category>
            <category>monitoring</category>
        </item>
        <item>
            <title><![CDATA[Про лимиты на CPU в kubernetes]]></title>
            <link>https://davy.page/k8s-cpu-limits</link>
            <guid>https://davy.page/k8s-cpu-limits</guid>
            <pubDate>Sun, 29 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Поговорим о лимитах на CPU в kubernetes: как работают, какие выставлять, нужны/не нужны и так далее.]]></description>
            <content:encoded><![CDATA[<p>Поговорим о лимитах на CPU в kubernetes: как работают, какие выставлять, нужны/не нужны и так далее.</p>
<p><img decoding="async" loading="lazy" alt="thumbnail" src="https://davy.page/assets/images/k8s-cpu-image1-57a3ea7a3da87c83175ddb45dd95623a.png" width="1920" height="850" class="img_ev3q"></p>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="проблема">Проблема<a href="https://davy.page/k8s-cpu-limits#%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0" class="hash-link" aria-label="Прямая ссылка на Проблема" title="Прямая ссылка на Проблема">​</a></h2>
<p>Мы с нашими клиентами часто сталкивались с ситуацией, когда контейнеру нужно значительно повышать лимиты на CPU, чтобы приложению в нём нормально работало и не теряло в производительности. И под "значительно повышать", я имею ввиду выставлять лимиты, в несколько раз превосходящие реквесты.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Интересное для пользователей/администраторов <b>OpenShift | OKD кластеров</b></summary><div><div class="collapsibleContent_i85q"><p>У вас есть приложение в контейнере, которое по графикам потребляет 50m CPU. При том, что лимит у него стоит в 100m, работает оно хреново. На графиках вы не видите, чтобы приложение упиралось в свой лимит по CPU и из-за этого не понимаете, в чем дело. Вы долго думаете, что делать, и решаете повысить лимит в 2 раза. О чудо! Производительность увеличилась в два раза! Но по графикам контейнер продолжает потреблять 50m CPU и не упирается в лимит. Как так?</p><p><img decoding="async" loading="lazy" alt="OpenShift Example" src="https://davy.page/assets/images/k8s-cpu-image2-95245269f2e0cca473b5c1aa53b60f66.png" width="1904" height="642" class="img_ev3q"></p><p>Это происходит, потому что метрика (<code>pod:container_cpu_usage:sum</code>), которую вам предоставляет OpenShift | OKD, сглаживает резкие скачки и падения потребления CPU. Метрика <code>pod:container_cpu_usage:sum</code> это на самом деле агрегированный через prometheus rule запрос <code>sum(rate(container_cpu_usage_seconds_total{container="",pod!=""}[5m])) BY (pod, namespace)</code>.</p><p>Ниже на скриншоте приведён пример потребления контейнера, в котором я запускал программу, которая сразу после запуска начинает потреблять все доступные ей ресурсы в рамках одного ядра. Запустил я её в ~13:08 и вместо того, чтобы увидеть максимальное потребление (в нашем случае 0.2CPU) в это время, я вижу, как потребление постепенно растёт, пока не достигает реального значения. Тоже самое происходит и после "убийства" процесса в ~13:23 – вместо того, чтобы моментально упасть до нуля, потребление плавно снижается.</p><p><img decoding="async" loading="lazy" alt="OpenShift Metrics Example" src="https://davy.page/assets/images/k8s-cpu-image3-57a3ea7a3da87c83175ddb45dd95623a.png" width="1920" height="850" class="img_ev3q"></p><p>Из-за этого на графиках в консоли OpenShift вы никогда не увидите краткосрочных скачков потребления. Например, если процесс на несколько секунд упрётся в лимит контейнера.</p></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="дробные-лимиты-на-cpu">Дробные лимиты на CPU<a href="https://davy.page/k8s-cpu-limits#%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D1%8B%D0%B5-%D0%BB%D0%B8%D0%BC%D0%B8%D1%82%D1%8B-%D0%BD%D0%B0-cpu" class="hash-link" aria-label="Прямая ссылка на Дробные лимиты на CPU" title="Прямая ссылка на Дробные лимиты на CPU">​</a></h2>
<p>Причина у нашей проблемы одна – дробные лимиты на CPU. О том, что это такое, как возникает и как лечить – расскажу ниже.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="i-у-приложения-один-поток">I. У приложения один поток<a href="https://davy.page/k8s-cpu-limits#i-%D1%83-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BE%D0%B4%D0%B8%D0%BD-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA" class="hash-link" aria-label="Прямая ссылка на I. У приложения один поток" title="Прямая ссылка на I. У приложения один поток">​</a></h3>
<p>Давайте представим, что у вас в контейнере запущено приложение, которое под капотом имеет всего один поток. В таком случае, если вы этому контейнеру установите лимит меньше одного ядра, вы будете всегда получать задержки, и соответственно просадки в производительности приложения.</p>
<p><img decoding="async" loading="lazy" alt="one thread example" src="https://davy.page/assets/images/k8s-cpu-image4-a691b726638fd373af5ec156db8d62bb.png" width="2204" height="884" class="img_ev3q"></p>
<p>Почему это происходит? Смотрите, когда поток становится исполняемым, то есть подошла его очередь на выполнение в процессоре, оно получает период выполнения, равный 100мс, в рамках которого процесс внутри потока должен выполниться. В случае, если этого не происходит, поток возвращается обратно в очередь и ждет следующего периода. И так он будет получать эти периоды, пока процесс в потоке не завершится.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Длина периода – это настраиваемый параметр. По дефолту – 100мс.</p></div></div>
<p>Как работает лимит? Допустим, вы указали контейнеру лимит в 400m. В таком случае поток приложения в контейнере сможет потратить 40мс из 100мс своих периодов. Что мы после этого получаем? Ниже у меня приведён пример процесса в потоке, контейнеру которого выставлен лимит в 400m CPU. По факту на выполнение этому процессу требуется всего 120мс, но из-за установленного лимита он не может потреблять всё время своих периодов. После того, как он проработал свой максимум (40мс), ему приходится ждать своего следующего периода. Поэтому на картинке мы видим паузы (троттлинг) в работе процесса, из-за которых 120мс превратились в 235мс.</p>
<p><img decoding="async" loading="lazy" alt="one thread limits example" src="https://davy.page/assets/images/k8s-cpu-image5-4d2f5ea077dd51e5a3188313881f544b.png" width="1024" height="367" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ii-у-приложения-много-потоков">II. У приложения много потоков<a href="https://davy.page/k8s-cpu-limits#ii-%D1%83-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%B2" class="hash-link" aria-label="Прямая ссылка на II. У приложения много потоков" title="Прямая ссылка на II. У приложения много потоков">​</a></h3>
<p>Давайте теперь рассмотрим чуть более сложный вариант – когда у приложения несколько потоков. В таком случае лимит, который вы указали для контейнера, будет делиться поровну между <strong>активными</strong> потоками приложения.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Под "активными" потоками я имею ввиду те, что в данный момент выполняются в процессоре.</p></div></div>
<p><img decoding="async" loading="lazy" alt="multiple threads 1" src="https://davy.page/assets/images/k8s-cpu-image6-8dbcad32d11c95098cad93044e1c9c86.png" width="2096" height="922" class="img_ev3q"></p>
<p>А если у вас лимит делится между активными, то существует <strong>большая вероятность</strong> того, что каждый из этих активных потоков по итогу получит дробный лимит (меньше одного).
<img decoding="async" loading="lazy" alt="multiple threads 2" src="https://davy.page/assets/images/k8s-cpu-image7-f96b426fc8da6b31788123c1b6129cbf.png" width="2174" height="1156" class="img_ev3q"></p>
<p>Например, у вас есть приложение с двумя потоками, вы контейнеру этого приложения задаёте лимит в одно ядро. В случае, если работает только один поток, он заберёт себе лимит в одно ядро полностью и соответственно будет иметь доступ к своим 100мс периодам (то есть по сути лимита для него не будет).</p>
<p>В случае же, если будут одновременно работать сразу два потока, то лимит в одно ядро поделится между ними и каждый получит по 500m CPU. А это в свою очередь означает, что каждый сможет использовать только половину своих периодов, что приведёт к троттлингу.
<img decoding="async" loading="lazy" alt="2 threads example" src="https://davy.page/assets/images/k8s-cpu-image8-1a3b2c6556e9c9866ec62e2dde254871.png" width="1390" height="812" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="итого">Итого<a href="https://davy.page/k8s-cpu-limits#%D0%B8%D1%82%D0%BE%D0%B3%D0%BE" class="hash-link" aria-label="Прямая ссылка на Итого" title="Прямая ссылка на Итого">​</a></h3>
<p>Давайте подведём небольшие итоги по дробным лимитам.</p>
<ol>
<li>Лимит меньше одного ядра приложений с одним потоком всегда будет приводить к задержкам и, соответственно, к потерям по производительности. Просто потому, что приложение не сможет целиком использовать свой период.</li>
<li>Для приложений с двумя и более потоками – анализируйте их загруженность. Например, есть приложение с двумя потоками, и эти потоки у него загруженны равномерно. Тут для получения максимальной производительности контейнеру нужно будет задавать лимит в два ядра, чтобы они поровну поделились между потоками и каждый получил по одному целому ядру. В случае же, если из этих двух потоков 90% времени работает только один, а второй выполняет фоновую активность, то контейнеру есть смысл ставить лимит в одно ядро, потому что большую часть времени работает из двух потоков только один.</li>
</ol>
<p><img decoding="async" loading="lazy" alt="limits resume" src="https://davy.page/assets/images/k8s-cpu-image9-e60754ca87246d2012d2636c686c1f54.png" width="1944" height="594" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="отказ-от-лимитов">Отказ от лимитов<a href="https://davy.page/k8s-cpu-limits#%D0%BE%D1%82%D0%BA%D0%B0%D0%B7-%D0%BE%D1%82-%D0%BB%D0%B8%D0%BC%D0%B8%D1%82%D0%BE%D0%B2" class="hash-link" aria-label="Прямая ссылка на Отказ от лимитов" title="Прямая ссылка на Отказ от лимитов">​</a></h2>
<p>Всё, что я рассказал выше про дробные лимиты, это на самом деле просто механизм ограничения использования процессорного времени в linux. Возможно он не учитывает какие-то факторы, которые хотелось бы, чтобы он учитывал, но имеем, что имеем.</p>
<p>Но исходя из того, что было мной рассказано выше – получается, что для максимальной производительности приложенния лимит его контейнеру должен быть либо <code>кол-во потоков = кол-во ядер в лимите</code>, либо <code>кол-во активных потоков = кол-во ядер в лимите</code>. И честно говоря, вторую формулу никто никогда не применяет :). Везде всегда лимит накручивается до максимума, лишь бы избавится от троттлинга. А если так, то зачем он вообще тогда нужен, может отказаться от него?</p>
<p>Идея отказа от лимитов на CPU звучит как что-то сумасшедшее, но на самом деле поизучав статьи в интернете, послушав мнения других пользователей k8s, мы в команде пришли к выводу, что в сообществе давно сформированно мнение о том, что установление CPU лимитов в k8s это своего рода антипаттерн, и что нужно ограничиться только высталвением CPU реквестов.</p>
<p>Но тут сразу возникает вопрос: не получится ли такой ситуации, что у меня на ноде появится процесс, который наплодит себе потоков, сожрёт все процессорное время ноды и не будет давать его другим контейнерам? Ответ: нет, такого не получится. В cgroupV2 существует параметр CPUWeight, который как раз включается в работу, когда на ноде начинается "борьба" за CPU ресурс. Например, у вас есть два потока, оба претендуют на процессорное время. У одного CPUWeight 100, у другого – 400. Тот, у которого 400, будет получать в 4 раза больше процессорного времени относительного того, у которого 100. В свою очередь параметр CPUWeight привязан к CPU реквестам, которые мы устанавливаем нашим контейнерам. Поэтому у нас получается, что в случае 100% загруженности CPU <strong>больше процессорного времени будут получать те процессы, которые его больше запросили в своих реквестах.</strong></p>
<ins><strong>Но есть один нюанс!</strong></ins>
<p>Более менее честно процессорное время при "борьбе за ресурсы" будет распределяться только если у контейнеров, между которыми это время распределяется, реквесты хотя бы больше 100m. Иначе будет получаться следующая картина.</p>
<p>(На ноде 16 CPU)</p>
<ol>
<li>Пример: два пода со 100% потреблением проц времени. Реквесты: 100m и 1m.
<img decoding="async" loading="lazy" alt="cpu-100-1_1" src="https://davy.page/assets/images/cpu-100-1_1-e60dc0265fc173e200a7b98704a4d700.png" width="3450" height="476" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-1_2" src="https://davy.page/assets/images/cpu-100-1_2-620309cf009f2eb6c901ec828a60efbf.png" width="3450" height="440" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-1_3" src="https://davy.page/assets/images/cpu-100-1_3-dc6d494c76d98439e67d1803a0aad535.png" width="3448" height="444" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-1_4" src="https://davy.page/assets/images/cpu-100-1_4-9f2176da168c29dede1577f68a0d71b2.png" width="3452" height="488" class="img_ev3q"></li>
<li>Пример: два пода со 100% потреблением проц времени. Реквесты: 100m и 20m.
<img decoding="async" loading="lazy" alt="cpu-100-2_1" src="https://davy.page/assets/images/cpu-100-2_1-860e7d58476e81d3d157ad6b5c0a0c62.png" width="3448" height="500" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-2_2" src="https://davy.page/assets/images/cpu-100-2_2-2bd40911b1be088389ca922a100e190d.png" width="3446" height="550" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-2_3" src="https://davy.page/assets/images/cpu-100-2_3-8087256ccbf66328f5c32e62e70f49c4.png" width="3444" height="400" class="img_ev3q">
<img decoding="async" loading="lazy" alt="cpu-100-2_4" src="https://davy.page/assets/images/cpu-100-2_4-f211e1b4d57705ed0f5cb165ba16db84.png" width="3450" height="546" class="img_ev3q"></li>
</ol>
<hr>
<p>Всё!</p>]]></content:encoded>
            <category>kubernetes</category>
            <category>cpu</category>
        </item>
        <item>
            <title><![CDATA[Почему Fedora CoreOS — это container optimized дистрибутив]]></title>
            <link>https://davy.page/why-fcos-is-container-optimized</link>
            <guid>https://davy.page/why-fcos-is-container-optimized</guid>
            <pubDate>Mon, 27 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Fedora CoreOS на официальном сайте представлена как container optimized, container-focused, container based и так далее OS. Но что это вообще значит? Там предустановлен какой-то container runtime? А еще что? В этой статье попытаемся разобраться.]]></description>
            <content:encoded><![CDATA[<p>Fedora CoreOS <a href="https://fedoraproject.org/" target="_blank" rel="noopener noreferrer">на официальном сайте</a> представлена как container optimized, container-focused, container based и так далее OS. Но что это вообще значит? Там предустановлен какой-то container runtime? А еще что? В этой статье попытаемся разобраться.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="fcos" src="https://davy.page/assets/images/fcos-921b80909a1dbb66fa94d60ba536fb8b.png" width="1560" height="877" class="img_ev3q"></p></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/companies/selectel/articles/817299/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/companies/selectel/articles/817299/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="что-такое-optimized">Что такое optimized<a href="https://davy.page/why-fcos-is-container-optimized#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-optimized" class="hash-link" aria-label="Прямая ссылка на Что такое optimized" title="Прямая ссылка на Что такое optimized">​</a></h2>
<p>Optimized в нашем случае стоит переводить не как «оптимизированная», а скорее как «оптимальная». Так и поступили неизвестные переводчики сайта Fedora Project. Потому что слово «оптимизированный» намекает на производительность, но никакого ее прироста при запуске контейнеров на FCOS (Fedora CoreOS) в сравнении с другими дистрибутивами мы не получим.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="fcos-screenshot" src="https://davy.page/assets/images/fcos-screenshot-19f25aff12361e9558cc536bb8507a67.png" width="1560" height="671" class="img_ev3q"></p></div>
<p>Почему вообще OS может называться оптимальной для контейнеров? Надо понимать, что для их запуска потребуется всего две вещи:</p>
<ul>
<li>Linux, потому что, будем честны, запускать контейнеризованные приложения на Windows — это не то, чем вы хотите заниматься;</li>
<li>Платформа для запуска контейнеров, например, docker или podman.</li>
</ul>
<p>Помимо этого сама система должна быть достаточно защищена и протестирована, чтобы во время нагрузки не всплыли неожиданные сюрпризы.</p>
<p>Fedora CoreOS зачастую используется для запуска Kubernetes кластеров. Собственно, для этого и была разработана. FCOS редко когда используют для того, чтобы запускать единичные контейнеры. Это основная система для OKD, а также апстрим для RHEL CoreOS, которая является дефолтной для OpenShift.</p>
<p>Теперь рассмотрим, какие основные фичи имеет FCOS, и подумаем, как они смогут облегчить нам жизнь в работе с контейнеризованными приложениями.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="иммутабельная-система-и-транзакционные-обновления">Иммутабельная система и транзакционные обновления<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B8%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D0%B1%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-%D0%B8-%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F" class="hash-link" aria-label="Прямая ссылка на Иммутабельная система и транзакционные обновления" title="Прямая ссылка на Иммутабельная система и транзакционные обновления">​</a></h2>
<p>Начну с самой интересной, на мой взгляд, особенности. FCOS использует систему <a href="https://coreos.github.io/rpm-ostree/" target="_blank" rel="noopener noreferrer">rpm-ostree</a>. Это своего рода git для вашей операционки. Разберемся подробнее, что это такое.</p>
<p>В основе лежит <a href="https://ostreedev.github.io/ostree/" target="_blank" rel="noopener noreferrer">ostree</a> — система контроля обновлений операционной системы, очень похожая на git. Вот как она работает. У вас есть базовый образ ОС, к примеру, последняя стабильная версия. Вам нужно установить на нее нужное программное обеспечение и сконфигурировать его. Вы это выполняете, тестируете и коммитите изменения. Тем самым вы делаете их резистентными к перезагрузкам системы, так как установленное, но незакомиченное ПО будет слетать после каждого ребута.</p>
<p>Если вас что-то не устроит в изменениях, вы сможете в любой момент откатиться до предыдущих. Более того, вы сможете использовать этот же репозиторий и на других машинах, которые будут стягивать коммиты по мере их появления. Разумеется, с возможностью откатиться до предыдущей версии, если что-то пошло не так. Тем самым можно централизовать управление обновлениями на большом количестве машин.</p>
<p>Обновления в ostree происходят транзакционно: последние два-три образа системы хранятся на диске. Именно за счет этого и можно быстро откатиться на них.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="ostree-scheme" src="https://davy.page/assets/images/ostree-scheme-50f36008cd92700c442ea10f6487f653.png" width="909" height="1052" class="img_ev3q"></p></div>
<p>А почему просто не использовать git? Зачем эта git-подобная система? Дело в том, что git отслеживает далеко не все. К примеру, без его внимания остаются метаданные файлов: права, владелец, дата создания и т. д. Для git все это — user specific data, которая ему не нужна.</p>
<p>А теперь вернемся к rpm-ostree. Она дополняет ostree, встраивая пакетный менеджер dnf. По итогу мы получаем image-based систему с гибкостью package-based системы. Rpm-ostree позволяет наслаивать установленные юзером пакеты на базовый образ. То есть их установка через rpm-ostree создает новый коммит в ostree-дерево. Таким образом, поддерживается так называемый client-side layering. Соответственно, когда у вас появится новая версия базового образа и вы хотите до нее обновиться, вы, можно сказать, делаете <code>git rebase</code>. :)</p>
<p>Изначально rpm-ostree проектировалась именно для поддержки удобного client-side layering, но сейчас все стало сложнее. Теперь система реализует ряд других полезных функций. Например, во время установки пакетов она изолирует запускаемые скрипты в контейнерах, используя утилиту <a href="https://github.com/containers/bubblewrap/" target="_blank" rel="noopener noreferrer">bubblewrap</a>, чтобы они не влияли на работающую систему. Также поддерживается функционал native containers, который позволяет собирать базовый образ системы через Docker-файлы (подробнее об этом — чуть ниже).</p>
<p>Если ostree считается иммутабельной системой больше из-за ее принципа обновления, то rpm-ostree к этому добавила почти полностью read-only файловую систему. Вносить изменения вы можете только в <code>/etc</code> или <code>/run</code>, в которых хранятся конфигурационные файлы, а также в <code>/var</code>, в котором находятся все остальные данные приложений.</p>
<p>Вот что происходит с файлами внутри этих директорий при обновлении системы:</p>
<ul>
<li><code>/run</code> приводится в первоначальное состояние, не сохраняя пользовательских изменений или добавленных юзером файлов с прошлого запуска. Оно и понятно, эта директория предназначена для добавления конфигурационных файлов, относящихся только к текущему запуску системы;</li>
<li><code>/etc</code> будет принимать новые изменения от обновлений (если они есть), но в то же время не будет трогать пользовательские изменения;</li>
<li><code>/var</code> никак не меняется.</li>
</ul>
<blockquote>
<p>Привычные директории типа <code>/home</code> — это симлинки на <code>/var/home</code>.</p>
</blockquote>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="автоматические-background-обновления">Автоматические background-обновления<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5-background-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F" class="hash-link" aria-label="Прямая ссылка на Автоматические background-обновления" title="Прямая ссыл�ка на Автоматические background-обновления">​</a></h2>
<p>Система rpm-ostree позволяет организовать транзакционные обновления в фоновом режиме. То есть когда появляется обновление, система об этом узнает и устанавливает его. После перезапуска будет использован новый образ.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="fcos-autoupdate-scheme" src="https://davy.page/assets/images/fcos-autoupdate-scheme-46c072c5cc1b1a9bfeb75d21fe5d98a6.png" width="1062" height="1076" class="img_ev3q"></p></div>
<p>По дефолту FCOS поставляется с запущенным приложением-демоном <a href="https://coreos.github.io/zincati/" target="_blank" rel="noopener noreferrer">Zincati</a>. Оно отвечает за автоматические обновления и перезапуски системы. Zincati узнает о доступных апдейтах с помощью удаленного сервера <a href="https://github.com/openshift/cincinnati" target="_blank" rel="noopener noreferrer">Cincinnati</a>, периодически запрашивая у него информацию. Cincinnati, можно сказать, подписывается на нужный образ системы и по запросу предоставляет граф обновлений. По нему и проходится Zincati (пример: <a href="https://builds.coreos.fedoraproject.org/graph?stream=stable%26basearch=x86_64" target="_blank" rel="noopener noreferrer">FCOS Updates Graph</a>).</p>
<p>Так как перезапуск системы — действие, которое теоретически может поломать (пусть даже временно) работу всего кластера, Zincati поддерживает несколько стратегий обновления:</p>
<ul>
<li>Immediate (default) — перезагружает систему сразу после установки обновления;</li>
<li>FleetLock — использует стороннее решение, которое устанавливает максимальное количество одновременно обновляющихся машин. Машина пошла обновляться — забрала замочек, обновилась — отдала. Если замков нет, она ждет, когда появятся;</li>
<li>Periodic — позволяет указать конкретные временные окна, в которые система должна перезагружаться. Например, 29 мая в 10 утра.</li>
</ul>
<p>По информации с форума Fedora Project, команда Fedora планирует упростить этот процесс и убрать из схемы Cincinati. Разработчикам кажется, что сейчас процесс излишне усложнен. Планируется оставить только Zincati, предварительно улучшив его и сделав умнее.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="zincati-forum-screen" src="https://davy.page/assets/images/zincati-forum-screen-96a3dcf884b10eef1aaf471397cc528e.png" width="1560" height="646" class="img_ev3q"></p></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="запуск-системы-на-основе-контейнер-образа">Запуск системы на основе контейнер-образа<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B-%D0%BD%D0%B0-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5-%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80-%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%B0" class="hash-link" aria-label="Прямая ссылка на Запуск системы на основе контейнер-образа" title="Прямая ссылка на Запу�ск системы на основе контейнер-образа">​</a></h2>
<p>Система rpm-ostree наследует часть кода библиотеки <a href="https://github.com/ostreedev/ostree-rs-ext/" target="_blank" rel="noopener noreferrer">ostree-rs-ext</a>, которая реализует функционал ostree native containers. Он позволяет создавать базовый образ системы на основе Docker-файлов.</p>
<p>Примеры:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"># Перемещение библиотек, установленных в /opt (симлинк на /var/opt), в /usr</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">FROM quay.io/fedora/fedora-coreos:testing-devel</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RUN mkdir /var/opt &amp;&amp; \</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    rpm -Uvh https://downloads.linux.hpe.com/repo/stk/rhel/7/x86_64/current/hp-scripting-tools-11.60-20.rhel7.x86_64.rpm &amp;&amp; \</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    mv /var/opt/hp/ /usr/lib/hp &amp;&amp; \</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    echo 'L /opt/hp - - - - ../../usr/lib/hp' &gt; /usr/lib/tmpfiles.d/hp.conf &amp;&amp; \</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    ostree container commit</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"># Установка пакетов</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">FROM quay.io/fedora/fedora-coreos:stable</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RUN rpm-ostree install kubernetes-client &amp;&amp; ostree container commit</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"># Изменение boolean значения SELinux</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">FROM quay.io/fedora/fedora-coreos:stable</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RUN setsebool -P -N container_manage_cgroup 1</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Чтобы использовать в системе «сбилженный» и опубликованный базовый образ, достаточно выполнить rebase системы (<code>rpm-ostree rebase ostree-unverified-registry:REGISTRY/IMAGE:VERSION</code>) и перезапуститься.</p>
<p>Дополнительную информацию по этой теме вы можете найти в <a href="https://coreos.github.io/rpm-ostree/container/" target="_blank" rel="noopener noreferrer">документации</a>, а больше примеров — на <a href="https://github.com/coreos/layering-examples" target="_blank" rel="noopener noreferrer">GitHub</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="безопасность">Безопасность<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C" class="hash-link" aria-label="Прямая ссылка на Безопасность" title="Прямая ссылка на Безопасность">​</a></h2>
<p>В целом из статьи понятны некоторые security-фичи, которые вытекают из факта использования rpm-ostree системы. Вот они:</p>
<ul>
<li>Иммутабельная файловая система;</li>
<li>Изоляция скриптов, запускаемых при установке пакетов, в контейнеры;</li>
<li>Ограниченный и контролируемый список установленных пакетов в базовом образе;</li>
<li>Автообновления.</li>
</ul>
<p>Отмечу, что один из фокусов команды Fedora заключается в том, чтобы сделать FCOS сконфигурированной по дефолту со всеми нужными политиками безопасности. Это необходимо для исключения ситуации, когда пользователь на старте может выбрать путь небезопасно настроенной системы.</p>
<p>Именно поэтому FCOS идет с предварительно установленным и настроенным SELinux. Правда, в базовом образе операционки не установлены некоторые дополнительные программы для него типа semanage, так как они зависят от python, которого в FCOS нет (по поводу зависимостей от python есть <a href="https://github.com/coreos/fedora-coreos-tracker/issues/126" target="_blank" rel="noopener noreferrer">отдельная дискуссия на GitHub</a>). Из-за этого управлять политиками SELinux может быть затруднительно, но вы все равно можете скомпилировать свои модули и установить их в систему.</p>
<p>Если вам все же нужен semanage, установите его вместе с питоном, используя пакет <code>policycoreutils-python-utils</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> rpm-ostree </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> policycoreutils-python-utils </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token plain">. </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Added:</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  checkpolicy-3.5-3.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  libb2-0.98.1-9.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  libgomp-13.2.1-7.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  mpdecimal-2.5.1-7.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  policycoreutils-python-utils-3.5-8.fc39.noarch </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python-pip-wheel-23.2.1-2.fc39.noarch </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python-unversioned-command-3.12.3-2.fc39.noarch </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-3.12.3-2.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-audit-3.1.2-8.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-distro-1.8.0-6.fc39.noarch </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-libs-3.12.3-2.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-libselinux-3.5-5.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-libsemanage-3.5-4.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-policycoreutils-3.5-8.fc39.noarch </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-setools-4.4.3-1.fc39.x86_64 </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  python3-setuptools-67.7.2-7.fc39.noarch</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Так как мы все-таки говорим о container optimized системе, отмечу следующее. Благодаря политикам SELinux в FCOS есть дополнительная изоляция контейнеров от хоста. Ниже приведены примеры на данный момент уже закрытых с помощью SELinux дыр в безопасности runc:</p>
<ul>
<li><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5736" target="_blank" rel="noopener noreferrer">https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5736</a></li>
<li><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=2021-30465" target="_blank" rel="noopener noreferrer">https://cve.mitre.org/cgi-bin/cvename.cgi?name=2021-30465</a></li>
</ul>
<p>Сама система в целом рассчитана на то, что большая часть юзер-софта будет запускаться в контейнерах. В сочетании с политиками SELinux это дает плюсик к безопасности.</p>
<p>Кстати, часто дыры в этой самой безопасности связаны с неправильным использованием памяти. Это так называемые «memory safety issues». Чтобы уменьшить количество связанных с ними багов, команда Fedora старается все чаще использовать в кодовой базе своих приложений языки Rust и Go.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="предустановленные-инструменты-для-контейнеров">Предустановленные инструменты для контейнеров<a href="https://davy.page/why-fcos-is-container-optimized#%D0%BF%D1%80%D0%B5%D0%B4%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%BE%D0%B2" class="hash-link" aria-label="Прямая ссылка на Предустановленные инструменты для контейнеров" title="Прямая ссылка на Предустановленные инструменты для контейнеров">​</a></h2>
<p>В FCOS из коробки идут podman и moby-engine (docker). А зачем их два? Одновременно запускать контейнеры и в одном, и в другом не получится — это вызовет конфликты, да и смысла нет. Разработчики FCOS оставляют moby-engine только ради удобства пользователей, которым привычнее работать с docker cli. Цитата с недавней встречи разработчиков:</p>
<blockquote>
<p>«When we started building Fedora CoreOS one of the things we wanted to do was keep Container Linux users happy. Users who wanted to continue to use docker could do so without issue. We've held to that principle for a long time. I would like to continue to ship it because I know there are good number of people who do use it».</p>
</blockquote>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Очень вольный перевод</summary><div><div class="collapsibleContent_i85q"><blockquote>
<p>Когда мы начинали создавать Fedora CoreOS, мы хотели, чтобы пользователи Container Linux (предшественник Fedora CoreOS) были довольны. Чтобы пользователи, которые хотели продолжать использовать Docker, могли бы делать это без проблем. Мы следовали этому принципу на протяжении длительного времени. Я хотел бы продолжить эту практику, потому что знаю, что многие люди используют Docker.</p>
</blockquote></div></div></details>
<p>Кстати, на этой встрече как раз обсуждалась идея выпиливания moby-engine из базового образа FCOS (подробности <a href="https://github.com/coreos/fedora-coreos-tracker/issues/1723" target="_blank" rel="noopener noreferrer">на GitHub</a>). Основным мотивом была нехватка волонтеров и мейнтейнеров в команде Fedora. Именно из-за нее версия moby-engine в стабильной FCOS на момент написания статьи — 24.0.5, когда для docker-ce доступна версия 26.1.2.</p>
<p>Кроме того, иногда в рамках одного обновления FCOS происходят большие скачки версии moby-engine. Например, так было в переходе с версии 38.20231027.3.2 на 39.20231101.3.0: moby-engine подняли сразу с 20.10.23 до 24.0.5. По итогу этой встречи в документацию решили добавить <a href="https://github.com/coreos/fedora-coreos-docs/pull/641/files" target="_blank" rel="noopener noreferrer">инструкцию</a> по замене moby-engine на docker-ce.</p>
<p>Сейчас, насколько я понимаю по <a href="https://src.fedoraproject.org/rpms/moby-engine/pull-request/21" target="_blank" rel="noopener noreferrer">репозиторию</a>, идет работа по обновлению пакета moby-engine до 26.0.0. Но когда этот переход произойдет, неизвестно.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="гибкий-деплой">Гибкий деплой<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B3%D0%B8%D0%B1%D0%BA%D0%B8%D0%B9-%D0%B4%D0%B5%D0%BF%D0%BB%D0%BE%D0%B9" class="hash-link" aria-label="Прямая ссылка на Гибкий деплой" title="Прямая ссылка на Г�ибкий деплой">​</a></h2>
<p>FCOS доступен для установки, по сути, на все платформы, которые вам только могут понадобиться. На ту же виртуалку в Selectel его можно установить с помощью образа для OpenStack.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="fcos-download" src="https://davy.page/assets/images/fcos-download-1e2268414f7ec67794a216e5fee9ea52.png" width="1288" height="1276" class="img_ev3q"></p></div>
<p>Предварительно сконфигурировать систему во время первого запуска можно с помощью Ignition-конфигурации. Ignition — это машиночитаемый формат, который можно скормить системе при первом запуске, как Cloud-Init, и она примет вид, описанный в файле. В свою очередь, Ignition-конфигурация формируется путем транспиляции файла в формате <a href="https://coreos.github.io/butane/getting-started/" target="_blank" rel="noopener noreferrer">Butane</a>. Butane — это YAML-файлы, данные в которых описаны человекочитаемой <a href="https://coreos.github.io/butane/config-fcos-v1_5/" target="_blank" rel="noopener noreferrer">Butane-схемой</a>.</p>
<p>Соответственно, в файлах Butane вы описываете желаемый вид вашей системы. Вот небольшой пример Butane-конфигурации, которая добавляет юзера с ssh-ключом, создает сетевой интерфейс, указывает hostname и отключает Zincati:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">variant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> fcos</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">version</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> 1.5.0</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">passwd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> core</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ssh_authorized_keys</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> ssh</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">ed25519 AA</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">storage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">files</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /etc/NetworkManager/system</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">connections/ens3.nmconnection</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">mode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0600</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">contents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">inline</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token scalar string" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          [connection]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          id=ens3</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          type=ethernet</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          interface-name=ens3</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          [ipv4]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          address1=192.168.0.3/24,192.168.0.1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          dns=8.8.8.8;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          dns-search=</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          may-fail=false</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token scalar string" style="color:hsl(95, 38%, 62%)">          method=manual</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /etc/hostname</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">mode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0644</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">contents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">inline</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> fcos</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">systemd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">units</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> zincati.service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">enabled</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:hsl(220, 14%, 71%);font-weight:bold">false</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="заключение">Заключение<a href="https://davy.page/why-fcos-is-container-optimized#%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5" class="hash-link" aria-label="Прямая ссылка на Заключение" title="Прямая ссылка на Заключение">​</a></h2>
<p>Возвращаемся к вопросу, который и стал причиной написания этой статьи: почему Fedora CoreOS — это оптимальная ОС для контейнеров?</p>
<p>В целом все описанные выше фичи FCOS способствуют тому, чтобы ее можно было просто и удобно использовать для работы с контейнерами. В первую очередь, как основную систему для узлов Kubernetes-кластера. Коробочное решение защищено с помощью политик SELinux, система невелика с точки зрения количества пакетов, в ней предустановлены две протестированные платформы для запуска контейнеров: moby-engine и podman.</p>
<p>Последний пункт, кстати, в этой статье я называл одним из минимальных требований к «оптимальной» для контейнеров ОС. Но во время своих поисков я наткнулся <a href="https://github.com/coreos/fedora-coreos-tracker/issues/1723%23issuecomment-2090120339" target="_blank" rel="noopener noreferrer">на этот занятный комментарий</a> одного из разработчиков CoreOS в треде про удаление moby-engine. Он говорит, что они хотели бы выпустить версию FCOS вообще без предустановленного container engine, чтобы юзеры сами могли выбрать, какой им нужен. Можно ли считать такой образ FCOS «container optimized»? Я думаю да, если доступные rpm-пакеты всех возможных container-платформ будут протестированы для него. ¯(ツ)/¯</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="fcos-dev-comment" src="https://davy.page/assets/images/fcos-dev-comment-e07b05b2ed31087954bcdca2c3be3e62.png" width="1560" height="476" class="img_ev3q"></p></div>]]></content:encoded>
            <category>linux</category>
            <category>fedora</category>
            <category>fcos</category>
            <category>kubernetes</category>
            <category>docker</category>
        </item>
        <item>
            <title><![CDATA[CPU планировщики в Linux]]></title>
            <link>https://davy.page/linux-cpu-schedulers</link>
            <guid>https://davy.page/linux-cpu-schedulers</guid>
            <pubDate>Sun, 14 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[В статье будет рассказано про основные алгоритмы, которые ядро Linux использует для планирования задач, готовых к выполнению. Как влияет приоритет задач и указанная для неё политика на то, как она будет получать процессорное время и сколько.]]></description>
            <content:encoded><![CDATA[<p>В статье будет рассказано про основные алгоритмы, которые ядро Linux использует для планирования задач, готовых к выполнению. Как влияет приоритет задач и указанная для неё политика на то, как она будет получать процессорное время и сколько.</p>
<p>Сразу хочется оговориться, что помимо описанных ниже алгоритмов и классов планирования в Linux также реализованы дополнительные алгоритмы, основывающиеся на <a href="https://docs.kernel.org/scheduler/sched-energy.html" target="_blank" rel="noopener noreferrer">энергопотреблении системы</a>, на <a href="https://docs.kernel.org/scheduler/sched-capacity.html" target="_blank" rel="noopener noreferrer">cpu capacity</a> и тд. Они встроены в классы, о которых поговорим ниже, но их самих мы затрагивать в рамках этой статьи не будем.</p>
<p><img decoding="async" loading="lazy" alt="CPU.png" src="https://davy.page/assets/images/CPU-linux-sched-7b6d6aabf1502fd3a3db35390f7f2a08.png" width="2715" height="1104" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/807645/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/807645/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="понятия-задачи-task-потока-thread-и-процесса-process">Понятия задачи (task), потока (thread) и процесса (process)<a href="https://davy.page/linux-cpu-schedulers#%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8-task-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B0-thread-%D0%B8-%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%B0-process" class="hash-link" aria-label="Прямая ссылка на Понятия задачи (task), потока (thread) и процесса (process)" title="Прямая ссылка на Понятия задачи (task), потока (thread) и процесса (process)">​</a></h2>
<p>Начнем с базы. Task, thread и process – это, в принципе, достаточно близкие по смыслу понятия, но надо всё-таки разобраться, что каждое из них значит.</p>
<p>Когда вы запускаете приложение, в системе создаётся процесс (process), которому выделяется память на хранение исполняемого кода и других данных. В рамках этого процесса создаётся минимум один поток (thread). Именно среди потоков планировщики Linux и распределяют время процессора, а также решают, в какой очерёдности они будут выполняться. Задачей (task) можно назвать уже непосредственно сами инструкции, которые процессор получает и выполняет. Дальше по статье я буду время от времени называть потоки задачами или процессами, потому что в рамках контекста статьи они своего рода синонимы.</p>
<p>Важно также знать, что у процессов есть поле <code>state</code>, которое, как понятно по названию, показывает, в каком состоянии сейчас находится процесс. Состояний может быть несколько:</p>
<ul>
<li>Running или Runnable (R) – процесс в состоянии running прямо сейчас использует процессорное время, в свою очередь runnable процесс только ожидает его.</li>
<li>Uninterruptible Sleep (D) – процесс ждёт результата операции ввода-вывода. Например, ждёт данные от диска. Такой процесс никак нельзя убить.</li>
<li>Interruptible Sleep (S) – процесс ждёт какое-то событие и не потребляет процессорного времени. Пример: ввод из командной строки.</li>
<li>Stopped (T) – процесс получил сигнал <code>SIGSTOP</code> или <code>SIGTSTP</code> и остановил свою работу. В этом состоянии процессу можно послать сигнал <code>SIGCONT</code> и запустить его снова.</li>
<li>Zombie (Z) – процесс, который получил сигналы на завершение работы, и полностью её завершил – он больше не потребляет ресурсов системы, только PID идентификатор. Он ждет, когда его родительский процесс выполнит системный вызов <code>wait</code>, после этого Zombie исчезнет. Иногда этого может не происходить, в таком случае приходится дебажить родителя.</li>
</ul>
<p>Всю информации о процессе можно достать из папки <code>/proc/&lt;PID&gt;</code>, где <code>&lt;PID&gt;</code> – это идентификатор процесса. Если вам нужно получить информацию в более “user friendly” виде, то воспользуйтесь утилитами <code>top</code>, <code>htop</code>, <code>ps</code> и тд.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="политики-и-классы">Политики и классы<a href="https://davy.page/linux-cpu-schedulers#%D0%BF%D0%BE%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B8-%D0%B8-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D1%8B" class="hash-link" aria-label="Прямая ссылка на Политики и классы" title="Прямая ссылка на Политики и классы">​</a></h2>
<p>У каждой задачи выставлена какая-то политика, которая определяет, как именно нужно планировать выполнение этой задачи, какие алгоритмы для этого использовать. В свою очередь классы это, по сути, реализации этих политик. Не у каждой политики есть свой личный класс, но все они реализованы в рамках какого либо класса. К примеру, в <code>rt_sched_class</code> реализованы 2 политики: <code>SCHED_FIFO</code> и <code>SCHED_RR</code>, а в <code>dl_sched_class</code> – только <code>SCHED_DEADLINE</code>.</p>
<p>Политика задачи определяется её приоритетом <code>sched_priority</code>, его можно найти в файле <code>/proc/&lt;PID&gt;/schedstat</code>. Сопоставляются приоритеты с классами следующим образом:</p>
<ul>
<li><code>sched_priority == 0</code> – класс "Deadline"</li>
<li><code>sched_priority &gt;= 1 &amp;&amp; sched_priority &lt;= 99</code> – класс "Real-Time"</li>
<li><code>sched_priority &gt;= 100</code> – класс "Fair"</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="класс-для-обычных-задач">Класс для “обычных” задач<a href="https://davy.page/linux-cpu-schedulers#%D0%BA%D0%BB%D0%B0%D1%81%D1%81-%D0%B4%D0%BB%D1%8F-%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D1%8B%D1%85-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87" class="hash-link" aria-label="Прямая ссылка на Класс для “обычных” задач" title="Прямая ссылка на Класс для “обычных” задач">​</a></h2>
<p>За распределение процессорного времени для задач с политиками <code>SCHED_OTHER</code>, <code>SCHED_BATCH</code> и <code>SCHED_IDLE</code> отвечает <code>fair_sched_class</code>, описанный в файле <a href="https://github.com/torvalds/linux/blob/ff9c18e435b042596c9d48badac7488e3fa76a55/kernel/sched/fair.c" target="_blank" rel="noopener noreferrer">kernel/sched/fair.c</a>. В нём с 2007 по 2023 год (с версии 2.6.23 до версии 6.6) использовался алгоритм "Completely Fair Scheduler" CFS, сейчас же это "Earliest Eligible Virtual Deadline First" EEVDF.</p>
<p>У “обычных” задач поле priority игнорируется, вместо него есть <code>NICE</code>, которое играет роль в планировании.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p><code>NICE</code> – это показатель толерантности потока к другим потокам :). Чем это значение выше, тем охотнее поток будет делиться процессорным временем или своей очередью (зависит от планировщика, об этом ниже). Минимальное значение -20, максимальное +19.</p></div></div>
<p>Про политики:</p>
<ul>
<li><code>SCHED_OTHER</code> – Дефолтная политика, используется для абсолютного большинства задач.</li>
<li><code>SCHED_BATCH</code> – Тоже самое, что и <code>SCHED_OTHER</code>, только <a href="https://github.com/torvalds/linux/blob/ff9c18e435b042596c9d48badac7488e3fa76a55/kernel/sched/fair.c#L8322" target="_blank" rel="noopener noreferrer">они не могут “смещать”</a> другие (не SCHED_IDLE), уже запущенные задачи.</li>
<li><code>SCHED_IDLE</code> – Используется для задач с самым низким приоритетом, ещё ниже чем <code>NICE</code> +19. В теории такие задачи запускаются только когда в очереди нет других задач. <a href="https://lwn.net/Articles/805317/" target="_blank" rel="noopener noreferrer">На практике же может быть и такое, когда IDLE задача выполняется вместе с <code>SCHED_OTHER</code> задачей, однако при этом получает слишком мало процессорного времени.</a></li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="completely-fair-scheduler-cfs">"Completely Fair Scheduler” CFS<a href="https://davy.page/linux-cpu-schedulers#completely-fair-scheduler-cfs" class="hash-link" aria-label="Прямая ссылка на &quot;Completely Fair Scheduler” CFS" title="Прямая ссылка на &quot;Completely Fair Scheduler” CFS">​</a></h3>
<p>Как можно понять по имени, основная цель планировщика CFS это максимально “честное” распределение процессорного времени среди всех требующих его процессов. CFS это, <a href="https://docs.kernel.org/scheduler/sched-design-CFS.html" target="_blank" rel="noopener noreferrer">как нам говорит документация linux</a>, моделирование “идеального многозадачного CPU”, который, если бы существовал, распределял время процессора примерно так: два <code>runnable</code> процесса, каждый получает по 50% процессорного времени.</p>
<p>В CFS все <code>runnable</code> процессы хранятся в red-black дереве, которое отсортировано по <code>vruntime</code> процесса, что является количеством процессорного времени в наносекундах, которое процесс использовал. Таким образом получается, что в левой части дерева находятся процессы, которые использовали меньше всего времени, а в правой части те, что больше всего. И когда CFS выбирает, какой задаче дать доступ к процессорному времени, он выбирает самую левую задачу в дереве, то-есть ту, которая получила его меньше всех.</p>
<p><img decoding="async" loading="lazy" alt="Пример red-black дерева" src="https://davy.page/assets/images/rb_tree-cc3ff479d6a17a4785ff8128864399e5.png" width="1343" height="658" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Так как любая операция над red-black деревом имеет сложность O(log n), то и сам алгоритм CFS имеет такую же. Однако CFS использует <a href="https://www.kernel.org/doc/html/v5.10/core-api/rbtree.html#cached-rbtrees" target="_blank" rel="noopener noreferrer">немного модифицированную реализацию этого дерева</a>, которая также хранит указатель на самую левую ноду. Поэтому для поиска процесса с наименьшим <code>vruntime</code> сложность будет O(1).</p></div></div>
<p>Когда задача получает доступ к процессорному времени, она получает его на заранее предопределённый промежуток времени, называемый <code>slice</code>. Он может увеличиваться и уменьшаться в зависимости от <code>NICE</code> значения процесса. Таким образом, к примеру, чем меньше значение <code>NICE</code>, тем больше процессорного времени получит задача по сравнению с задачами, имеющими более высокое значение.</p>
<p>Несмотря на то, что CFS действительно хорошо справлялся с “честным” распределением времени процессора на все <code>runnable</code> процессы, у него были и серьёзные недостатки. Один из них это невозможность правильно работать с процессами, которые требуют время процессора, как можно скорее. Для того, чтобы подружить CFS с этой историей были внедрены так называемые <a href="https://lwn.net/Articles/887842/" target="_blank" rel="noopener noreferrer">latency nice патчи</a>. Они добавляли новое значение <code>latency-nice</code>, которое было зеркально существующему <code>nice</code> значению, в том плане, что тоже имело ограничение от -20 до +19 и его понижение также, как и у <code>nice</code>, понижало толерантность к другим процессам. Если у нового процесса <code>latency-nice</code> был ниже, чем у того, который в текущее время работает в процессоре, то он мог заменить его. Таким образом задачи с низким <code>latency-nice</code> не получали больше процессорного времени, но получали право на его более быстрое выделение.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="earliest-eligible-virtual-deadline-first-eevdf">"Earliest Eligible Virtual Deadline First" EEVDF<a href="https://davy.page/linux-cpu-schedulers#earliest-eligible-virtual-deadline-first-eevdf" class="hash-link" aria-label="Прямая ссылка на &quot;Earliest Eligible Virtual Deadline First&quot; EEVDF" title="Прямая ссылка на &quot;Earliest Eligible Virtual Deadline First&quot; EEVDF">​</a></h3>
<p><a href="https://lwn.net/ml/linux-kernel/20230306132521.968182689@infradead.org/#t" target="_blank" rel="noopener noreferrer">Peter Zijlstra посчитал</a>, что для решения той же проблемы, что решают <code>latency-nice</code> патчи для CFS, есть более подходящий путь. Он предположил, что использование алгоритма EEVDF, <a href="https://citeseerx.ist.psu.edu/document?repid=rep1&amp;type=pdf&amp;doi=805acf7726282721504c8f00575d91ebfd750564" target="_blank" rel="noopener noreferrer">представленного ещё в 1995 году</a>, может больше подходить для этого и избавит планировщик от кучи «icky heuristics code» (полагаю, что по-русски это значит «говнокод»).</p>
<p>По названию этого алгоритма можно примерно догадаться, как он работает :). Процессору он отдаёт ту задачу, которая “имеет на это право” и у которой раньше всех наступает deadline. В принципе на этом всё. Только осталось разобраться, что вообще значит “имеет право”, и как рассчитывается этот загадочный deadline.</p>
<p>Начнём с параметра “eligible”. Имеет право или не имеет право определяется функцией <code>vruntime_eligible</code> в файле <a href="https://github.com/torvalds/linux/blob/master/kernel/sched/fair.c" target="_blank" rel="noopener noreferrer">kernel/sched/fair.c</a>, в комментарии к которой написано: “Entity is eligible once it received less service than it ought to have, eg. lag &gt;= 0”. То есть задача “eligible” тогда и только тогда, когда она получила меньше процессорного времени, чем должна. В пример приводится неравенство <code>lag ≥ 0</code>, которое собственно это и значит, потому что <code>lag</code> – это разница между временем, что задача должна была получить, и тем, что она на текущий момент получила. Как это считается? Мы берём средний <code>vruntime</code> всей очереди и отнимаем от него <code>vruntime</code> задачи. Важно понимать, что и средний <code>vruntime</code> очереди и <code>vruntime</code> отдельной задачи у нас считаются, учитывая веса задач, которыми являются их <code>NICE</code> значения. Таким образом, благодаря механизму “eligibility” среди всех процессов “честно” распределяется время.</p>
<p>Теперь перейдём к понятию “deadline”. Deadline – это самое раннее время, до которого задача должна получить <code>slice</code> своего процессорного времени. Считается по формуле: <code>vruntime + (slice / weight)</code>, соответственно чем больше вес задачи (зависит от <code>NICE</code>), тем раньше её deadline.</p>
<p>Все runnable процессы так же, как и в CFS хранятся в red-black дереве, однако отсортировано оно не по <code>vruntime</code>, а по deadline’у. Само дерево является “augmented”, то есть дополненным, и содержит в своих узлах не только deadline процесса, но и остальные его данные (в CFS также), в том числе и <code>min_vruntime</code>, который считается по формуле <code>se-&gt;min_vruntime = min(se-&gt;vruntime, se-&gt;{left,right}-&gt;min_vruntime)</code>. Таким образом появляется возможность фильтровать дерево по “eligibility” и затем уже выбирать самый левый узел, то есть процесс с самым близким deadline’ом.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="класс-для-real-time-задач">Класс для Real-Time задач<a href="https://davy.page/linux-cpu-schedulers#%D0%BA%D0%BB%D0%B0%D1%81%D1%81-%D0%B4%D0%BB%D1%8F-real-time-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87" class="hash-link" aria-label="Прямая ссылка на Класс для Real-Time задач" title="Прямая ссылка на Класс для Real-Time задач">​</a></h2>
<p><code>rt_sched_class</code>, описанный в файле <a href="https://github.com/torvalds/linux/blob/master/kernel/sched/rt.c" target="_blank" rel="noopener noreferrer">kernel/sched/rt.c</a>, распределяет процессорное время для задач с политиками: <code>SCHED_FIFO</code>, <code>SCHED_RR</code> – обе эти политики описаны в стандарте POSIX. Значение <code>NICE</code> у задач роли не играет, берётся во внимание только приоритет.</p>
<p><code>SCHED_FIFO</code> (FIFO – First In First Out) берёт задачу с самым большим приоритетом и отдаёт на выполнение в процессор, пока она не заблокируется, не закончит своё выполнение или не будет смещена более приоритетной задачей.</p>
<p>Для <code>SCHED_RR</code> (RR – Round-Robin) справедливо всё то, что и для <code>SCHED_FIFO</code>, за исключением того, что он не позволяет задачам исполняться в процессоре “до победного”, ограничивая время их исполнения. Таким образом, задача, время выполнения которой больше или равно отведённому ей, будет отправлена в конец очереди для задач с таким же приоритетом.</p>
<p>Важно отметить, что так как Real-Time задачи имею больший приоритет, чем обычные, это приводит к тому, что любая новая <code>runnable</code> Real-Time задача смещает обычную <code>running</code> задачу (если такая есть, конечно).</p>
<p>Пользователю, для того, чтобы сделать какую-либу задачу “Real-Time”, нужно воспользоваться утилитой <code>chrt</code>.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrt </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-f</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-p</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2445</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Выставляем задаче с PID 2445 </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                   </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># политику SCHED_FIFO и приоритет 10</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrt </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-r</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"> your_command </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Выставляем задаче, выполняющей вашу команду, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                        </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># политику SCHED_RR и приоритет 10</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="класс-для-deadline-задач">Класс для Deadline задач<a href="https://davy.page/linux-cpu-schedulers#%D0%BA%D0%BB%D0%B0%D1%81%D1%81-%D0%B4%D0%BB%D1%8F-deadline-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87" class="hash-link" aria-label="Прямая ссылка на Класс для Deadline задач" title="Прямая ссылка на Класс для Deadline задач">​</a></h2>
<p><code>dl_sched_class</code>, описанный в файле <a href="https://github.com/torvalds/linux/blob/master/kernel/sched/rt.c" target="_blank" rel="noopener noreferrer">kernel/sched/deadline.c</a>, распределяет процессорное время для задач с политикой <code>SCHED_DEADLINE</code>, используя для этого в связке два алгоритма: EDF “Earliest Deadline First” и CBS “Constant Bandwidth Server”.  В этом классе у задач игнорируется приоритет и <code>NICE</code> значения, все задачи, благодаря CBS, выполняются “изолировано” друг от друга, то есть не пересекаются.</p>
<p>Deadline задачи имеют самый высокий приоритет среди всех остальных задач в пространстве пользователя. Таким образом, они могут замещать даже Real-Time задачи с самым высоким приоритетом.</p>
<p>В рамках этого класса у задачи есть 3 параметра: <code>runtime</code> определяет сколько процессорного времени задача будет получать, <code>period</code> определяет, за какой период он его получит, и <code>deadline</code>, который рассчитывается с помощью CBS, устанавливает крайнюю отметку времени, до которой задача может выполняться, для того, чтобы она не пересекалась с другими задачами. Алгоритм EDF, в свою очередь, использует значение <code>deadline</code> для понимания того, какую задачу отдавать на выполнение процессору, выбирая всегда процесс с самым ранним deadline’ом.</p>
<p><img decoding="async" loading="lazy" alt="Идеальный (не реальный) пример работы алгоритма из статьи https://lwn.net/Articles/743740/" src="https://davy.page/assets/images/deadline-sched-ed2c52ca1841fbe14d7510effb627bc0.png" width="1281" height="600" class="img_ev3q"></p>
<p>Чтобы задать процессу “deadline“ политику, пользователю, также, как и в случае с “Real-Time” политиками, нужно воспользоваться утилитой <code>chrt</code>, но теперь ей, помимо приоритета, который всегда 0 для “deadline” задач, необходимо также указать в наносекундах <code>period</code>, <code>runtime</code> и <code>deadline</code>.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># В этом примере задача будет иметь гарантированные 5мс процессорного времени</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># с периодом 16.6мс и с дедлайном 10мс</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrt </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-d</span><span class="token plain"> --sched-runtime </span><span class="token number" style="color:hsl(29, 54%, 61%)">5000000</span><span class="token plain"> --sched-deadline </span><span class="token number" style="color:hsl(29, 54%, 61%)">10000000</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    	    --sched-period </span><span class="token number" style="color:hsl(29, 54%, 61%)">16666666</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"> your_command</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<hr>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="источники">Источники<a href="https://davy.page/linux-cpu-schedulers#%D0%B8%D1%81%D1%82%D0%BE%D1%87%D0%BD%D0%B8%D0%BA%D0%B8" class="hash-link" aria-label="Прямая ссылка на Источники" title="Прямая ссылка на Источники">​</a></h2>
<ul>
<li><a href="https://lwn.net/Articles/743740/" target="_blank" rel="noopener noreferrer">https://lwn.net/Articles/743740/</a></li>
<li><a href="https://lwn.net/Articles/743946/" target="_blank" rel="noopener noreferrer">https://lwn.net/Articles/743946/</a></li>
<li><a href="https://docs.kernel.org/scheduler/sched-design-CFS.html?highlight=sched_fifo" target="_blank" rel="noopener noreferrer">https://docs.kernel.org/scheduler/sched-design-CFS.html</a></li>
<li><a href="https://docs.kernel.org/scheduler/sched-deadline.html" target="_blank" rel="noopener noreferrer">https://docs.kernel.org/scheduler/sched-deadline.html</a></li>
<li><a href="https://lwn.net/Articles/925371/" target="_blank" rel="noopener noreferrer">https://lwn.net/Articles/925371/</a></li>
<li><a href="https://lwn.net/ml/linux-kernel/20230306132521.968182689@infradead.org/" target="_blank" rel="noopener noreferrer">https://lwn.net/ml/linux-kernel/20230306132521.968182689@infradead.org/</a></li>
<li><a href="https://www.cs.unc.edu/~anderson/teach/comp790/papers/posix-rt.pdf" target="_blank" rel="noopener noreferrer">https://www.cs.unc.edu/~anderson/teach/comp790/papers/posix-rt.pdf</a></li>
<li><a href="https://lwn.net/Articles/805317/" target="_blank" rel="noopener noreferrer">https://lwn.net/Articles/805317/</a></li>
</ul>]]></content:encoded>
            <category>linux</category>
            <category>cpu</category>
        </item>
        <item>
            <title><![CDATA[Пробуем новый ЯП Pkl для создание манифестов Kubernetes]]></title>
            <link>https://davy.page/pkl-try</link>
            <guid>https://davy.page/pkl-try</guid>
            <pubDate>Wed, 28 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Не так давно Apple выпустили раннюю версию своего нового языка]]></description>
            <content:encoded><![CDATA[<p>Не так давно Apple выпустили раннюю версию своего нового языка
программирования специального назначения – Pkl,
предназначенного для написания конфигураций.
Несмотря на то, что этот язык, по сути, только родился, он уже способен
на некоторые интересные вещи. В этой статье опробуем Pkl путём
написания YAML манифестов для Kubernetes.</p>
<p><img decoding="async" loading="lazy" alt="Pkl" src="https://davy.page/assets/images/pkl-try-90226b8b606f6bfe148f20369bda53f9.png" width="3264" height="1731" class="img_ev3q"></p>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="что-такое-pkl">Что такое Pkl?<a href="https://davy.page/pkl-try#%D1%87%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-pkl" class="hash-link" aria-label="Прямая ссылка на Что такое Pkl?" title="Прямая ссылка на Что такое Pkl?">​</a></h2>
<p>Pkl (читается, как Pickle) – это, как я уже выше написал, ЯП
специального назначения для создания конфигураций.
Синтаксис напоминает HCL и Nginx, только с кучей вспомогательных функций.</p>
<p>Pkl поддерживает валидацию полей через проставленые типов, проверки
типа <code>if</code>, циклы, функции, наследование и GET http запросы.
Всё это в настолько примитивном виде, на сколько это возможно.</p>
<p>Перевести код на Pkl вы можете в JSON, YAML, XML <a href="https://pkl-lang.org/main/current/introduction/concepts.html#rendering" target="_blank" rel="noopener noreferrer">и другие форматы</a>.
Он также может генерировать код на Go, Java,
Kotlin и Swift, но в статьей это рассматривать не будем.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Пример</summary><div><div class="collapsibleContent_i85q"><div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">example.pkl</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Swallow"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">job</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">title</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Sr. Nest Maker"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">company</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Nests R Us"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">yearsOfExperience</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">example-output.json</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"name"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Swallow"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"job"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">"title"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Sr. Nest Maker"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">"company"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Nests R Us"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">"yearsOfExperience"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="манифесты-kubernetes-на-pkl">Манифесты Kubernetes на Pkl<a href="https://davy.page/pkl-try#%D0%BC%D0%B0%D0%BD%D0%B8%D1%84%D0%B5%D1%81%D1%82%D1%8B-kubernetes-%D0%BD%D0%B0-pkl" class="hash-link" aria-label="Прямая ссылка на Манифесты Kubernetes на Pkl" title="Прямая ссылка на Манифесты Kubernetes на Pkl">​</a></h2>
<p>Для примера я взял манифесты своего pet-проекта, которые
включают в себя <code>Deployment</code>, <code>Service</code> и <code>Ingress</code> ресурсы, и всё переписал на Pkl.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Deployment манифест</summary><div><div class="collapsibleContent_i85q"><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">deployment.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> apps/v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Deployment</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">selector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">template</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">containers</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">image</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> image</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain">v0.0.81</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">imagePullPolicy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> IfNotPresent</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">resources</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">readinessProbe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">livenessProbe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">imagePullSecrets</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> vault</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">registry</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">secret</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Service манифест</summary><div><div class="collapsibleContent_i85q"><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">service.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> ClusterIP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ports</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">targetPort</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> http</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">selector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Ingress манифест</summary><div><div class="collapsibleContent_i85q"><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">ingress.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> networking.k8s.io/v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Ingress</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">annotations</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">cert-manager.io/cluster-issuer</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"letsencrypt-prod"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ingressClassName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">tls</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hosts</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> davy.page</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">secretName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">tls</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">rules</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">host</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy.page</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">http</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">paths</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">pathType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Prefix</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">backend</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">number</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Основная задача заключалась в том, чтобы взять за основу текущие манифесты, которые
у меня использовались для поднятия одного стенда, и создать конфигурацию на Pkl, с помощью которой,
я смогу легко генерировать манифесты для трех разных окружений: <code>prod-type-1</code>, <code>prod-type-2</code> и <code>beta-(0..999)</code>.</p>
<p>Для валидации конфигов уже есть готовый
модуль <a href="https://github.com/apple/pkl-k8s/tree/main" target="_blank" rel="noopener noreferrer">pkl-k8s</a>. Он содержит в себе
типизированные объекты для ресурсов Kubernetes. Если вы будете добавлять в будущий k8s ресурс
поля, которых там не должно быть, или будете корректным полям выставлять некорректные значения, то при
сборке конфига получите ошибку.</p>
<p>По итогу у меня получился вот такой главный файл, который
создаёт необходимые манифесты для стендов любого типа:</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/K8sResource.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./DavyPageStand.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token property" style="color:hsl(355, 65%, 65%)">stand</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new DavyPageStand.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Stand</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Все аргументы, которые нужны берутся из ENV переменных.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если их вдруг нет, то выставится либо дефолтное значение, либо null.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> read?(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"env:TYPE"</span><span class="token plain">) ?? </span><span class="token string" style="color:hsl(95, 38%, 62%)">"blog"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">version</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> read?(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"env:VERSION"</span><span class="token plain">) ?? </span><span class="token string" style="color:hsl(95, 38%, 62%)">"v0.0.81"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">id</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> read?(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"env:ID"</span><span class="token plain">)</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">output</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">value</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new Listing&lt;K8sResource&gt; </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    stand.deployment</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    stand.service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    stand.ingress</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">renderer</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> (K8sResource.output.renderer as YamlRenderer) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">isStream</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Для гибкости, если вдруг нужно подредактировать, в полученных объектах, конкретные поля,
можно сделать так (в моём понимаение это костыль, и так
смысл есть делать, только если нужно прям супер срочно
что-то починить и нет желания смотреть другие Pkl файлы):</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">...</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token property" style="color:hsl(355, 65%, 65%)">value</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new Listing&lt;K8sResource&gt; </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  (stand.deployment) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">metadata</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"test"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">template</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">containers</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// меняем образ только у контейнера с таким именем</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">name </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy-page"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token property" style="color:hsl(355, 65%, 65%)">image</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"bruh"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  stand.service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  stand.ingress</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Конструкция <code>(object) { ... }</code> обнозначает наследование. Так можно накладывать на какой-то
существующий объект свои новые значения.</p>
<p>Этот главный файл ссылается на <code>DavyPageStand.pkl</code>, который объединяет
файлы: <code>DavyPageDeployment.pkl</code>, <code>DavyPageService.pkl</code>, <code>DavyPageIngress.pkl</code>, каждый из которых
в свою очередь отвечает за создание объектов для своего ресурса (для какого можно понять по названию).</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>DavyPageStand.pkl</summary><div><div class="collapsibleContent_i85q"><div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/K8sResource.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./DavyPageDeployment.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./DavyPageService.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./DavyPageIngress.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">const function getHost(type, id) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> if (id !</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> null) </span><span class="token string" style="color:hsl(95, 38%, 62%)">"pr-\(id).\(type).dev.davy.page"</span><span class="token plain"> else if (type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"blog"</span><span class="token plain">) </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy.page"</span><span class="token plain"> else </span><span class="token string" style="color:hsl(95, 38%, 62%)">"p.davy.page"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  type: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  version: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  id: String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Stand</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  args: Args</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">_args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Костыль (про него будет ниже в статье)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  ammend_deploy: Mapping</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">type_name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> if (args.type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"blog"</span><span class="token plain">) </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy-page-blog"</span><span class="token plain"> else </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy-page-private"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> if (args.id !</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> null) </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(type_name)-\(args.id)"</span><span class="token plain"> else </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(type_name)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">variant</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> if (args.id !</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> null) </span><span class="token string" style="color:hsl(95, 38%, 62%)">"dev"</span><span class="token plain"> else </span><span class="token string" style="color:hsl(95, 38%, 62%)">"prod"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">deployment</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new DavyPageDeployment.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">DPL</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">resource_name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">version</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> _args.version</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app-variant"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> variant</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    ...ammend_deploy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new DavyPageService.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">SVC</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">resource_name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app-variant"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> variant</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">ingress</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new DavyPageIngress.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">ING</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">resource_name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">resource_host</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> getHost(_args.type, _args.id)</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">with_auth</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> _args.id !</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> null || _args.type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"private"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app-variant"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> variant</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>DavyPageDeployment.pkl</summary><div><div class="collapsibleContent_i85q"><div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/api/apps/v1/Deployment.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/api/core/v1/Probe.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/api/core/v1/ResourceRequirements.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">const </span><span class="token property" style="color:hsl(355, 65%, 65%)">defaultProbe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Probe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">httpGet</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">scheme</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"HTTP"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">path</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"/img/logo.svg"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">port</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">failureThreshold</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">timeoutSeconds</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">const </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">params</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">readinessProbe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> (defaultProbe) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">initialDelaySeconds</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">periodSeconds</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">5</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">livenessProbe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> (defaultProbe) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">initialDelaySeconds</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">periodSeconds</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">resources</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">ResourceRequirements</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">requests</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"memory"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"170Mi"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cpu"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"10m"</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">limits</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"memory"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"340Mi"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cpu"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"100m"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">image</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"my-image"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">image_pull_secret</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"vault-registry-secret"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  resource_name: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  version: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  labels: Mapping&lt;String, String&gt;?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class DPL extends </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Deployment</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  hidden args: Args</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">metadata</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">namespace</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(args.resource_name)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      ...args.labels</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">selector</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">matchLabels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">template</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">metadata</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">containers</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy-page"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">image</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(params.image):\(args.version)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">imagePullPolicy</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"IfNotPresent"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">resources</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> params.resources</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">readinessProbe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> params.readinessProbe</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">livenessProbe</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> params.livenessProbe</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">imagePullSecrets</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> params.image_pull_secret</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>DavyPageService.pkl</summary><div><div class="collapsibleContent_i85q"><div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/api/core/v1/Service.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  resource_name: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  labels: Mapping&lt;String, String&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class SVC extends </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  hidden </span><span class="token property" style="color:hsl(355, 65%, 65%)">args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> Args</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">metadata</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">namespace</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(args.resource_name)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      ...args.labels</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"ClusterIP"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">ports</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token property" style="color:hsl(355, 65%, 65%)">port</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token property" style="color:hsl(355, 65%, 65%)">targetPort</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"http"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">selector</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>DavyPageIngress.pkl</summary><div><div class="collapsibleContent_i85q"><div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">import </span><span class="token string" style="color:hsl(95, 38%, 62%)">"@k8s/api/networking/v1/Ingress.pkl"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  resource_name: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  resource_host: String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  with_auth: Boolean</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  labels: Mapping&lt;String, String&gt;?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">class ING extends </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Ingress</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  hidden args: Args</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">metadata</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">namespace</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"davy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">annotations</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"cert-manager.io/cluster-issuer"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"letsencrypt-prod"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      when (args.with_auth) </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"nginx.ingress.kubernetes.io/auth-type"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"basic"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"nginx.ingress.kubernetes.io/auth-secret"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"private-basic-auth"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"nginx.ingress.kubernetes.io/auth-realm"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"private zone"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">labels</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"app"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(args.resource_name)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      ...args.labels</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">spec</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">ingressClassName</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"nginx"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">tls</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">hosts</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> args.resource_host </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token property" style="color:hsl(355, 65%, 65%)">secretName</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"\(args.resource_name)-tls"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">rules</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token property" style="color:hsl(355, 65%, 65%)">host</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_host</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">http</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">paths</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token property" style="color:hsl(355, 65%, 65%)">path</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token property" style="color:hsl(355, 65%, 65%)">pathType</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Prefix"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">backend</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                  </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> args.resource_name</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">port</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                    </span><span class="token property" style="color:hsl(355, 65%, 65%)">name</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"http"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>На выходе я получаю рабочий k8s манифест состоящий из трёх ресурсов:</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Пример результата в YAML формате</summary><div><div class="collapsibleContent_i85q"><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> apps/v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Deployment</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app-variant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> prod</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">template</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">imagePullSecrets</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> vault</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">registry</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">secret</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">containers</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">image</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">image</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain">v0.0.81</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">imagePullPolicy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> IfNotPresent</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">livenessProbe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">failureThreshold</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">periodSeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">timeoutSeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">initialDelaySeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">httpGet</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /img/logo.svg</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">scheme</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> HTTP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">resources</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">requests</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">memory</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> 170Mi</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">cpu</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> 10m</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">limits</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">memory</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> 340Mi</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">cpu</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> 100m</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">readinessProbe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">failureThreshold</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">periodSeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">5</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">timeoutSeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">initialDelaySeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">httpGet</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /img/logo.svg</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">scheme</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> HTTP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">selector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">matchLabels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app-variant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> prod</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ports</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> http</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">targetPort</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">80</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> ClusterIP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">selector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">apiVersion</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> networking.k8s.io/v1</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">kind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Ingress</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">metadata</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">annotations</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">cert-manager.io/cluster-issuer</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> letsencrypt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">prod</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">labels</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">app-variant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> prod</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">namespace</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">spec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ingressClassName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> nginx</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">rules</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">host</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy.page</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">http</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">paths</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> /</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">backend</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> http</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">pathType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Prefix</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">tls</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">secretName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> davy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">page</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">blog</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain">tls</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hosts</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> davy.page</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="проблемы">Проблемы<a href="https://davy.page/pkl-try#%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D1%8B" class="hash-link" aria-label="Прямая ссылка на Проблемы" title="Прямая ссылка на Проблемы">​</a></h2>
<p>Есть несколько проблем, с которыми лично я столкнулся, во время работы с Pkl.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-указание-ключей-объектам">1. Указание ключей объектам<a href="https://davy.page/pkl-try#1-%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%B9-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0%D0%BC" class="hash-link" aria-label="Прямая ссылка на 1. Указание ключей объектам" title="Прямая ссылка на 1. Указание ключей объектам">​</a></h4>
<p>Начну с самого бесячего. Если вы хотите полю в объекте
назначить переменную с таким же названием – вы получите Stack Overflow. Потому что
Pkl будет подставлять вашу переменную вместо и ключа, и значения.</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Pkl Error – A stack overflow occurred.</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token property" style="color:hsl(355, 65%, 65%)">arg</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"test"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token property" style="color:hsl(355, 65%, 65%)">object</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">MyObject</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">arg</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> arg</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Чтобы этого избежать, приходится придумывать костыли:</p>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">good</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token property" style="color:hsl(355, 65%, 65%)">_arg</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"test"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token property" style="color:hsl(355, 65%, 65%)">object</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> new </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">MyObject</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">arg</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> _arg</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-расширения-для-ide">2. Расширения для IDE<a href="https://davy.page/pkl-try#2-%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B4%D0%BB%D1%8F-ide" class="hash-link" aria-label="Прямая ссылка на 2. Расширения для IDE" title="Прямая ссылка на 2. Расширения для IDE">​</a></h4>
<p>Лично я пользуюся VSCode и для него пока есть только расширение,
раскрашивающее синтаксис, и не более. Никаких подсказок нет. Для IntelliJ IDEA
вроде как есть что-то получше, но я этого не проверял.</p>
<p>Расширение для VSCode, к тому же, не устанавливается из вкладки "Extensions", а скачивается отдельным файлом из гитхаба)
Это не сильный минус, просто лишний раз показывает на насколько ещё молод Pkl.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-типизация">3. Типизация<a href="https://davy.page/pkl-try#3-%D1%82%D0%B8%D0%BF%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F" class="hash-link" aria-label="Прямая ссылка на 3. Типизация" title="Прямая ссылка на 3. Типизация">​</a></h4>
<p>Вы не можете через тип указать, что такое-то поле должно быть конкретной строкой,
или одной из строк (Пример из TS: <code>let a: "string" | "string1"</code>). Такого можно добиться,
но только через <code>if</code>, что не очень удобно.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-глобальные-переменные">4. Глобальные переменные<a href="https://davy.page/pkl-try#4-%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5" class="hash-link" aria-label="Прямая ссылка на 4. Глобальные переменные" title="Прямая ссылка на 4. Глобальные переменные">​</a></h4>
<p>Их нет. Вернее они есть, но только статичные – поменять их в коде будет нельзя. Поэтому объявить глобальную <strong>переменную</strong> для
всего процесса билда конфига вы не сможете.</p>
<p>Есть <code>module.&lt;var&gt;</code> переменные, но они относятся только к контексту одного файла.</p>
<p>Вы также можете задавать различные properties через cli <code>-p name=value</code>. Они будут доступны всем файлам в
рамках одного билда, но это всё равно будет статичная переменная. Тоже самое про ENV.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-http-запросы">5. Http запросы<a href="https://davy.page/pkl-try#5-http-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B" class="hash-link" aria-label="Прямая ссылка на 5. Http запросы" title="Прямая ссылка на 5. Http запросы">​</a></h4>
<p>Из HTTP запроов есть только GET, и из него вы можете только
raw текст вытащить и в таком виде где-нибудь использовать. То-есть достать с
запроса JSON, и обращаться к конкретным полям вы не сможете.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="вывод">Вывод<a href="https://davy.page/pkl-try#%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4" class="hash-link" aria-label="Прямая ссылка на Вывод" title="Прямая ссылка на Вывод">​</a></h2>
<p>C Pkl'ом интересно работать и уже можно, как мне кажется, начинать
активно практиковаться в нём в своих pet-проектах. Но завозить его в коммерческую
разработку пока всё-таки рановато. Это связано не только с выше перечисленными проблемами,
но также с отсутствием стабильной версии: каждое новое
минорное обновление может принести существенные изменения в
язык, из-за чего потребуется значительная адаптация
существующих Pkl-файлов для обновления версии.</p>]]></content:encoded>
            <category>pkl</category>
            <category>kubernetes</category>
        </item>
        <item>
            <title><![CDATA[Создаём виртуальную сеть, как это делает Docker]]></title>
            <link>https://davy.page/isolated-virtual-network</link>
            <guid>https://davy.page/isolated-virtual-network</guid>
            <pubDate>Thu, 08 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Как известно, Docker умеет создавать виртуальные сети для безопасного и удобного сетевого]]></description>
            <content:encoded><![CDATA[<p>Как известно, Docker умеет создавать виртуальные сети для безопасного и удобного сетевого
взаимодействия внутри контейнеров. В этой статье мы рассмотрим, как именно он это делает
на примере базовых манипуляций с сетью в рамках одного хоста с операционной системой Linux.</p>
<p><img decoding="async" loading="lazy" alt="NGINX" src="https://davy.page/assets/images/docker-networking-c220fb1fc1dee11ab4d82479c9fcb3a1.png" width="1200" height="675" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/794262/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/794262/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="небольшая-теоретическая-часть">Небольшая теоретическая часть<a href="https://davy.page/isolated-virtual-network#%D0%BD%D0%B5%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B0%D1%8F-%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F-%D1%87%D0%B0%D1%81%D1%82%EF%BF%BD%D1%8C" class="hash-link" aria-label="Прямая ссылка на Небольшая теоретическая часть" title="Прямая ссылка на Небольшая теоретическая часть">​</a></h2>
<p>Для того, чтобы понимать, что будет происходить дальше в статье, надо немного окунуться в теорию.
Если вы уже работали с настройкой сетей в Linux, то можете
сразу переходить <a href="https://davy.page/isolated-virtual-network#%D1%87%D1%82%D0%BE-%D0%B4%D0%B5%D0%BB%D0%B0%D0%B5%D1%82-docker">к следующей части</a>.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>На всякий случай в этом блоке кратко объясню, что значат строки типа <code>192.168.0.1/16</code>.
Часть <code>/16</code> означает, что первые 16 бит ip-адреса предназначены для идентификации сети, а
все остальные – для идентификации узла. В приведённом ранее примере <code>192.168</code> – это
часть, идетифицирующая сеть, а <code>0.1</code> – идентифицирующая узел.</p><p><code>/32</code> означает, что указан конкретный ip-адрес узла.</p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="сетевые-namespaceы-netns">Сетевые Namespace'ы (netns)<a href="https://davy.page/isolated-virtual-network#%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D1%8B%D0%B5-namespace%D1%8B-netns" class="hash-link" aria-label="Прямая ссылка на Сетевые Namespace'ы (netns)" title="Прямая ссылка на Сетевые Namespace'ы (netns)">​</a></h3>
<p>Network Namespace в Linux – это изолированная среда сетевых ресурсов. У неё свои ip-адреса,
таблицы маршрутизации, firewall (о нём ниже) и так далее.</p>
<p>Они полезны, когда, например, у вас есть две виртуальные машины,
которые вы хотите связать друг с другом, но изолировать от других сетей.
Ну, или если вам нужно сделать тоже самое, но с контейнерам :).</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="виртуальные-сетевые-интерфейсы">Виртуальные сетевые интерфейсы<a href="https://davy.page/isolated-virtual-network#%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D1%8B%D0%B5-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81%D1%8B" class="hash-link" aria-label="Прямая ссылка на Виртуальные сетевые интерфейсы" title="Прямая ссылка на Виртуальные сетевые интерфейсы">​</a></h3>
<p>Виртуальные сетевые интерфейсы – это, по сути, логическое представление физических.
Используются для маршрутизации, туннелирования, создания виртуальных сетей и так далее.</p>
<p>Мы будет использовать <code>loopback</code> (или lo или localhost), <code>veth</code> и <code>bridge</code>, поэтому про них поподробнее.</p>
<ul>
<li><code>loopback</code> (localhost) – Предоставляет возможность обмена трафиком в пределах самого устройства.<!-- -->
<ul>
<li>Используется для внутренней коммуникации приложений и тестирования.</li>
<li>Доступен по адресам 127.0.0.1 - 127.255.255.255.</li>
</ul>
</li>
<li><code>veth</code> (Virtual Ethernet) – Виртуальный ethernet кабель: связывает 2 точки виртуальной
сети и делает возможным передачу трафика между ними.</li>
<li><code>bridge</code> – По сути, это виртуальный switch.</li>
</ul>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Switch – это устройство, с помощью которого можно соединить различные сетевые устройства для обмена трафиком.</p><p>Например, подключив компьютер и принтер к одному и тому же Switch'у, компьютер сможет "говорить" принтеру, что
и в каком количестве надо распечатать :).</p><div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" alt="Switch" src="https://davy.page/assets/images/switch-73c04861884d58def611b13c907b942a.png" width="600" height="283" class="img_ev3q"></p></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="firewall">Firewall<a href="https://davy.page/isolated-virtual-network#firewall" class="hash-link" aria-label="Прямая ссылка на Firewall" title="Прямая ссылка на Firewall">​</a></h3>
<p>Firewall используется для фильтрации трафика, как входящего, так и исходящего. Он может иметь
вид физического устройства или виртуальной логической реализации. Мы будем
использовать второе для дополнительной изоляции сетевых namespace'ов.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="nat">NAT<a href="https://davy.page/isolated-virtual-network#nat" class="hash-link" aria-label="Прямая ссылка на NAT" title="Прямая ссылка на NAT">​</a></h3>
<p>NAT или Network Address Translation – это технология преобразования внутренних ip-адресов
во внешний, и наоброт. Например, когда вы подключены к одному Wi-Fi с телефона и компьютера, на обоих устройствах
будет единый внешний ip-адрес. NAT будет менять у входящего трафика ip-адрес роутера на внтуренний ip-адрес
устройста, которому адресованы пакеты. И наоборот, ip-адрес у исходящих пакетов будет изменён на ip-адрес роутера.</p>
<p>Нужно всё это для экономии публичных ip-адресов, так как их количество
сильно ограничено (около 4.3 миллиардов, <a href="https://uchet-jkh.ru/i/skolko-ipv4-adresov-v-mire/" target="_blank" rel="noopener noreferrer">из которых 81% уже
назначены или зарезервированы</a>).</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="что-делает-docker">Что делает Docker?<a href="https://davy.page/isolated-virtual-network#%D1%87%D1%82%D0%BE-%D0%B4%D0%B5%D0%BB%D0%B0%D0%B5%D1%82-docker" class="hash-link" aria-label="Прямая ссылка на Что делает Docker?" title="Прямая ссылка на Что делает Docker?">​</a></h2>
<p><img decoding="async" loading="lazy" alt="how-docker-workds.png" src="https://davy.page/assets/images/how-docker-network-works-38bd9f04c620bc33157804f8295bef59.png" width="1200" height="675" class="img_ev3q"></p>
<p>Docker для каждого контейнера создаёт сетевой namespace (netns), и если вы не указали
при создании контейнера сеть, к которой его надо подключить, то контейнер подключится к дефолтной сети
(которой под капотом является <code>bridge</code>) парой <code>veth</code> интерфейсов. Это нужно для того,
чтобы по умолчанию контейнеры могли друг с другом общаться.</p>
<p>Но только этого было бы недостаточно. Для отправки ip пакетов контейнеры должны знать, какой узел будет начальной
точкой в построении маршрута до других контейнеров, подключённых к той же docker-сети, то есть <code>bridge</code>'у.
Этой начальной точкой (<code>gateway</code>'ем) становится сам <code>bridge</code>, к которому подключен контейнер. То есть выглядит
это как-то так: "Для трафика, отправленного на ip-адреса, которые находятся в подсети 172.17.0.0/16, задай gateway
172.17.0.1".</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Мы только что рассмотрели docker network driver <strong>bridge</strong>, но есть ещё несколько драйверов, например:</p><ul>
<li><code>--network none</code> – контейнер вообще не будет ни к чему подключен, и не будет иметь
даже доступа в интернет через сеть хоста. Всё что у него
будет, это <code>loopback</code> интерфейс.</li>
<li><code>--network host</code> – контейнер будет подключен к сети хоста.</li>
</ul></div></div>
<p>Для того, чтобы у контейнеров был доступ в интернет, Docker добавляет в NAT правила подмены ip-адреса для пакетов,
которые отправляются из <code>bridge</code> интерфейсов docker-сетей. Это нужно, чтобы ip-адреса контейнеров
менялись на ip-адрес выходного интерфейса (или ip-адрес хоста), через который строятся маршруты в интернет.
Также каждому контейнеру добавляется дефолтный gateway (шлюз) в таблицу маршрутизации, чтобы пакеты для
всех адресов отправлялись через <code>bridge</code> интерфейс, так как у него
есть доступ к сети хоста.</p>
<p>Помимо этого Docker добавляет в <code>firewall</code> правила, запрещающие перенаправление трафика из одной docker-сети
в другую для их изоляции друг от друга.</p>
<p>Когда вы публикуете порт из контейнера <code>-p &lt;внешний порт&gt;:&lt;внутренний порт&gt;</code> внутренний
порт становится доступен на локальной сети хоста. Сейчас по дефолту docker для этого держит
процесс "docker-proxy", который слушает нужные порты и перенаправляет на адрес нужного контейнера,
и его внутренний порт. Это ненужное legacy, <a href="https://github.com/docker/docker/issues/8356" target="_blank" rel="noopener noreferrer">которое будет скоро полностью удалено из Docker</a>
в пользу hairpin NAT, но пока его можно только вручную отключить, добавив демону флаг <code>--userland-proxy=false</code>.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Простыми словами, hairpin NAT - это процесс, когда пакет отправляется на адрес внешнего узла, но затем
направляется обратно к узлу внутри той же локальной сети.</p></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Docker также умеет: создавать оверлейную сеть, соединяя несколько docker демонов,
создавать IPvlan сеть, объединяя контейнеры без использования <code>bridge</code> интерфейса и так далее.
Это всё очень интересно, но в текущуюю статью это не войдет, слишком много информации.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="практическая-часть">Практическая часть<a href="https://davy.page/isolated-virtual-network#%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F-%D1%87%D0%B0%D1%81%D1%82%D1%8C" class="hash-link" aria-label="Прямая ссылка на Практическая часть" title="Прямая ссылка на Практическая часть">​</a></h2>
<p>Создадим виртуальную сеть с доступом в интернет и выведем из неё в сеть хоста TCP порт 8000,
который будет доступен через <code>127.0.0.1</code> и другим машинам
в нашей сети (аналог <code>docker -p &lt;внешний порт&gt;:&lt;внутренний порт&gt;</code>).</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Большая часть объяснений будет в комментариях в кодовых блоках.</p></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Далее по статье для модификаций Firewall и NAT я буду использовать <code>iptables</code>.
Понимаю, что он уже считается устаревшим, но Docker продолжает его использовать,
поэтому и я решил использовать его, а не <code>nftables</code>.</p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="шаг-1--создаём-network-namespace">Шаг #1 – Создаём network namespace<a href="https://davy.page/isolated-virtual-network#%D1%88%D0%B0%D0%B3-1--%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%91%D0%BC-network-namespace" class="hash-link" aria-label="Прямая ссылка на Шаг #1 – Создаём network namespace" title="Прямая ссылка на Шаг #1 – Создаём network namespace">​</a></h3>
<p>Начнём с создания netns и запуска в нём простого питоновского http-сервера.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># Создаём netns c именем "red"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> red</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Задаём loopback интерфейсу Ipv4 адрес, так как по дефолту он не задан</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-n</span><span class="token plain"> red addr </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">127.0</span><span class="token plain">.0.1/8 dev lo </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Включаем loopback интерфейс</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-n</span><span class="token plain"> red </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> lo up</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Запускаем http-сервер в рамках нового netns</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">exec</span><span class="token plain"> red python3 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> http.server</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Мы можем запрашивать у сервера что-либо только изнутри netns (<code>ip netns exec red curl 127.0.0.1:8000</code>).
Пока он полностью изолирован.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="шаг-2--создаём-bridge-интерфейс">Шаг #2 – Создаём bridge интерфейс<a href="https://davy.page/isolated-virtual-network#%D1%88%D0%B0%D0%B3-2--%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%91%D0%BC-bridge-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81" class="hash-link" aria-label="Прямая ссылка на Шаг #2 – Создаём bridge интерфейс" title="Прямая ссылка на Шаг #2 – Создаём bridge интерфейс">​</a></h3>
<p>Теперь нам нужно создать тот самый <code>bridge</code> интерфейс и подключить к нему ранее созданный netns red.</p>
<p>Помимо этого мы также зададим ip-адреса для наших
netns и <code>bridge</code> вместе с указанием подсети, которая должна у них совпадать.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># Создаём bridge интерфейс с именем br0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> br0 </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token plain"> bridge</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Задаём bridge интерфейсу ip-адрес 10.100.0.1. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># При этом также указывая, что первые 24 бита </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># предназначены для идентификации сети, то есть часть "10.100.0".</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> addr </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.1/24 dev br0</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Включаем интерфейс br0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> br0 up</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Создаём пару veth интерфейсов с именами red0 и red0.br0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> red0 </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token plain"> veth peer name red0.br0</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Подключаем один из veth интерфейсов к bridge'у и включаем его</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> red0.br0 master br0</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> red0.br0 up</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Второй veth устанавливаем для нашего red netns</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> red0 netns red</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Устанавливаем ему ip-адрес и включаем</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-n</span><span class="token plain"> red addr </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2/24 dev red0</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-n</span><span class="token plain"> red </span><span class="token function" style="color:hsl(207, 82%, 66%)">link</span><span class="token plain"> </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">set</span><span class="token plain"> red0 up</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Теперь с сети хоста можно пинговать netns и отправлять запросы http-серверу.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">ping</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">curl</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2:8000</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Для эксперимета можете по аналогии создать второй netns, подключить
его к <code>bridge</code> и попробовать попинговать один netns из другого и наоборот.</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">exec</span><span class="token plain"> blue </span><span class="token function" style="color:hsl(207, 82%, 66%)">ping</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">exec</span><span class="token plain"> red </span><span class="token function" style="color:hsl(207, 82%, 66%)">ping</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.3</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Вы увидете, что <code>ping</code> проходит, так как оба netns подключены к одному и тому же <code>bridge</code>.</p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="шаг-3--необходимые-системные-параметры">Шаг #3 – Необходимые системные параметры<a href="https://davy.page/isolated-virtual-network#%D1%88%D0%B0%D0%B3-3--%D0%BD%D0%B5%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D0%BC%D1%8B%D0%B5-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B5-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B" class="hash-link" aria-label="Прямая ссылка на Шаг #3 – Необходимые системные параметры" title="Прямая ссылка на Шаг #3 – Необходимые системные параметры">​</a></h3>
<p>Чтобы всё у нас корректно работало нам нужно поменять два системных параметра:</p>
<ol>
<li><code>net.ipv4.ip_forward</code> – ip port forwarding нужен для того,
чтобы можно было перенаправлть трафик между интерфейсами.</li>
<li><code>net.ipv4.conf.&lt;interface&gt;.route_localnet</code> – <code>route_localnet=1</code> разрешает перенаправления
трафика на локальные сети. В нашем случае нам нужно разрешить это для нашего <code>bridge</code> интерфейса.</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sysctl</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-w</span><span class="token plain"> </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">net.ipv4.ip_forward</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">sysctl</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-w</span><span class="token plain"> </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">net.ipv4.conf.br0.route_localnet</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="шаг-4--даём-доступ-в-интернет-из-network-namespace">Шаг #4 – Даём доступ в интернет из network namespace<a href="https://davy.page/isolated-virtual-network#%D1%88%D0%B0%D0%B3-4--%D0%B4%D0%B0%D1%91%D0%BC-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%B2-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82-%D0%B8%D0%B7-network-namespace" class="hash-link" aria-label="Прямая ссылка на Шаг #4 – Даём доступ в интернет из network namespace" title="Прямая ссылка на Шаг #4 – Даём доступ в интернет из network namespace">​</a></h3>
<p>Нужно добавить в таблицу NAT в iptables правило, которое
применяет ко всем пакетам с исходными адресами нашей подсети <code>bridge</code> действие подмены ip-адреса
на ip-адрес интерфейса, через который пакеты прошли (в нашем случае на ip-адрес интерфейса eth0).
Вы должны подставить вместо eth0 имя вашего основного сетевеого интерфейса с доступом в интернет.</p>
<p>Также через тот же iptables необходимо добавить правила, разрешающие forward трафика из
нашего основного сетевого интерфейса в <code>bridge</code> интерфейс и наоборот, в таблицу FILTER.</p>
<p>И наконец, добавить дефолтный gateway для netns, чтобы по умолчанию
пакеты, адресованные во внешний интернет, шли через адрес <code>bridge</code> интерфейса.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># Правило для таблицы NAT</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-t</span><span class="token plain"> nat </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> POSTROUTING </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-s</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.0/24 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> eth0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> MASQUERADE</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Правило для таблицы FILTER (firewall)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> FORWARD </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> eth0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-i</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> ACCEPT</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> FORWARD </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-i</span><span class="token plain"> eth0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> ACCEPT</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Для нашего netns'а задаём дефолтным gateway'ем наш bridge</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">exec</span><span class="token plain"> red </span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> route </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> default via </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.1</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Пробуем пропинговать внешний ip-адрес:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain"> netns </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">exec</span><span class="token plain"> red </span><span class="token function" style="color:hsl(207, 82%, 66%)">ping</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8.8</span><span class="token plain">.8.8</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="шаг-5--выводим-tcp-порт-в-сеть-хоста">Шаг #5 – Выводим TCP порт в сеть хоста<a href="https://davy.page/isolated-virtual-network#%D1%88%D0%B0%D0%B3-5--%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B8%D0%BC-tcp-%D0%BF%D0%BE%D1%80%D1%82-%D0%B2-%D1%81%D0%B5%D1%82%D1%8C-%D1%85%D0%BE%D1%81%D1%82%D0%B0" class="hash-link" aria-label="Прямая ссылка на Шаг #5 – Выводим TCP порт в сеть хоста" title="Прямая ссылка на Шаг #5 – Выводим TCP порт в сеть хоста">​</a></h3>
<p>На этом этапе мы добавим возможность стучать в наш http-сервер через <code>http://localhost:8000</code> и
вместе с этим сделаем возможным обращаться к нему машинкам извне, то есть другим реальным
компьютерам, которые подключены к вашей приватной сети, или,
если у вас напрямую подключение к публичной сети, тогда вообще для всех компьютеров в интернете.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">### Правила для таблицы NAT</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Для пакетов извне (с других компьютеров) (относится к цепочке PREROUTING) добавляем правило, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># которое для всех пакетов, адресованных нашей локальной сети по tcp порту 8000,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># меняет destionation адрес на адрес нашего namespace'а.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-t</span><span class="token plain"> nat </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> PREROUTING </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-p</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> addrtype --dst-type LOCAL </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--dport</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8000</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> DNAT --to-destination </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2:8000</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Для пакетов, сгенерированных хостом (относится к цепочке OUTPUT), добавляем правило, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># которое для всех пакетов, адресованных нашей локальной сети по tcp порту 8000,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># меняет destionation адрес на адрес нашего namespace'а.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-t</span><span class="token plain"> nat </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> OUTPUT </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-p</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> addrtype --dst-type LOCAL </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--dport</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8000</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> DNAT --to-destination </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2:8000</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Добавляем действие MASQUERADE, которое применяется к пакетам,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># проходящим через интерфейс br0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># и которые были отправлены с локальной сети (то есть прошедшие через цепочку OUTPUT).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># MASQUERADE заменит их ip-адрес на ip-адрес шлюза,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># через который они покинули сеть, в нашем случае на ip-адрес br0.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-t</span><span class="token plain"> nat </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> POSTROUTING </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> addrtype --src-type LOCAL </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> MASQUERADE</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Добавляем действие MASQUERADE ко всем TCP пакетам </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># с портом 8000, адресованным локальной сети.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Нужно для пакетов, пришедших от других компьютеров (вышедших из цепочки PREROUTING). </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-t</span><span class="token plain"> nat </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> POSTROUTING </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> addrtype --dst-type LOCAL </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-p</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--dport</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8000</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> MASQUERADE</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">### Правила для таблицы FILTER (firewall)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Разрешаем роутинг, пакетам проходящим через bridge интерфейс, которые относятся к установленным соединениям.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> FORWARD </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> conntrack </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--ctstate</span><span class="token plain"> RELATED,ESTABLISHED </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> ACCEPT</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Разрешаем роутинг пакетам, не входящим с интерфейса bridge и адресованным этому интерфейсу по TCP порту 8000. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> FORWARD </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-d</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.100</span><span class="token plain">.0.2/32 </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-i</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-o</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-p</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-m</span><span class="token plain"> tcp </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--dport</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8000</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> ACCEPT</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Разрешаем трафик, который приходит с bridge интерфейса</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">iptables </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-A</span><span class="token plain"> FORWARD </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-i</span><span class="token plain"> br0 </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-j</span><span class="token plain"> ACCEPT</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Теперь можно попробовать постучаться в наш http-сервер из сети хоста:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">curl</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">127.0</span><span class="token plain">.0.1:8000</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>И также поотправлять в него запросы с других машин через ip-адрес хоста:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># замените ip на свой x)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">curl</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">192.168</span><span class="token plain">.1.15:8000</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="всё">Всё!<a href="https://davy.page/isolated-virtual-network#%D0%B2%D1%81%D1%91" class="hash-link" aria-label="Прямая ссылка на Всё!" title="Прямая ссылка на Всё!">​</a></h2>
<p><img decoding="async" loading="lazy" alt="End" src="https://davy.page/assets/images/end-140ad7b072d6ff5109316fde983e00bc.jpeg" width="900" height="580" class="img_ev3q"></p>
<p>По итогу мы получили:</p>
<ol>
<li>http-сервер, запущенный в изолированном сетевом пространстве.</li>
<li>Доступ к этому серверу по порту 8000 из loopback (localhost) интерфейса хоста.</li>
<li>Перенаправление пакетов от других машин по tcp порту 8000 в наш http-сервер.</li>
</ol>
<hr>
<p>Спасибо за чтение :)</p>]]></content:encoded>
            <category>networking</category>
            <category>docker</category>
            <category>linux</category>
        </item>
        <item>
            <title><![CDATA[Работа с auth_basic в nginx. На что обратить внимание]]></title>
            <link>https://davy.page/nginx-bug</link>
            <guid>https://davy.page/nginx-bug</guid>
            <pubDate>Thu, 01 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Расскажу про использование директивы auth_basic для включения/отключения базовой аутентификации в nginx.]]></description>
            <content:encoded><![CDATA[<p>Расскажу про использование директивы <code>auth_basic</code> для включения/отключения базовой аутентификации в nginx.
Как она работает, и что может заставить её работать не так, как вы ожидаете.</p>
<p><img decoding="async" loading="lazy" alt="NGINX" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAIACAMAAAArE+6LAAAAD1BMVEUgIB4AmQAOYA0DiAMbMRk4GBtpAAAQzUlEQVR42uzdi3LbthIA0AiL///m2k7ayCIeC5CSPNNzkrmd1jYp+QqLxeLBX78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgB+i1lpKqfX1V/r97V9/F/+xcP3BN398vV7xvmdXqlfeqJZrrgS/P1LldrvFh9Ofq1ri40of1yrZH/j89i+L/4jU5Uv5ejXRCQEfLzc+v6Fc8Cv8c6XOjT5ew23h1zL7DXffEWw1/z+iXnOlyF4pbpsyben+nZXhzU+2zLsbtVpmfcaNbkIAV7f/kxFg/UplOwAkUoAaw4BR4/7rZxrm9EaLgSv5/5UIwNXt/0O96kqZCLDf/uct6fH1lOG9TzTMGsMbTb583Y1g40N1aFi7hYDDleY91IkEYJ4ClNswIE2+vNIsY/gbLIffy0Xt/yNYywE4qdEE9z5Vh1QicaEz7X92+WNzKQtfPtMsH250u11zp8aNwueXkwlA3C6KABsf9HKq/U8+/o2LT5KPvbcdkxB6Vx88NXpv3ShkAJzTbINbn6v1APAYfOK+lcRx+u/wn+viO2u3y/8uX08G0Gi+8Xh8C3s5QDNSqwLwjACwNbgsy6P0ctdw4hAJDhdb/PjH8YfKePRRdtr/tF1G822s5gCJG8GpABDncoDSaKyrKcPqGKAm6wvxpABQO0WMsvQtGzcKAYBnZgAbcwGrGUBNVgBGhcLR5z/TMce5icBOtzyNNMttN3UjOB8AYrskVhoNdvSZPpcA/G6/kcwAGi38ggygNpKMSAeAhdu1bnTFukIo3V52NQcoi7NUsdvsk2OAfMe8mU93u+XvVyrRS2XKuRuFWQCeNgRYzwFKo62mvj360wAxCwIlEWDiOUXAGrmhSWv6fmk2cHAjCQBPDABr/ctaDaCW/Eh/9NWazDDi6gAw6P8fWnZ5nNxcu2ON/q9BAsCFAeDc0pjSuMRe4En0/IkmNKnyPSwxiOWy3K1XADgsBSzJSLEQaEIFgCdlALFZB1iqAdTIdPyJABEX1AA2MoA6fuFla7BwZqABlw8B1nKApXUAZb/wl90TGE8MAMP8v7EfsOy24kEBQf/PVQEgRnWAuh9KYq1fi6mVBvTEAFBnictjZn+cx8vtC9D/86oMoLsWdzUAJNYB1Pbqg89D84aa0aomAkAc+sw6WSi4PP6/DU8XqbFTxujO/2v/PGUIcGY9QDmuVu1lAHXziJ/W8t5uS5i0y9g6ZGyW//dDyUYlsEY3aMj/eU0NID8b2LrSpB3H6pi2LLy85BAgVjvV9v6/Wfdc17P5Gp2VEvp/XhkAknsD8zWA9jlAkWp8kV4M9KQaQLP/j0SfXvurrtvfH6cORIW9ANDoGmM1AAxnATo18boZrzobAupz9gK0uuXklWr0f66o//FzM4BUHaA0Vt4s3LJsHyPeeXGZDCC6CwU3xv+JnL67LWA8b6D/5wUBIM6tB0jXANor2+pGwBpW7+N7kSGuGALM5v9mQ/T+rP5DBGgtlPr3fWj/XB0AYrr4Zj4KyNYATiUAC2cYPmElYKP/by/U79f1cxt75P+8xvhUjljJAZK7AWvzgL/8vqOSbRPZGkBcsix3aYfCbDaw9gOy/J831AAydYDkXoBycllLa0lN7NYAlsbW99335AjDkrhI/6fWqoVwaQCIzTpAa4N/owGc3nhccmWxGstH9S0vy99K06c5gPof7woAcSIHaFQTIvnxj/2NuP0GNznyp9GHl7XbDs4uHlY0IrqX+fy53vmf+n+eGgBiuhxgnANkZgE66+GWHnBTWxMXtRsA4pp1ANn6/20plBxPCav6f95cA4i9VcGZGkCn/a8dbJNMATKzAOlmOxr/r5cTR3MB2j/vDgCjR3bWUxlAaT4LaDUAtAYb9XwRcLotL9JNdtZUM8OJUP/jVQHg+9r6Wgbn9dRMAIhOBvCwMGcrAfiMAEfHa0y+aaXfHkzfR2l9cbaqIftMhLuzxvT/vCoDGD62u9tcW3tdEknC5pMyP/9+/c/vf6vtb3r8s5cB1Biu+dtbUrR6Cpr2zwsCQPxbih7kop25gHKcvY4nVACucizF9/rYb118HIflERutdWEFlvE/T9P6HH61yDJYjFY3awDlJ3Vt6X57uix3b19hjePpYPp/3pcBPGxLqavrAaZ7AermJoP3BoDh+P/3leJwuElmVFOzSzBC/89LawD1PqVPzwXMMoD2B/5dn+3WdruyPv7fzwBSdYDQ//PyAPBv91XX1gPM1gFsHwT4zgygO/9/F7q2agDt8Vf7EFDtnycHgPaceonuZ7KRA7Q6+EmLW08A6q8/MwCNEn/tzQZMA0CcOpZn/4DxZiUw1P/4ERnA3047dQxPOYyEv3XvdWXj/NdMf/z5e//n4V+Pf/5er7UOoK5lAPPxfy8DWDzdINT/+Gk1gNU6wLgG0OlLWw2l1s0Hhn1veecPBEmM/89lAJ+RLsbTgPp/XhQA/sv377uvhbmAcQ2guQg4d3ru5nKZxaXAcXygV+TS8jhzanfdffIZPD8DuG+4MakEDjOATq57cfu/PyC45gJAfxYgfSxXcj6hW4wI7Z+fWQM4dt3Rb7+NpcAxjA63aCUAZ/r/W83n+LPE/TD+76blJ2oAk0LL2xZJ8H9Ry/RTl90XMMwASnI2sdbUytjE66kLASAGx3LOR/iXPmj8YTghA+AlGcCoMl9zXe79XoDjbsD28eNlcUg8DgixsttndmJYpNPy7XUAs1/u7k4puKwG8KdpJ54dPJ4FSKYAowAQs//y7WqTJwONE4Tuy4hG477+QeNOAePH1AAm3dTfRjXZC1Bms2m9QkJ6MPAQTZaeDPS9adfRsX39Kl7kzgRMjv/fvlaS/2EAiHblqcS8TjXZC9A5VKd2X056MUC0X/f+EGD0/L9Gh3xiJWBkoptRAK8IADH6wCX2BUz2AtT2AeQxTUjSceCh1aUXAsXDlzvj/+6RAft7AZIxTgTgrTWATvN+6MXL9wZ1eDJQai1gyVf9YpIqx2GFU+5U4OXHcq0dL/r399G5UWP6QQTguQEg5h1OPTbv7xGjNA7MScSQOD4Uc+EE7sGa2c2lwPn5/1EGkDkPYOVBIyIA780A5jnA/ESg5tLax1U1u4sAYrFjbgy/y6+tx3Jungi09A5FAF4WALqPtu23zM+YMX8uQG2n7u2Fh8dUINYWzaeKgPFwid7+/9GxvI2n/Z190HjuMYtwVs1nALMcYJ4BfL9ZtFtLSaX/MW8g2acD38eHGhud8EYG0Br/t2ZJ1AF4XQYwP9BuuCq4caWY5BDtKsDqZuBOeX6jBrD3WK6I1C7H3fG/CMDrhgAx3oEyOiu49aXEgOPw0a75p5XFKEPuDPKPTfBvKhJbx/KtZwA1NpY7iAA8LwBE8oNWW4Pzfo1+0vO11wPWspwE5B4OOssA+iOM4bbc5XUAtf9L+6e9O9uRG4cBAIgV9f/fvMkGc3XrIGWnZ7CoQt6S2G7DkijqitYWk5DUALwgCbhag9p7qVzmOhHx1FXog82+fv/5vVFYdm/xeg5gXpctC3R1P4B1R2O1H4JMIC+oANYNzSoPsP9ge2QW2M6rnz5sIIcNdCkHUBxh2EYAvdL+f73RJFUqBuAHRACfaoA4iQA+Pv8vBTi/8UUk5hM//ctIDQNOK4NWfKTlOcOL/v9bRbPoAYkB+OYI4LEJW81nHXyu/dr5YL04Q7c0CnC4LVfEZmSz0v6P3lFsNlGCOyqAyO5D1dLT9TYt4DqLlyzVk2ZxsPowNouBBj8oEnVT5ZzhHrO1jJ+frrfFg6kBuL8CiFJHsyfnsI1K5pfmLYq92zbquc+m6N8TAexjk0IOIDvRYJEJFANwo96O2piWLD6FQpD6rIcL9cfP209GAY6O5c5HAD3d0ViNBagB+Gs5gEh+YG0wcTU7gb0dp7d6pY8+2MWsPgqQeRcRD52G6UHjixu2XK5EJpC/ngRM9TLbdi5QTCKAx3V6hcM0IrMPwGMJH+9B2jOjmblt+dMHjZcmMr3XAPYH4LUVQO7zyixnjUokHIeVzqyQZuYB3HIsTzIH0BcTD9umdxZiAH5WBJDLA+TbzMwSuuGOoZFvmMc5gPEGgJFvaFMRQK8vNJIH4FUVQORWAw6atCht0vEQf38te1Gaf7BtpeurAY/a/+TZgIuAaXojeQB+cATwEAMM5wfWvuxoS8OtwOYPezQMGPW5Salzhs8WGosB+LE5gFUvIHbN1IUDwNP9htRU4PkARv5AjnhOJyQOV4rMjZYxgBqA740A9nmAym0r+39kIuFYrxnajGIUGthtBLBq/zfzH3qb/3YxAN8cAayGtiJTPEsbYhT76VdyAHHxfO82eUn1iUa9zV+SGoCrem1HoEkMMN2p7zx2SFYA/bhhjmvzfwsRwHj+f3b+4zIP4APmngggjhuWfjAKMAg94qgn0NLlMgrzAKJWsEajALtz0ws3WqwN/EcIwLfmAIZteWQigP+2FroaBUStYZ6dDvx4rnmxYd1EAIsEQO5FL9YGGgzke3MAmzxA8c7pDGAkQuDNyF7c0v//HAFMbjQ97Sx9o3kvwEgA91UAcfpVDVYGxS4C+JwaPwwENvsIneYAyh3r9I0iP/43qQGiMoYIL4kAFvMBareuVgRtXy6jWgEcFKnNWoDZBl+VtzyNAVQAfHcO4EsNEIUKoDobqLgiJrcWIK6XqLMph7UbzWoAFQD3RwAHlzla4NdG+2NGuh7I79UZg0Y3ytPyDl/hcPfReiXbbopX4LkZjsutyrAXsDsg58J8wH0Zauuou902tWaQpN/d6GBfr/HLkgTkjgrgc1MY/eir6vU2+tJsoP0cunVA0gbTc87a0+df/uUVtrgneT+aFWwUgNv6AHFxaOl5PkDkbp7Ymz8OMhXPTWbfZCDaLXXo04WeOhuH+3r291mXIQXAXwoBLjQqTzXAPpRY5gFjuetgK/+yh2L3eMDJeX+6Pb3CPvzruPiGn3dE8flyPQS47fSph3P7MgWqnY4ERnHn0nj+H3FbQr2tr9Sq9WK2BtAB4OYY4FpauZfPsOmD0bjIjAK06vMMHqfdlU/vmyu1eXhw0gu440rw/lX198msF4eV+vsHGtl+btsX/DieA/vpeYbbdLa43vH5uFLMX+HHgedXl/B+PLLFwNxXB/z6Qn99uu2GyqR6pTjSSs/Tpif1tD+Xu96Wvl1p9mDtz3u5odHub1dSAXBbBfADr/Si5+m3laRXFUkFH/7f1SgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwk/0LD/pxg//r/PMAAAAASUVORK5CYII=" width="1024" height="512" class="img_ev3q"></p>
<!-- -->
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="как-это-работает-и-для-чего-вообще-нужно">Как это работает и для чего вообще нужно?<a href="https://davy.page/nginx-bug#%D0%BA%D0%B0%D0%BA-%D1%8D%D1%82%D0%BE-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-%D0%B8-%D0%B4%D0%BB%D1%8F-%D1%87%D0%B5%D0%B3%D0%BE-%D0%B2%D0%BE%D0%BE%D0%B1%D1%89%D0%B5-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE" class="hash-link" aria-label="Прямая ссылка на Как это работает и для чего вообще нужно?" title="Прямая ссылка на Как это работает и для чего вообще нужно?">​</a></h3>
<p>Часто бывают случаи, когда нужно обернуть веб-сервер в дополнительный слой защиты, которым
может стать базовая http аутентификация.</p>
<p>По сути вся базовая http аутентификация заключается в добавлении клиентом к запросу хедера <code>Authorization</code>
со строкой <code>Basic $credentials</code>, где <code>$credentials</code> это закодированные в base64 логин и пароль
в формате <code>login:password</code>. Пример полного хедера: <code>Authorization: Basic YWRtaW46dGVzdA==</code>.</p>
<p>В случае, если клиент пользуется веб браузером для получения доступа к ресурсам, то ему браузер предложит
ввести пароль в специальное окно.</p>
<p><img decoding="async" loading="lazy" alt="Basic Auth" src="https://davy.page/assets/images/basic-auth-a0e263ec149c6ac43479d9c3c92c9a1c.png" width="678" height="466" class="img_ev3q"></p>
<p>После ввода браузер запомнит учетные данные для этого сайта и в запросы всех остальных ресурсов будет автоматически
помещать логин и пароль, которые вы ввели при заходе. Но если на один из запросов вернётся статус код <code>401 Unauthorized</code>
– придётся вводить логин и пароль заново.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="как-этим-пользоваться-в-nginx">Как этим пользоваться в nginx?<a href="https://davy.page/nginx-bug#%D0%BA%D0%B0%D0%BA-%D1%8D%D1%82%D0%B8%D0%BC-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%D1%81%D1%8F-%D0%B2-nginx" class="hash-link" aria-label="Прямая ссылка на Как этим пользоваться в nginx?" title="Прямая ссылка на Как этим пользоваться в nginx?">​</a></h3>
<p>Для того, чтобы включить базовую аутентификацию в nginx для всего виртуального сервера достаточно в контекст <code>server</code>
добавить следующие директивы:</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive string" style="color:hsl(95, 38%, 62%)">"auth"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># обозначает защищаемую область. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                   </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Также должен выводиться пользователю в окне ввода </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                   </span><span class="token comment" style="color:hsl(220, 10%, 40%)"># логина и пароля, но лично ни разу такого не видел)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>В <code>auth_basic_user_file</code> нужно указать путь до файла, в котором будут указаны учетные данные для доступа. Файл должен
быть создан при помощи утилиты htpasswd от Apache. <a href="https://kubernetes.github.io/ingress-nginx/examples/auth/basic/" target="_blank" rel="noopener noreferrer">Подробнее читать тут</a>.</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Так же директиву <code>auth_basic_user_file</code> можно указывать в <code>location</code>, <code>http</code> и <code>limit_except</code> блоках.</p></div></div>
<p>Для отключения базовой аутентификации для конкретных ресурсов
достаточно добавить следующий блок в <code>location</code>.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>С отключением иногда могут возникнуть проблемы, о них я расскажу ниже.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="на-что-следует-обратить-внимание">На что следует обратить внимание<a href="https://davy.page/nginx-bug#%D0%BD%D0%B0-%D1%87%D1%82%D0%BE-%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D0%B5%D1%82-%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%B8%D1%82%D1%8C-%D0%B2%D0%BD%D0%B8%D0%BC%D0%B0%D0%BD%D0%B8%D0%B5" class="hash-link" aria-label="Прямая ссылка на На что следует обратить внимание" title="Прямая ссылка на На что следует обратить внимание">​</a></h3>
<p>И так, существуют варианты конфигураций, при которых включение или отключение basic auth работать не будет.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-использование-с-директивой-return">1. Использование с директивой <code>return</code><a href="https://davy.page/nginx-bug#1-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B9-return" class="hash-link" aria-label="Прямая ссылка на 1-использование-с-директивой-return" title="Прямая ссылка на 1-использование-с-директивой-return">​</a></h4>
<p>Эта директива сработает вне зависимости от того, включена или выключена базовая аутентификация.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># всегда будет возвращать 200, несмотря та то, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># что локейшон наследует базовую аутентификацию</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> = /test</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">200</span><span class="token directive"> </span><span class="token directive string" style="color:hsl(95, 38%, 62%)">"success"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-использование-с-директивой-rewrite">2. Использование с директивой <code>rewrite</code><a href="https://davy.page/nginx-bug#2-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B9-rewrite" class="hash-link" aria-label="Прямая ссылка на 2-использование-с-директивой-rewrite" title="Прямая ссылка на 2-использование-с-директивой-rewrite">​</a></h4>
<p>Надо понимать, что <code>rewrite</code> перепишет ваш урл и направит
на другой локейшон, и если в этом локейшоне не отключен <code>auth_basic</code>, то у клиента всё равно
запросит логин и пароль.</p>
<p>Но в сочитании с директивой <code>proxy_pass</code> переписанный локейшон сразу перейдёт в проксю,
и, соответственно, запроса на аутентификацию не будет (если у ресурса,
который указан в <code>proxy_pass</code> нет своей аутентификации. Смотреть в пункте 3).
Тоже самое с <code>try_files</code> – переписанный урл уйдёт в папку статики и базовая
аутентификация не запросится.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример с proxy_pass</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Перебросит на location /todos, но так как у todos </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># не отключена базовая аутентификация, то /link будет её запрашивать</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> /link</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">rewrite</span><span class="token directive"> ^/link/(.+?)$ /todos/</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$1</span><span class="token directive"> break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> /todos</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">proxy_pass</span><span class="token directive"> https://jsonplaceholder.typicode.com</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Перепишет урл и отправит его в проксю. Базовая </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># аутентификация не будет запрошена.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> /rewrited_todos</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">rewrite</span><span class="token directive"> ^/link/(.+?)$ /todos/</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$1</span><span class="token directive"> break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">proxy_pass</span><span class="token directive"> https://jsonplaceholder.typicode.com</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример с try_files</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">root</span><span class="token directive"> /usr/share/nginx/html</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Перепишет урл и отправит его в папку </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># статики за файлом. Базовая </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># аутентификация не будет запрошена.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> /static</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">rewrite</span><span class="token directive"> ^/static/(.+?)$ /</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$1</span><span class="token directive"> break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">try_files</span><span class="token directive"> /</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$uri</span><span class="token directive"> =404</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-использование-с-директивой-proxy_pass">3. Использование с директивой <code>proxy_pass</code><a href="https://davy.page/nginx-bug#3-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B9-proxy_pass" class="hash-link" aria-label="Прямая ссылка на 3-использование-с-директивой-proxy_pass" title="Прямая ссылка на 3-использование-с-директивой-proxy_pass">​</a></h4>
<p>Тут особо говорить нечего. Просто помните, что бэкенд, на который ведёт проксипас,
может быть скрыт под своей базовой аутентификацией.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-использование-с-директивой-error_page">4. Использование с директивой <code>error_page</code><a href="https://davy.page/nginx-bug#4-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B9-error_page" class="hash-link" aria-label="Прямая ссылка на 4-использование-с-директивой-error_page" title="Прямая ссылка на 4-использование-с-директивой-error_page">​</a></h4>
<p>Директива отвечает за обработку ошибок и переброс на нужную fallback-страничку.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># На все перечисленные ошибки nginx будет возвращать </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># error.html страничку из директории со статикой.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">error_page</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">400</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">403</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">404</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">500</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">501</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">502</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">503</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">504</span><span class="token directive"> /error.html</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Используя её в связке с <code>auth_basic</code> стоит обратить внимание на то,
что если локейшон с отключенной аутентификацией отдаст ошибку, которая
обработается этой директивой и у этой страницы будет включена базовая аутентификация, то
и ваш локейшон её запросит. Помните, что <code>error_page</code> может указываться не только для конкретного локейшона,
но и для всего сервера.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive string" style="color:hsl(95, 38%, 62%)">"auth"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">error_page</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">400</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">403</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">404</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">500</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">501</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">502</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">503</span><span class="token directive"> </span><span class="token directive number" style="color:hsl(29, 54%, 61%)">504</span><span class="token directive"> /error.html</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># При запросе несуществующего ресурса (например /todos/2223424), вернётся 404, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># которая обработается директивой error_page и вернёт error.html </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># для которого включена basic auth.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Соответственно и этот локейшон в таком случае запросит аутентификацию.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> /todos</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">proxy_ssl_server_name</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">on</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">proxy_intercept_errors</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">on</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">proxy_pass</span><span class="token directive"> https://jsonplaceholder.typicode.com</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-использование-с-директивой-try_files">5. Использование с директивой <code>try_files</code><a href="https://davy.page/nginx-bug#5-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B9-try_files" class="hash-link" aria-label="Прямая ссылка на 5-использование-с-директивой-try_files" title="Прямая ссылка на 5-использование-с-директивой-try_files">​</a></h4>
<p>Используя <code>try_files</code> смотрите, куда вы отправляете nginx за статикой. Вы можете
создать локейшон с <code>auth_basic off</code> и <code>try_files</code>, который будет доставать статику из защищённого
базовой аутентификацией контекста, и в таком случае отключение basic auth в вашем локейшоне работать не будет.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">Пример</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive string" style="color:hsl(95, 38%, 62%)">"auth"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic_user_file</span><span class="token directive"> /etc/nginx/conf.d/.htpasswd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">root</span><span class="token directive"> /usr/share/nginx/html</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Базовая аутентификация все равно будет запрашиваться,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># так как try_files будет запрашивать </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># файлы у рутовой директории, которая защищена basic auth.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">location</span><span class="token directive"> ^~ /htmls</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">auth_basic</span><span class="token directive"> </span><span class="token directive boolean" style="color:hsl(29, 54%, 61%)">off</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">rewrite</span><span class="token directive"> ^/htmls/(.+?)$ /</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$1</span><span class="token directive"> break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token directive keyword" style="color:hsl(286, 60%, 67%)">try_files</span><span class="token directive"> /</span><span class="token directive variable" style="color:hsl(207, 82%, 66%)">$uri</span><span class="token directive"> =404</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content:encoded>
            <category>nginx</category>
        </item>
        <item>
            <title><![CDATA[Одноразовые пароли для доступа по ssh через HashiCorp Vault]]></title>
            <link>https://davy.page/vault-ssh-otp</link>
            <guid>https://davy.page/vault-ssh-otp</guid>
            <pubDate>Sat, 06 Jan 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[HashiCorp Vault имеет в своём арсенале SSH secrets engine, который позволяет организовать]]></description>
            <content:encoded><![CDATA[<p>HashiCorp Vault имеет в своём арсенале SSH secrets engine, который позволяет организовать
защищённый доступ к вашим машинам по ssh, через создание клиентских
сертификатов и одноразовых паролей. Про последнее – создание одноразовых паролей
(OTP) – мы и поговорим в этой статье.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/785052/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/785052/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="как-это-работает">Как это работает?<a href="https://davy.page/vault-ssh-otp#%D0%BA%D0%B0%D0%BA-%D1%8D%D1%82%D0%BE-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82" class="hash-link" aria-label="Прямая ссылка на Как это работает?" title="Прямая ссылка на Как это работает?">​</a></h2>
<p><img decoding="async" loading="lazy" alt="Схема работы" src="https://davy.page/assets/images/vault-otp-scheme-04a85537c6a52d7ad228387016093058.avif" width="964" height="412" class="img_ev3q"></p>
<p>Клиент генерирует OTP для нужного пользователя и ip-адреса, далее обычным <code>ssh username@host</code>
подключается к серверу. Сгенерировать ключ можно напрямую через vault, используя cli, API или
веб-интерфейс, или через вашу внутреннюю систему, которая сама будет дёргать vault API и создавать
OTP.</p>
<p>Когда SSH-сервер получает запрос на аутентификацию, он вызывает PAM (Pluggable Authentication Modules)
модуль, который в процессе выполняет внешнюю команду. Этой внешней командой является
<a href="https://github.com/hashicorp/vault-ssh-helper" target="_blank" rel="noopener noreferrer">vault-ssh-helper</a>, который, в свою очередь,
стучится в ваш Vault-кластер для проверки токена, отправленного клиентом. Если всё ок, то
доступ предоставляется, а токен инвалидируется.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><p>Установка и настройка</p></summary><div><div class="collapsibleContent_i85q"><p>Вся настройка достаточно быстрая и состоит из двух этапов: необходимые
манипуляции внутри кластера Vault и на самом host'е.</p><div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Как всё настроить подробно описано в
<a href="https://developer.hashicorp.com/vault/tutorials/secrets-management/ssh-otp" target="_blank" rel="noopener noreferrer">официальной статье от HashiCorp</a>.
Инструкция ниже это по сути её перевод. Вы можете это пропустить и перейти сразу к нюансам.</p></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="манипуляции-внутри-vaultа">Манипуляции внутри Vault'а<a href="https://davy.page/vault-ssh-otp#%D0%BC%D0%B0%D0%BD%D0%B8%D0%BF%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D0%B8-%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B8-vault%D0%B0" class="hash-link" aria-label="Прямая ссылка на Манипуляции внутри Vault'а" title="Прямая ссылка на Манипуляции внутри Vault'а">​</a></h4><p>Включаем SSH secrets engine.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault secrets </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">enable</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">ssh</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Создаём роль, которая будет использована для генерации OTP ключей для клиентов.
Указываем дефолтного юзера и список разрешённых. А также в <code>cidr_list</code> задаём список
адресов, к которым будут подходить ключи.</p><div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>Рекомендуется создавать по одной роли для каждого пользователя.</p></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault </span><span class="token function" style="color:hsl(207, 82%, 66%)">write</span><span class="token plain"> ssh/roles/otp_role </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">key_type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">otp </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">default_user</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">worker </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">allowed_users</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">worker, worker2 </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">cidr_list</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token number" style="color:hsl(29, 54%, 61%)">10.10</span><span class="token plain">.10.10/32</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Далее осталось создать policy к нашей роли для генерации ключей и сгенерировать access-token, привязанный к этой policy.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">tee</span><span class="token plain"> test.hcl </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;&lt;</span><span class="token string" style="color:hsl(95, 38%, 62%)">EOF</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">path "ssh/creds/otp_role" {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">  capabilities = ["update"]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">EOF</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault policy </span><span class="token function" style="color:hsl(207, 82%, 66%)">write</span><span class="token plain"> otp-polcy ./test.hcl</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Создаём token и сохраняем его, потому что потом запросить его у vault не удастся.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault token create </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-policy</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">otp-polcy</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Key                  Value</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">---                  -----</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">token                hvs.CAESIG1_CrngaECzf6yvTDBgUZz2Lt-mYfdZXogrsiV0ulH1Gh4KHGh2cy4bPmFmN24xNVM5cnBqbFNLTUdpd1JDcTM</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">token_accessor       n76E8Bc8P9SyPLpVZa2EoWGq</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">token_duration       768h</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">token_renewable      </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">token_policies       </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"default"</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"otp-polcy"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">identity_policies    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">policies             </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"default"</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"otp-polcy"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="манипуляции-внутри-нужной-машины">Манипуляции внутри нужной машины<a href="https://davy.page/vault-ssh-otp#%D0%BC%D0%B0%D0%BD%D0%B8%D0%BF%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D0%B8-%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B8-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE%D0%B9-%D0%BC%D0%B0%D1%88%D0%B8%D0%BD%D1%8B" class="hash-link" aria-label="Прямая ссылка на Манипуляции внутри нужной машины" title="Прямая ссылка на Манипуляции внутри нужной машины">​</a></h4><p>Скачиваем последнюю версию vaul-ssh-helper с <a href="https://releases.hashicorp.com/vault-ssh-helper" target="_blank" rel="noopener noreferrer">этой ссылки</a>,
указанной в <a href="https://github.com/hashicorp/vault-ssh-helper" target="_blank" rel="noopener noreferrer">этом репозитории</a>.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">wget</span><span class="token plain"> https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Распаковываем в директорию <code>/usr/local/bin</code>.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">unzip</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-q</span><span class="token plain"> vault-ssh-helper_0.2.1_linux_amd64.zip </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-d</span><span class="token plain"> /usr/local/bin</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Указываем владельцем root'а и устанавливаем права доступа 0755 (rwxr-xr-x).</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">chown</span><span class="token plain"> root:root /usr/local/bin/vault-ssh-helper</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">chmod</span><span class="token plain"> 0755 /usr/local/bin/vault-ssh-helper</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Создаём файл с конфигурацией vault-ssh-helper в директории <code>/etc/vault-ssh-helper.d</code>.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">mkdir</span><span class="token plain"> /etc/vault-ssh-helper.d</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">tee</span><span class="token plain"> /etc/vault-ssh-helper.d/config.hcl </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;&lt;</span><span class="token string" style="color:hsl(95, 38%, 62%)">EOF</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">vault_addr = "VAULT_ADDR"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">tls_skip_verify = false</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">ca_path = "CA_CRT_PATH"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">ssh_mount_point = "ssh"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">allowed_roles = "*"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">EOF</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Меняем конфигурация для PAM sshd (<code>/etc/pam.d/sshd</code>).</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># на всякий случай бэкапим её</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">cp</span><span class="token plain"> /etc/pam.d/sshd /etc/pam.d/sshd.orig</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Комментируем строчку <code>@include common-auth</code> и добавляем следующие две: в них для <code>vault-ssh-helper</code>
указываем конфиг helper'а и файл, куда будут выводиться логи.</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">auth requisite pam_exec.so quiet expose_authtok log=/var/log/vault-ssh.log /usr/local/bin/vault-ssh-helper -config=/etc/vault-ssh-helper.d/config.hcl</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">auth optional pam_unix.so not_set_pass use_first_pass nodelay</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Меняем конфигурацию sshd (<code>/etc/ssh/sshd_config</code>).</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># на всякий случай бэкапим её</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">cp</span><span class="token plain"> /etc/ssh/sshd_config /etc/ssh/sshd_config.orig</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Добавляем вот такие строчки (предварительно проверьте файл, возможно они уже вставлены).</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">KbdInteractiveAuthentication yes</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">UsePAM yes</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">PasswordAuthentication no</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="С�копировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>Старые версии Ubuntu используют <code>ChallengeResponseAuthentication</code> вместо <code>KbdInteractiveAuthentication</code>.</p></div></div><div class="theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>осторожно</div><div class="admonitionContent_BuS1"><p>Так как вы отключаете аутентификацию по паролю, убедитесь, что возможны другие способы
доступа к серверу. Например доступ по ssh ключу у root'а.</p></div></div><p>Перезапускаем sshd.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sudo</span><span class="token plain"> systemctl restart sshd</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="проверка">Проверка<a href="https://davy.page/vault-ssh-otp#%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0" class="hash-link" aria-label="Прямая ссылка на Проверка" title="Прямая ссылка на Проверка">​</a></h4><p>Авторизуемся в vault с токеном, полученным выше.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault login </span><span class="token variable" style="color:hsl(207, 82%, 66%)">$TOKEN</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Генерируем OTP ключ для нужного ip-адреса (юзера не указываем – используется дефолтный).</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault </span><span class="token function" style="color:hsl(207, 82%, 66%)">write</span><span class="token plain"> ssh/creds/otp_key_role </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">ip</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token variable" style="color:hsl(207, 82%, 66%)">$IP_ADDRESS</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Key                Value</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">---                -----</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">lease_id           ssh/creds/otp_key_role/yZaiE4bRiVUVvc6LetQDtDmS</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">lease_duration     768h</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">lease_renewable    </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">ip</span><span class="token plain">                 </span><span class="token number" style="color:hsl(29, 54%, 61%)">10.10</span><span class="token plain">.10.10</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">key                edcf6837-902f-43c6-9e54-c8c26ab80ff3</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">key_type           otp</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">port               </span><span class="token number" style="color:hsl(29, 54%, 61%)">22</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">username           username</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Подключаемся к серверу с полученным ключём.</p><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">ssh</span><span class="token plain"> username@10.10.10.10</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="нюансы">Нюансы<a href="https://davy.page/vault-ssh-otp#%D0%BD%D1%8E%D0%B0%D0%BD%D1%81%D1%8B" class="hash-link" aria-label="Прямая ссылка на Нюансы" title="Прямая ссылка на Нюансы">​</a></h2>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Чтобы лучше понимать некоторые пункты</div><div class="admonitionContent_BuS1"><p><strong>Роль в ssh secret engine</strong> – это конфигурация для генерации SSH-учетных
данных. В рамках OTP она включает в себя такие параметры, как, например:
списки разрешённых ip-адресов и пользователей, а также дефолтное имя пользователя,
для которого сгенерируется OTP в случае, если имя пользователя не будет передано.</p><p><strong>Lease в Vault</strong> – это метаданные, которые содержат информацию о времени
действия, возможности обновления и т.д.,
связанных с каждым динамическим секретом и токеном.</p></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-генерировать-на-одного-юзера-можно-сколько-угодно-ключей">#1 Генерировать на одного юзера можно сколько угодно ключей<a href="https://davy.page/vault-ssh-otp#1-%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%BD%D0%B0-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE-%D1%8E%D0%B7%D0%B5%D1%80%D0%B0-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D1%83%D0%B3%D0%BE%D0%B4%D0%BD%D0%BE-%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%B9" class="hash-link" aria-label="Прямая ссылка на #1 Генерировать на одного юзера можно сколько угодно ключей" title="Прямая ссылка на #1 Генерировать на одного юзера можно сколько угодно ключей">​</a></h4>
<p>Имея токен с доступом к нужной роли ssh engine, можно создавать сколько угодно
одноразовых ключей для всех пользователей и всех машин, которые указаны в
роли. И живут они около месяца. <strong>Поэтому рекомендуется ограничивать конфигурацию роли одним пользователем на одной машине</strong>.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-сгенерированные-ключи-останутся-рабочими-после-удаления-роли">#2 Сгенерированные ключи останутся рабочими после удаления роли<a href="https://davy.page/vault-ssh-otp#2-%D1%81%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8-%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D1%83%D1%82%D1%81%D1%8F-%D1%80%D0%B0%D0%B1%D0%BE%D1%87%D0%B8%D0%BC%D0%B8-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D1%80%D0%BE%D0%BB%D0%B8" class="hash-link" aria-label="Прямая ссылка на #2 Сгенерированные ключи останутся рабочими после удаления роли" title="Прямая ссылка на #2 Сгенерированные ключи останутся рабочими после удаления роли">​</a></h4>
<p>Пока валиден lease созданного ключа, не важно, существует роль, которой его выдали, или нет – ключ останется валидным.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-узнать-сколько-сейчас-неиспользованных-ключей-для-пользователя-невозможно">#3 Узнать, сколько сейчас неиспользованных ключей для пользователя, невозможно<a href="https://davy.page/vault-ssh-otp#3-%D1%83%D0%B7%D0%BD%D0%B0%D1%82%D1%8C-%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D1%81%D0%B5%D0%B9%D1%87%D0%B0%D1%81-%D0%BD%D0%B5%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D1%85-%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%B9-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D0%BD%D0%B5%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE" class="hash-link" aria-label="Прямая ссылка на #3 Узнать, сколько сейчас неиспользованных ключей для пользователя, невозможно" title="Прямая ссылка на #3 Узнать, сколько сейчас неиспользованных ключей для пользователя, невозможно">​</a></h4>
<p>В принципе узнать, сколько было выдано на роль ключей, можно, посмотрев, сколько у этой роли lease'ов, привязанных к ключам.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-s</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-X</span><span class="token plain"> LIST </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-H</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"X-Vault-Token: </span><span class="token string variable" style="color:hsl(207, 82%, 66%)">${VAULT_TOKEN}</span><span class="token string" style="color:hsl(95, 38%, 62%)">"</span><span class="token plain"> </span><span class="token variable" style="color:hsl(207, 82%, 66%)">${VAULT_ADDR}</span><span class="token plain">/v1/sys/leases/lookup/ssh/creds/</span><span class="token variable" style="color:hsl(207, 82%, 66%)">$ROLE_NAME</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Но понять, какой lease указывает на валидный ключ, а какой нет, вы не сможете.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-инвалидировать-ключ-можно-только-отозвав-привязанный-к-нему-lease">#4 Инвалидировать ключ можно только отозвав привязанный к нему lease<a href="https://davy.page/vault-ssh-otp#4-%D0%B8%D0%BD%D0%B2%D0%B0%D0%BB%D0%B8%D0%B4%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%BA%D0%BB%D1%8E%D1%87-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%BE%D1%82%D0%BE%D0%B7%D0%B2%D0%B0%D0%B2-%D0%BF%D1%80%D0%B8%D0%B2%D1%8F%D0%B7%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BA-%D0%BD%D0%B5%D0%BC%D1%83-lease" class="hash-link" aria-label="Прямая ссылка на #4 Инвалидировать ключ можно только отозвав привязанный к нему lease" title="Прямая ссылка на #4 Инвалидировать ключ можно только отозвав привязанный к нему lease">​</a></h4>
<p>Так как ключи живут даже после удаления роли, единственный способ их убить, это отозвать lease.</p>
<p>Можно точечно:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault lease revoke ssh/creds/otp-role/lease-id</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>А можно отрубить сразу lease'ы всех ключей роли:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault lease revoke </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-prefix</span><span class="token plain"> ssh/creds/otp-role</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-по-дефолту-логи-использования-access-tokenов-в-hashicorp-vault-не-ведутся">#5 По дефолту логи использования access-token'ов в HashiCorp Vault не ведутся<a href="https://davy.page/vault-ssh-otp#5-%D0%BF%D0%BE-%D0%B4%D0%B5%D1%84%D0%BE%D0%BB%D1%82%D1%83-%D0%BB%D0%BE%D0%B3%D0%B8-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-access-token%D0%BE%D0%B2-%D0%B2-hashicorp-vault-%D0%BD%D0%B5-%D0%B2%D0%B5%D0%B4%D1%83%D1%82%D1%81%D1%8F" class="hash-link" aria-label="Прямая ссылка на #5 По дефолту логи использования access-token'ов в HashiCorp Vault не ведутся" title="Прямая ссылка на #5 По дефолту логи использования access-token'ов в HashiCorp Vault не ведутся">​</a></h4>
<p>Чтобы узнать какие access-token'ы, когда и для чего использовались, нужно включить запись логов обращения к API.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault audit </span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">enable</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">file</span><span class="token plain"> </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">file_path</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain">ПУТЬ_ДО_ФАЙЛА_КУДА_БУДУТ_СОХРАНЯТЬСЯ_ЛОГИ</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>примечание</div><div class="admonitionContent_BuS1"><p>Файл с логами будет очень жирным.</p></div></div>
<p>Все token'ы и их accessor'ы в логах будут захешированы. Чтобы как-то найти строчки использования
нужного вам token'а, вам придется сначала прогнать его через ту же хеш-функцию, которую использует audit.
И дальше по полученному хешу искать в лог-файле.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vault </span><span class="token function" style="color:hsl(207, 82%, 66%)">write</span><span class="token plain"> sys/audit-hash/file </span><span class="token assign-left variable" style="color:hsl(207, 82%, 66%)">input</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token string" style="color:hsl(95, 38%, 62%)">"&lt;TOKEN ACCESSOR&gt;"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="автоматизация-получение-otp">Автоматизация получение OTP<a href="https://davy.page/vault-ssh-otp#%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-otp" class="hash-link" aria-label="Прямая ссылка на Автоматизация получение OTP" title="Прямая ссылка на Автоматизация получение OTP">​</a></h2>
<p>Автоматизировать этот процесс очень легко благодаря Vault API и гибкой настройке прав доступа через ACL.
По сути просто создаёте пользователя или сразу token с необходимой policy, и можете использовать нужные вам роли
для генерации OTP ключей.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="пример-с-ansible">Пример с Ansible<a href="https://davy.page/vault-ssh-otp#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D1%81-ansible" class="hash-link" aria-label="Прямая ссылка на Пример с Ansible" title="Прямая ссылка на Пример с Ansible">​</a></h4>
<p>Самый, наверное, простой способ – это создать Ansible Playbook, запрашивающий OTP
у vault напрямую модулем <code>community.hashi_vault.vault_write</code>.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Play</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hosts</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> localhost</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">gather_facts</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:hsl(220, 14%, 71%);font-weight:bold">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">tasks</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Get OTP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">community.hashi_vault.vault_write</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">auth_method</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> token</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">url</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain">//vault.service</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">token</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> YOUR_TOKEN</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">path</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> ssh/creds/otp_role</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ip</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> HOST_IP</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">register</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> ssh</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> Setting ssh vars</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ansible.builtin.set_fact</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hashi_host_ip</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'{{ ssh.data.data.ip }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hashi_host_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'{{ ssh.data.data.username }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hashi_host_port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'{{ ssh.data.data.port }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">hashi_host_key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'{{ ssh.data.data.key }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> DBG</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">ansible.builtin.debug</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token key atrule" style="color:hsl(29, 54%, 61%)">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'ip: {{ hashi_host_ip }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'port: {{ hashi_host_port }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'username: {{ hashi_host_username }}'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'password: {{ hashi_host_key }}'</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="пример-с-использованием-api-запросов">Пример с использованием API запросов<a href="https://davy.page/vault-ssh-otp#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D1%81-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC-api-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2" class="hash-link" aria-label="Прямая ссылка на Пример с использованием API запросов" title="Прямая ссылка на Пример с использованием API запросов">​</a></h4>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--location</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'https://vault.service/v1/ssh/creds/otp_role'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--header</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'X-Vault-Token: TOKEN'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--header</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'Content-Type: application/json'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--data</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'{</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">    "ip": "10.10.10.10"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token string" style="color:hsl(95, 38%, 62%)">}'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token plain"> jq </span><span class="token string" style="color:hsl(95, 38%, 62%)">'.data'</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<hr>
<p>Спасибо за чтение! :)</p>]]></content:encoded>
            <category>vault</category>
            <category>ssh</category>
            <category>туториал</category>
        </item>
        <item>
            <title><![CDATA[WebSocket сервер для мини игры обмена файлами (Rust)]]></title>
            <link>https://davy.page/rust-websocket</link>
            <guid>https://davy.page/rust-websocket</guid>
            <pubDate>Fri, 19 May 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Это туториал по написанию небольшого WebSocket сервера для мультиплеерной мини игры. Суть игры простая – обмениваешься файлами с другими игроками в небольшом 2D пространстве. Полный код приложений есть в гитхабе.]]></description>
            <content:encoded><![CDATA[<p>Это туториал по написанию небольшого WebSocket сервера для мультиплеерной мини игры. Суть игры простая – обмениваешься файлами с другими игроками в небольшом 2D пространстве. Полный код приложений есть в <a href="https://github.com/idavydoff/filecats" target="_blank" rel="noopener noreferrer">гитхабе</a>.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" src="https://habrastorage.org/getpro/habr/upload_files/629/15c/ddd/62915cddd2e3aeda06cbe056cc5a7fc8.gif" alt="demo.gif" class="img_ev3q"></p></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/736174/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/736174/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="начало">Начало<a href="https://davy.page/rust-websocket#%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE" class="hash-link" aria-label="Прямая ссылка на Начало" title="П�рямая ссылка на Начало">​</a></h2>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Большая часть объяснений описана в качестве комментариев к коду.</p></div></div>
<p>Создайте проект с помощью команды <code>cargo new &lt;name&gt;</code>. После этого добавьте в файл Cargo.toml все эти зависимости.</p>
<div class="language-toml codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-toml codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token table class-name" style="color:hsl(29, 54%, 61%)">dependencies</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Рантайм для асинхронного кода</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">tokio</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token key property" style="color:hsl(355, 65%, 65%)">version</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"1.28.1"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token key property" style="color:hsl(355, 65%, 65%)">features</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"full"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Асинхронная версия библиотеки tungstenite, реализующей протокол WebSocket, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># работающая в связке с библиотекой tokio.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">tokio-tungstenite</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.18.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Вспомогательные методы для работы с массивами байтов. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">bstr</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"1.4.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Вспомогательные метода для работы асинхронными объектами.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">futures-util</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.3"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Библиотека для работы регулярными выражениями.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">regex</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Mutex, RwLock и тд. быстрее чем в стандартной библиотеке.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">parking_lot</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.12.1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># Генерирует рандомные числа.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token key property" style="color:hsl(355, 65%, 65%)">rand</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.8.5"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="базовые-типы">Базовые типы<a href="https://davy.page/rust-websocket#%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D1%8B%D0%B5-%D1%82%D0%B8%D0%BF%D1%8B" class="hash-link" aria-label="Прямая ссылка на Базовые типы" title="Прямая ссылка на Базовые типы">​</a></h2>
<p>Структура <code>UserFileMessage</code> – хранит в себе информацию о файле, переданную пользователем, а так же имеет метод позволяющий парсить эту информацию из массива байтов. Будет использоваться при получении бинарного сообщения (один из типов сообщений протокола WebSocket) от пользователя, для проверки его валидности.</p>
<p>Структура <code>Connection</code> – хранит в себе идентификатор соединения, а также само соединение, в которое записывается информация и передаётся подключенному юзеру.</p>
<p>Enum <code>BroadcastEvents</code> – содержит список событий, которые могут быть отправлены всем пользователем сразу. Нужен для того чтобы разделить на типы сообщения, получаемые <code>Broadcast</code>’ером (о нём ниже).</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код типов (Файл server/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт с вспомогательными методами для массима байтов </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">bstr</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ByteSlice</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// SplitSink это Sink часть разделённого на два объекта потока. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Подробнее позже</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">futures_util</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">stream</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SplitSink</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Асинхронный TCP стрим </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Тип WebSocket потока и сообщения из него</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio_tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WebSocketStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">UserFileMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Имя пользователя отправившего файл</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Имя файла</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> file_name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Content-Type файла</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> file_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Сам файл </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> file_bytes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserFileMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод из массива байтов собирает структуру UserFileMessage.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Паттерн разделителя, который отделяет каждый фрагмент </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// информации от другого. Например:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// username&lt;pattern&gt;filename&lt;pattern&gt;filetype&lt;pattern&gt;filebytes</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> pattern</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">12</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">226</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">128</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">147</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">226</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">128</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">147</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">226</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">128</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">147</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">226</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">128</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">147</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Делит массив по паттерну</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">split_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">pattern</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params">x</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">filter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params">x</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> x</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">collect</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если разделение прошло на 4 элемента, то все прошло успешно. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если нет, то данные переданы некорректно и нужно возвращать None.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">4</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_utf8_lossy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> file_name </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_utf8_lossy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> file_type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_utf8_lossy</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> file_bytes </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserFileMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> file_name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> file_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> file_bytes </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Рандомный идентификатор соединения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u32</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Sink часть websocket потока для передачи в него информации</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SplitSink</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WebSocketStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">enum</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляет подключение в broadcast'ер</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AddConn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправка всем участникам сообщения о подключении нового</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Join</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправка всем участникам сообщения о выходе игрока. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так же передаём первым элементом идентификатор его</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// подключения, чтобы удалить его из списка.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Quit</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u32</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправка всем участникам полученного от одного из них файла.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SendFile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="broadcast">Broadcast<a href="https://davy.page/rust-websocket#broadcast" class="hash-link" aria-label="Прямая ссылка на Broadcast" title="Прямая ссылка на Broadcast">​</a></h2>
<p><code>Broadcast</code> – это функция, которая будет работать в отдельной <code>Task</code>’е <code>tokio</code>, принимать сигналы от других потоков и в зависимости от полученного сигнала, отправлять всем подключенным игрокам разные сообщения.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p><code>Task</code> в <code>tokio</code> это зелёный (виртуальный) поток. Он управляется рантаймом токио, а не операционной системой.</p></div></div>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код broadcast (Файл server/src/broadcast.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/broadcast.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">collections</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт добавляющий удобные методы для Sink объектов (в </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// нашем случае Sink'ом будет, полученная после деления, вторая часть</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// потока WebSocketStream, в которую мы будем записывать данные, для </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// передачи их пользователю).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">futures_util</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SinkExt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Тип получателя для неограниченного mpsc канала</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UnboundedReceiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Тип сообщения, передаваемого по WebSocket'у</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio_tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">types</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> rx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UnboundedReceiver</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u32</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В цикле ждём новый сигнал </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">while</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> rx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">recv</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> event </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем соединение в список для рассылки</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AddConn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Рассылаем всем юзерам сообщение о подключении нового игрока</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пример сообщения: JOIN|userA</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Join</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> iconn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter_mut</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> iconn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"JOIN|{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Рассылаем всем юзерам сообщение о выходе игрока</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пример сообщения: LEFT|userA</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Quit</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_empty</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter_mut</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"LEFT|{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пересылаем юзерам сообщение с файлом.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как сообщение для пересылки нужно клонировать и при </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// большом количестве игроков это может вызвать замедления в работе</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// функции, максимальный размер файла ограничен 5МБ. (Это будет ниже)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SendFile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> connections</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter_mut</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="состояния-игроков">Состояния игроков<a href="https://davy.page/rust-websocket#%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F-%D0%B8%D0%B3%D1%80%D0%BE%D0%BA%D0%BE%D0%B2" class="hash-link" aria-label="Прямая ссылка на Состояния игроков" title="Прямая ссылка на Состояния игроков">​</a></h2>
<p>Для контроля за состоянием игроков создадим отдельную структуру <code>Game</code>, в которой будем хранить список подключённых пользователей и отправитель сигналов в <code>Broadcast</code>.</p>
<p>Для предотвращения спама файлами, у нас будет стоять небольшой cooldown в 15 секунд для игроков на отправку файла. Поэтому за каждым игроком, кроме его имени и времени последней отправки файла, ничего закреплено не будет.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры Game (Файл server/src/game.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/game.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">collections</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UnboundedSender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">time</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Instant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio_tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">types</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Player</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Время последнего отправленного файла. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как, когда пользователь только зашел, он ещё не успел отправить</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// что-нибудь, записывать в это поле нечего. В таком случае будет</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// выставлено значение енама Option – None.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> dt_last_send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Instant</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Мапа со всеми подключенными играками (Формат: username:Player).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Для того чтобы это поле было доступно для нескольких потоков,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// его необходимо обернуть в смарт-поинтер Arc, которые реализует</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// множественное владение данными в нескольких потоках. А чтобы </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// мапу можно было внутри Arc'а ещё и изменять, нужно дополнительно</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// завернуть её в Mutex. Так же Mutex обезопасит данные, ограничив</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// максимальное количество единовременно изменяемых мапу потоков до одного.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Player</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправитель сигналов в Broadcast</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UnboundedSender</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём новый инстанс</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UnboundedSender</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем игрока и отправляем сигнал в Broadcast.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызов метода send вернёт Result, который мы не хотим в данном</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// случае обрабатывать. Поэтому засунем его в игнорируемую переменную.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так же проверяем есть ли такой игрок уже на сервере и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// не превысит ли количество игроков на сервере 50,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// если игрок подключится. (Максимум 50 игроков)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">add_player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> players </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains_key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"> players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">50</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Player</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> dt_last_send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Join</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем соединение в Broadcast</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">add_connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AddConn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">conn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Удаляем игрока и отправляем сигнал в Broadcast</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">remove_player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u32</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Quit</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Формируем сообщение со списком пользователей.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пример: LIST|userA,userB,userC</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">get_list_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> list_string </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params">w</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> w</span><span class="token number" style="color:hsl(29, 54%, 61%)">.0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">collect</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">join</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">","</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"LIST|{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> list_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляем сообщение с файлом в Broadcast.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Перед этим проверяем прошел или нет у пользователя </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// cooldown на отправку файла.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">send_file</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> players </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">dt_last_send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_none</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">dt_last_send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">elapsed</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">as_secs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SendFile</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        players</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Player</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> dt_last_send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Instant</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">now</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="получение-запросов-на-соединение">Получение запросов на соединение<a href="https://davy.page/rust-websocket#%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%BD%D0%B0-%D1%81%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5" class="hash-link" aria-label="Прямая ссылка на Получение запросов на соединение" title="Прямая ссылка на Получение запросов на соединение">​</a></h2>
<p>Так как WebSocket работает поверх TCP, для начала нам нужно просто создать прослушивающий TCP сокет методом bind у <code>TcpListener</code>’а, и в цикле принимать все запросы на соединение.</p>
<p>Для оптимизации обработки соединений лучше выводить их в отдельный поток. В нашем случае, в <code>Task</code>’у токио.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Начало кода main.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Методы для удобного управления потоком подключения WebSocket</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">futures_util</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamExt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SinkExt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Фунция для принятия WebSocket соединения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio_tungstenite</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">accept_async</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">mpsc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Структура для работы с регулярными выражениями</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">regex</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Regex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Рандомайзер для чисел</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">rand</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Rng</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">types</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserFileMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">game</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">types</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">broadcast</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обязательно навешиваем на main макрос tokio::main, который</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// создаст рантайм токио для исполнения асинхронного кода.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[tokio::main]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём прослушивающий TCP сокет на порте 8080</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> server </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.0.0.0:8080"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём неограниченный канал mpsc</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> broadcast_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">unbounded_channel</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BroadcastEvents</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём новый поток токио и на выполнение ему передаём нашу </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// функцию Broadcast.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token namespace">broadcast</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">broadcast_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> game </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">broadcast_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В цикле принимаем все запросы на соединение</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> _</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">accept</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обрабатываем все соединения в отдельном токио потоке</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">tokio</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Функция обработки соединения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"Connection!"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="обработка-соединений">Обработка соединений<a href="https://davy.page/rust-websocket#%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0-%D1%81%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9" class="hash-link" aria-label="Прямая ссылка на Обработка соединений" title="Прямая ссылка на Обработка соединений">​</a></h2>
<p>Наша функция обработки соединения будет работать в 2 этапа.</p>
<p>На первом этапе она отправит список все подключённых игроков пользователю, добавит соединение в список соединений в <code>Broadcaster</code>’е, чтобы подключенный пользователь уже мог получать данные о выходах и входах других игроков. И после этого будет ждать от пользователя сообщение формата <code>JOIN|&lt;username&gt;</code>. После того, как она его получит, перейдёт ко второму этапу.</p>
<p>На втором этапе она будет в цикле ждать от пользователя сообщений с файлами и рассылать их всем остальным подключённым игрокам. Когда цикл в очередной раз попытается прочитать сообщение и получит ошибку, это будет означать обрыв соединения с пользователем. После этого функция вызовет метод <code>remove_player</code> у инстанса game, что удалит соединение пользователя из <code>Broadcast</code>’а и его ник из списка игроков, а так же сообщит о его отключении всем подключённым пользователям.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код обработчика соединений (Файл server/mail.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Генерируем идентификатор для соединения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> id </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">rand</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">thread_rng</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">gen</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u32</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Производим websocket handshake, после чего получаем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// websocket поток или ошибку. В случае ошибки виртуальный </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// поток токио оборвется.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> websocket </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">accept_async</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Делим поток вебсокета на Sink и Stream объекты </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// для того чтобы можно было читать данные с потока в </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// одном потоке, а получать в другом. В нашем случае </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Sink объект (sender) мы отправим броадкастеру, а с </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Stream продолжим работать тут чтоб получать сообщения.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> websocket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">split</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляем список игроков пользователю</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get_list_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем подключение в список подключений Broadcast</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">add_connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    con</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ждём сообщение входа от пользователя.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если приходят любые другие сообщения, кроме текстовых</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// формата "JOIN|&lt;username&gt;" – игнорируем их.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// При это длина имени игрока не должна превышать 13 символов.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Когда валидное сообщение получено, он добавляет игрока в список и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщает всем остальнм о новом участнике.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">while</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">next</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> msg </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into_text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> re </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Regex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">r"JOIN\|[A-Za-z0-9]*$"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> re</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_match</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">5</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">13</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">add_player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove_player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обработываем полученные сообщения после входа.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Все не бинарные сообщение игнорируем, а бинарные парсим и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// проверяем на валидность. Если размер файла больше 5МБ, или </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// если в сообщении отправителем указан не тот игрок, что </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// записан в соединении – игнорируем. В ином случае, пересылаем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщение всем подключенным игрокам.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">while</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">next</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> msg </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_binary</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserFileMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">file_bytes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">5_000_000</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> username </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send_file</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> msg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Когда соединение оборвано (цикл закончился), удаляем игрока </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// из списка и уведомляем всех остальных об этом.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  game</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove_player</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<hr>
<p>Спасибо за внимание! :) Так же клиентскую часть игры можно найти в репозитории проекта по ссылке ниже.</p>
<p>Ссылка на полный код проекта – <a href="https://github.com/idavydoff/filecats" target="_blank" rel="noopener noreferrer">https://github.com/idavydoff/filecats</a></p>]]></content:encoded>
            <category>rust</category>
            <category>туториал</category>
        </item>
        <item>
            <title><![CDATA[Чат в терминале на Rust]]></title>
            <link>https://davy.page/rust-terminal-chat</link>
            <guid>https://davy.page/rust-terminal-chat</guid>
            <pubDate>Thu, 13 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Эта статья — туториал по написанию небольшого чат сервиса (серверное и клиентское приложения) на Rust, используя функционал TCP сокетов из стандартной библиотеки Rust. Сам чат для пользователя будет выглядеть, как приложение в терминале. Полный код приложений есть в гитхабе.]]></description>
            <content:encoded><![CDATA[<p>Эта статья — туториал по написанию небольшого чат сервиса (серверное и клиентское приложения) на Rust, используя функционал TCP сокетов из стандартной библиотеки Rust. Сам чат для пользователя будет выглядеть, как приложение в терминале. Полный код приложений есть в <a href="https://github.com/idavydoff/terminal-chat" target="_blank" rel="noopener noreferrer">гитхабе</a>.</p>
<div style="display:flex;justify-content:center"><p><img decoding="async" loading="lazy" src="https://habrastorage.org/getpro/habr/upload_files/008/e51/b4d/008e51b4dba38a946787e2a2829f27e8.gif" alt="demo.gif" class="img_ev3q"></p></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>к сведению</div><div class="admonitionContent_BuS1"><p>Ссылка на статью на хабре – <a href="https://habr.com/ru/articles/728870/" target="_blank" rel="noopener noreferrer">https://habr.com/ru/articles/728870/</a></p></div></div>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="начало">Начало<a href="https://davy.page/rust-terminal-chat#%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE" class="hash-link" aria-label="Прямая ссылка на Начало" title="Прямая ссылка на Начало">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>подсказка</div><div class="admonitionContent_BuS1"><p>Много объяснений будет записано в качестве комментариев к коду.</p></div></div>
<p>У нас будет 2 приложения: сервер, который будет принимать сообщения и раздавать их всем пользователям, подключённым к чату, и клиент, который будет показывать юзеру сообщения полученные от сервера и отправлять серверу сообщения от юзера. Создать шаблон для этих приложений можно через <code>cargo new &lt;name&gt;</code>. После этого нашим приложениям надо прописать базовые состояния и типы, которые они будут использовать на протяжении всей свой работы.</p>
<p>Для сервера начнём со структуры <code>Settings</code>. Она будет парсить и сохранять аргументы пользователя при запуске программы. Для парсинга будет использоваться clap.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры Settings на сервере (Файл server/src/settings.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/settings.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Импортирование нужного трейта из clap</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">clap</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Parser</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Объявление того, что будет парсится в качестве аргументов. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// С помощью derive макроса можно навесить на структуру макрос импортированного </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// трейта в качестве атрибута этой структуры. В нашем случае таким образом </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// будет сгенерирован нужный impl c функционалом Parser'а для структуры Args.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Parser)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Макрос arg так же импортируется из clap автоматически</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и позволяет объявить поле аргументом и задать ему нужные свойства.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// short означает, что аргумент можно будет вписать сокращённо</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// вот так "-p 8080". long, что можно использовать </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// полное название "--port 8080". А help это просто вспомогательный </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// текст, который будет показываться при запуске приложения с --help</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[arg(short, long, help = </span><span class="token attribute attr-name string" style="color:hsl(95, 38%, 62%)">"Port that the server will serve"</span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u16</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт Debug позволяет удобно выводить структуру через print в консоль, а </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Clone добавляет функционал для клонирования инстансов структуры.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В derive мы опять передаём макросы этих трейтов чтобы они сгенерировали нам</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// impl'ы с реализациями Debug и Clone, чтобы вручную не писать это.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u16</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Внутри impl прописываются методы структуры</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// используем метод от трейта Parser </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> args </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Args</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">parse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём инстанс структуры Settings и возвращаем его</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> args</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Добавим создание объекта <code>Settings</code> в наш main.rs. После этого при запуске приложения будут запрашиваться аргументы, а нашем случае — порт сервера.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код server/src/main.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// anyhow это небольшая библиотека, которая добавляет enum Result, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// почти аналогичный Result'у из std, с единственным отличием, что этот </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// может принимать любую ошибку</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Импортирование нашей новой структуры</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обязательное указание модуля, иначе файл виден не будет</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создание инстанса нстроек</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> settings </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// возвращение Result::Ok() значения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Следующее, что нужно сделать это структуру состояния (<code>State</code>) нашего серверного приложения. Так как сервер, будет работать сразу в несколько потоков, то и состояние должно поддерживать многопоточность. Для этого внутри структуры данные завёрнуты в <code>Arc</code> и <code>Mutex</code>, подробнее в коде.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры State на сервере (Файл server/src/state.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/state.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Arc (Atomic Reference Counter) это smart pointer, который реализует </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// множественное владение переменной. То-есть, грубо говоря, данные на</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// которые указывает Arc не исчезнут пока есть </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// хотя бы один клон этого Arc'а. По сути, то же самое делает и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Rc (Reference Counter), но Rc не поддерживает многопоточность.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">collections</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Это аналог Mutex'а из стандартной библиотеки, но работающий намного быстрее. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Сам Mutex это структура, которая блокируется для доступа из других потоков,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// если в одном из них она уже используется. И соответственно после использования </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// она становится доступна для других потоков. Это нужно для того чтобы не было </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// рассинхрона данных между потоками. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MutexGuard</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">settings</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Каждый юзер после подключения будет записываться в стейт,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// структура UserData описывает, что будет хранить в себе запись </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// о подключенном юзере. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">UserData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ip адрес подключённого пользователя + его сокета</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">StateData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Настройки приложения, которые мы описали ранее</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// HashMap'а хранящая данные о подключённых юзерах, где ключ это никнейм,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// значение это UserData </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserData</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Arc, как я писал выше реализует множественно владение данными, но он не</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// позволяет эти данные менять. Для этого чтобы это было возможно и безопасно мы</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// дополнительно оборачиваем StateData в Mutex.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StateData</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StateData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод для упрощения доступа к данным. Он блокирует Mutex для работы с </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// данными только в текущем потоке. И возвращает MutexGuard. Пока MutexGuard</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// жив другие потоки не смогут заблокировать данные для себя.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MutexGuard</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StateData</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Реализация трейта Clone для State. Просто повесить макрос трейта Clone </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// через derive не получится, потому что копировать нужно внутренний Arc.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Поэтому необходимые для Clone методы реализуем вручную.  </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Clone</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">clone_from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> source</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token operator" style="color:hsl(207, 82%, 66%)">*</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> source</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь так же перенесём <code>State</code> в нашу main функцию.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Обновлённый код функции main для сервера (Файл server/src/main.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> settings </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Для серверного приложения состояние и базовые параметры готовы, тоже самое нужно прописать для клиента.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры Settings для клиента (Файл client/src/settings.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/settings.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">clap</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Parser</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Parser)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Args</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Адрес сервера с портом, к которому будет производится подключение</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[arg(short, long, help = </span><span class="token attribute attr-name string" style="color:hsl(95, 38%, 62%)">"Server address"</span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> server_address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> args </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Args</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">parse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      server_address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> args</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">address</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p><code>State</code> для клиента немного отличается, но суть та же. Структура, чтобы хранить состояние приложения, с возможностью раздачи его на несколько потоков.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры State для клиента (Файл client/src/state.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/state.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// mpsc нужно для передачи сообщений по каналу между несколькими потоками.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В нашем случае будут два потока (главный и созданный), один из которых</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// будет передавать второму сигналы по каналу mpsc.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// BufReader будем использовать для чтения данных с tcp сокета. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Он работает по такому принципу: делает редкие, но объемные read</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// запросы по файл дескриптору и далее мы можем удобно, что он прочитал.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Для чтения строк из tcp сокета это очень хорошо подходит.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Два трейта. Один для чтения из BufReader'а, другой для записи в файл</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// (в нашем случае в сокет). </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufRead</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Write</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ник, который юзер введёт при запуске приложения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Принимающая часть канала mpsc. В качестве типа передаваемых данных</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// указан unit (пустой tuple), так как нам нужен будет сам факт наличия </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// нового сообщения, его внутренности интересовать не будут.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Указывается как Option, потому что в будет передана другому потоку и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// после этого доступна не будет и тут будет храниться None. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> chat_reload_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Receiver</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Часть канала mpsc, которая отправляет информацию принимающему потоку.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Sender</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В user_input'е будет лежать текущий ввод пользователя. Пример:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// юзер пишет "привет", но не отправляет его в чат. "приве" лежит </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в user_input'е. Обычно такая реализация не требуется, но у нас часто будет</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// полностью перерисовываться чат, и при этом будет пропадать дефолтный </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ввод юзера. Поэтому чтобы это ввод не исчезал, приходится хранить его</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// отдельно. Подробнее об этом будет позже, когда перейдём к месту</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// реализации ввода сообщения. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Массив, полученных с сервера сообщений.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создание mpsc канала. Так как функция вернёт tuple, его можно</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сразу разбить на две переменные</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">channel</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> user_input </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> messages </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> instance </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chat_reload_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> sx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызов метода для получения username'а</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод, который запрашивает у user'а ввод его ника и</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// записывает полученные данные в state.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Для некоторых манипуляций с терминалом, будем использовать termion.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Библиотека позволяет "стирать" все из терминала, красить текст,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// менять режим у stdout'а (об этом позже) и тд. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В данном случае нам нужно очистить терминал. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">clear</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">All</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">print!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"Username: "</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Макрос print! добавляет в буфер текст, но не выполняет flush</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и из-за этого после простого выполнения print! в консоли вы </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ничего не увидите. Чтобы это исправить нужно вызвать flush вручную.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">stdout</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">flush</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Чтение строки из stdin и запись содержимого в username</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// через передачу мутабельной ссылки на username в read_line.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">stdin</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обрезаем с начала и конца ненужные символы </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// (пробелы, перенос строки и тд) и записываем в наш объект State.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Снова всё очищаем.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">clear</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">All</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код функции main для клиента (Файл client/src/main.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">io</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> settings </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в �буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="прописывание-общих-типов-для-клиента-и-сервера">Прописывание общих типов для клиента и сервера<a href="https://davy.page/rust-terminal-chat#%D0%BF%D1%80%D0%BE%D0%BF%D0%B8%D1%81%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BE%D0%B1%D1%89%D0%B8%D1%85-%D1%82%D0%B8%D0%BF%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D0%B0-%D0%B8-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0" class="hash-link" aria-label="Прямая ссылка на Прописывание общих типов для клиента и сервера" title="Прямая ссылка на Прописывание общих типов для клиента и сервера">​</a></h2>
<p>Теперь когда у нас готовы базовые вещи, можно начинать делать логику.</p>
<p>И так, у нас сервер и клиент будут передавать друг другу сообщения в одном и том же формате. Эти сообщения называются “сигналы”. Сам формат сигналов похож на формат передаваемых данных в http, только очень сильно упрощен.</p>
<p>В начале сигнала идут хедеры (список ниже). Хедеры разделяются символами “\r\n”.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">/*</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  Кто отправляет         Поле                 Значение</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  USER                   USERNAME             Строка</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  SERVER                 AUTH_STATUS          "ACCEPTED", "DECLINED"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  USER+SERVER            WITH_MESSAGE         Нет</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  USER+SERVER            SIGNAL_TYPE          "CONNECTION", "NEW_MESSAGE"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  SERVER                 SERVER_MESSAGE       Нет</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">*/</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">/*</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  Определения хедеров</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  USERNAME         Имя пользователя, от которого пришло сообщение</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  AUTH_STATUS      Статус авторизации</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  WITH_MESSAGE     В сигнале есть сообщение</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  SIGNAL_TYPE      Тип сигнала: запрос на авторизацию или сообщение</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  SERVER_MESSAGE   Серверное сообщение</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">*/</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Потом в случае если в хедерах сигнала есть “WITH_MESSAGE”, то после хедеров идет ещё один разделитель “\r\n” и начинается сообщение, которое заканчивается символами “\r\n\r\n”.</p>
<p>Нам нужно уметь парсить сигналы и легко формировать свои. Для этого нужно прописать ряд типов, которые будут иметь вспомогательные методы, которыми мы будем пользоваться.</p>
<p>Перед этим создадим нашу кастомную ошибку, которую мы будем отдавать при возникновении проблем с парсингом.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код кастомной ошибки парсинга (начало файла с типами &lt;client &amp; server&gt;/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">&lt;client &amp; server&gt;/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Импорт утилит для форматирования и вывода строк</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  fmt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Импорт трейта Error (все ошибки как правило должны его имлементить)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">error</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт Debug обязателен для Error, поэтому навешиваем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// макрос Debug на нашу структуру.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// impl Error для структуры. Внутри при желании можно не </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// реализовывать методы, потому что все они реализованы по умолчанию.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Error так же требует реализации трейта fmt::Display</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token namespace">fmt</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Display</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">fmt</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> f</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token namespace">fmt</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Formatter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">fmt</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">write!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">f</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"invalid signal data"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Можно начинать постепенно реализовывать нужные типы. Первым из них будет простенькие <code>enum SignalType.</code> Он описывает 2 варианта возможных типов сигнала: <code>Connection</code> (подключение, отправляется клиентом серверу), <code>NewMessage</code> (новое сообщение, клиент и сервер отправляют их друг другу).</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код enum’а SignalType (продолжение файла с типами &lt;client &amp; server&gt;/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">&lt;client &amp; server&gt;/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone, Copy)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">enum</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт FromStr идет из стандартной библиотеки и добавляет функцию</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// для создания нужного типа из строки.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> s </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"CONNECTION"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"NEW_MESSAGE"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Трейт ToString также идёт из стандартной библиотеки и добавляет функцию</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// для создания уже строки из типа.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ToString</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// .to_owned() делает из заимствованного типа (ссылки), владеющий.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В данном случае делает из &amp;str String. Подробно об этом</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// останавливаться не буду. Лучше отдельно почитать статьи про</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ownership модель в Rust.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"CONNECTION"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"NEW_MESSAGE"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Далее идёт ещё один простой enum <code>AuthStatus</code>. Он содержит значения, которые возвращает сервер в ответ на попытку авторизации юзером. <code>ACCEPTED</code> — авторизация прошла успешно, <code>DENIED</code> — авторизация отклонена. После <code>DENIED</code> соединение сбрасывается.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код enum’а AuthStatus (продолжение файла с типами &lt;client &amp; server&gt;/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">&lt;client &amp; server&gt;/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone, Copy)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">enum</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token constant" style="color:hsl(29, 54%, 61%)">ACCEPTED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token constant" style="color:hsl(29, 54%, 61%)">DENIED</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> s </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"ACCEPTED"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">ACCEPTED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"DENIED"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">DENIED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ToString</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">ACCEPTED</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"ACCEPTED"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">DENIED</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"DENIED"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь нужно реализовать enum <code>SignalHeader</code>. Это уже тип поинтереснее, он содержит хедеры сигнала и значения, которые они передают. Подробнее про то, какие есть хедеры и какие значения имеют я писал выше, поэтому на этом не буду заострять особо внимание.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код enum’а SignalHeader (продолжение файла с типами &lt;client &amp; server&gt;/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">&lt;client &amp; server&gt;/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">enum</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">header</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> value</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">split_once</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token char" style="color:hsl(95, 38%, 62%)">':'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap_or</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> header </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"USERNAME"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">value</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"AUTH_STATUS"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">value</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"SIGNAL_TYPE"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">value</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"WITH_MESSAGE"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token string" style="color:hsl(95, 38%, 62%)">"SERVER_MESSAGE"</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ToString</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"USERNAME: {v}\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"AUTH_STATUS: {}\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"SIGNAL_TYPE: {}\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"WITH_MESSAGE\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"SERVER_MESSAGE\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Осталось создать самую важную для типов структуры — структуру, которая будет формировать и парсить сигнал. Она самая объёмная в плане кода в файле types.rs. Хотя сам код конечно тривиальный.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры SignalData (конец файла с типами &lt;client &amp; server&gt;/src/types.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">&lt;client &amp; server&gt;/src/types.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> password</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> auth_status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> signal_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> with_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">bool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> server_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">bool</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод создания нового инстанса SignalData. В него передаётся </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// массив хедеров, который будет иметь сигнал и сообщение. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как сообщения может не быть, то типом сообщения является</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// enum Option. Этот enum идет с растом из коробки и имеет два значения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Some(v) и None.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">headers</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      password</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      auth_status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      signal_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      with_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      server_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> header </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> headers </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> header </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">auth_status </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">with_message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap_or</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">""</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    data</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод для парсинга данных сигнала. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      password</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      auth_status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      signal_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      with_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      server_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> splitted </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">split</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> string </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> splitted </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> header </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> header </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">auth_status </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">with_message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">with_message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> splitted </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">split_once</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> splitted </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> v</span><span class="token number" style="color:hsl(29, 54%, 61%)">.1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">ends_with</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> string </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> v</span><span class="token number" style="color:hsl(29, 54%, 61%)">.1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token plain">string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">4</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token number" style="color:hsl(29, 54%, 61%)">.1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ParseSignalDataError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ToString</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод для преобразования объекта сигнала в строку, для</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// отправки клиенту/серверу.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> res_str </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">auth_status </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">with_message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    res_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    res_str</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="принятие-запросов-от-клиентов-сервером">Принятие запросов от клиентов сервером<a href="https://davy.page/rust-terminal-chat#%D0%BF%D1%80%D0%B8%D0%BD%D1%8F%D1%82%D0%B8%D0%B5-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%BE%D1%82-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D0%BE%D0%B2-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%BE%D0%BC" class="hash-link" aria-label="Прямая ссылка на Принятие запросов от клиентов сервером" title="Прямая ссылка на Принятие запросов от клиентов сервером">​</a></h2>
<p>Для обмена сигналами клиенту и серверу нужно установить соединение. Для этого мы будем использовать TCP сокеты. Сервер при запуске будет открывать один listening (прослушивающий) сокет (сокет, который слушает запросы на соединение), а клиент будет запрашивать подключение к этому сокету.</p>
<p>Вообщем, нам нужно сначала, чтобы сервер создавал при запуске прослушивающий сокет. Для этого создадим отдельную пустую структуру <code>Service</code>, в которой у нас будет единственный метод, отвечающий за запуск нашего сервиса. Метод будет принимать в себя аргументом state, который мы уже формируем при запуске. Оттуда он возьмёт для себя всё необходимое (пока что это только порт, который привяжется к прослушивающему сокету).</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры Service для сервера (Файл server/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> thread</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">state</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод bind у TcpListener создаст tcp сокет, привяжет к нему </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// адрес, который мы передали, и поставит его в режим прослушивания.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> listener </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.0.0.0:{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод incoming возвращает итератор, который на каждую</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// следующую итерацию вызывает у tcpListener'а метод .accept().</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Этот метод блокирует текущий поток и ждёт пока не появится</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// соединение, которое он сможет принять. Поэтому цикл</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// не умрет, пока жив tcpListener.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> con </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> listener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">incoming</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Для оптимизации работы с подключениями, каждое из них мы будем</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// обрабатывать в отдельном потоке. Важно помнить, что переменные, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// которые используются в потоке, перемещаются в него и обратно не</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// возвращаются)) По крайней мере в нашем случае.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пока что нам с самим соединением делать нечего, так что </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// давайте просто выведем адрес подключенного сокета клиента.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// "?" нужен тут чтобы достать из enum'а Result успешный результат.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как con это enum Result&lt;TcpStream, Error&gt;, а он содержит</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// значения Ok(v) и Err(e), то "?" вернёт нам значение из Ok, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// то-есть TcpStream. В случае если con это Err, то </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ошибка передастся вверх функции родителю. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{:?}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> con</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Осталось вызвать метод run у сервиса в функции main.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Обновленный код функции main для сервера (Файл server/src/main.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">service</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> settings </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь наконец-то можно запустить сервер и увидеть что-то интересное. Впишите в терминале команду cargo run -- --port 8080 (--port это аргумент, который мы определяли в структуре <code>Settings</code>). Дальше попробуйте отправить на этот порт запрос через curl (команда curl 127.0.0.1:8080) и вы должны увидеть в выводе сервера нечто подобное.</p>
<p><img decoding="async" loading="lazy" src="https://habrastorage.org/r/w1560/getpro/habr/upload_files/531/869/d8a/531869d8af80d0fa364031355f15372c.png" alt="вывод сервера" class="img_ev3q"></p>
<p>Он будет выводить вам адреса TCP сокетов клиентов. Так как у любого TCP сокета должен быть какой-то порт, в том числе у того, который производить запрос на подключение, система сама автоматически выдаст ему свободный порт. Поэтому в выводе вы будете видеть локалхост в связке со случайными портами.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="подключение-клиента-к-серверу">Подключение клиента к серверу<a href="https://davy.page/rust-terminal-chat#%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D0%B0-%D0%BA-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D1%83" class="hash-link" aria-label="Прямая ссылка на Подключение клиента к серверу" title="Прямая ссылка на Подключение клиента к серверу">​</a></h2>
<p>Подключение к серверу на клиенте будет завернуто в структуру <code>Connection</code>. В ней будет храниться сам <code>TcpStream</code> (сокет подключённый к серверу) и <code>BufReader</code>, с помощью которого будем читать данные из сокета. Про него я немного рассказал выше в описание кода структуры <code>State</code> для клиента.</p>
<p><code>Connection</code> будет выполнять 2 функции: подключение к серверу с отправлением всех нужных данных (юзернейма и типа сигнала) и чтение данных из сокета. Для этого будут реализованы методы <code>new</code> и <code>read_signal</code> соответственно.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код структуры Connection для клиента (Файл client/src/connection.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/connection.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Write</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufRead</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">types</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// инстанс BufReader'а нужен только для внутреннего пользования,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// поэтому делать его публичным нет смысла</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Формирование сигнала. Передаётся тип сигнала и имя пользователя, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// который подключается.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> signal </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">vec!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод connect у TcpStream создаст TCP сокет, и</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// попытается подключиться к сокету, адрес которого </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// был передан аргументом.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> connection </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">connect</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод write_all запишет байты в сокет и они будут </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// переданы сокету на другом конце, то-есть серверу.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">write_all</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">as_bytes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём инстанс BufReader'а, который будет читать данные с сокета.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> reader </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём инстанс Connection</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> instance </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      reader</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// С сервера должен прийти AuthStatus. Ждём его и когда он приходит</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в зависимости от статуса, либо отдаём ошибку, либо отдаём </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// инстанс Connection.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> data_from_socket </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> data_from_socket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">DENIED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ConnectionAborted</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Access denied"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> res_line </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Индикатор того, что хедеры были прочитаны</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> headers_read </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> buf_line </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ридер читает по одной строчке и записывает в буферную переменную.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если находит ошибку, то всё вылетает. Если он читает 0 байт, то</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// значит, что соединение потеряно (специфика чтения сокетов).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> buf_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">panic!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"Got an error: {}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BrokenPipe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"Connection closed"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">buf_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если он натыкается на "\r\n\r\n", то значит хедеры закончились</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и если нет хедера WITH_MESSAGE, то сигнал можно считать прочитанным</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и возвращать его. Если есть, то цикл уходить на второй круг </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и читает сообщение.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">ends_with</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> headers_read </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        headers_read </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Реализация трейта Clone для Connection. Просто навесить </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// макрос для Clone не получится, потому что нужно чуть иначе клонировать</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// TcpStream и BufReader. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Clone</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Основная часть логики работы клиента будет описываться в структуре <code>Service</code>. В нашем серверном приложении тоже есть такая структура, но там на неё ложиться ответственность только за запуск приложения. В принципе на данном этапе в клиенте нам тоже требуется только описать запуск.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Начало файла client/src/service.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">io</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">connection</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> connection </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> instance </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      state</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь добавим вызов нашего нового метода в <code>main</code> функцию клиента. Пока при запуске приложения он просто подключится к серверу и сразу закроется. Более никаких изменений в <code>main</code>’е клиента не будет.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код main функции клиента (Файл client/src/main.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">io</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">service</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">types</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> settings </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="пул-сообщений-на-сервере-messagespool">Пул сообщений на сервере (MessagesPool)<a href="https://davy.page/rust-terminal-chat#%D0%BF%D1%83%D0%BB-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B9-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5-messagespool" class="hash-link" aria-label="Прямая ссылка на Пул сообщений на сервере (MessagesPool)" title="Прямая ссылка на Пул сообщений на сервере (MessagesPool)">​</a></h2>
<p>Наш сервер будет работать с подключениями в отдельных потоках. Для каждого пользователя будет создано 2 отдельных потока: на принятие сообщений от него и на отправку сообщений ему от других пользователей. Новые сообщения необходимо отправлять всем пользователям чата, то-есть потоки, пользователей, которые отвечают за отправку им новых сообщений должны получить каким-то образом сигнал о том, что в чате появилось новое сообщение и его надо отправить юзеру.</p>
<p>Для решения этой проблемы я решил создавать на время жизни процесса сервера структуру, которая будет хранить в себе списком 256 последних сообщений. Потоки отправляющие сообщения юзеру будут с определённым интервалом читать сообщения из этой структуры, начиная с последнего прочитанного. А в свою очередь потоки принимающие сообщения от пользователей будут в конец списка добавлять новые сообщения.</p>
<p>Опишем тип самого сообщения, которое будет храниться в пуле.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Начало файла server/src/messages_pool.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/messages_pool.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">collections</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">VecDeque</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> iter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token attribute attr-name" style="color:hsl(29, 54%, 61%)">#[derive(Debug, Clone)]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Уникальный идентификатор сообщения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Сообщениям, отправленным сервером ставится true. Это сообщения </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// о входе и выходе пользователя.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> from_server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">bool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      from_server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Далее приступим к описанию самого пула. Простыми словами пул - это просто массив с ограниченной длинной (256 сообщений). Каждое новое сообщения будет добавляться в конец, а если сообщений в пуле 256, то первое сообщение будет удалено для того чтобы в конце освободилось место для нового.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Продолжение файла server/src/messages_pool.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/messages_pool.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">//...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вектор с сообщениям. Используется VecDeque, а не Vec </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// для того чтобы можно было удалять и добавлять сообщения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и в конец и в начало вектора.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">VecDeque</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Для упрощения вычислений индексы сообщений в векторе хранятся </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в отдельной таблице.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Кол-во сообщений в пуле.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u16</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создём вектор на 256 элементов. Метод repeat_with создас бесконечный </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// итератор, который будет повторять одни и теже данные. Далее методом</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// take можно преобразовать этот итератор в итератор поменьше. И </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// collect'ом собираем итератор в коллекцию (в VecDeque в нашем случае).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> arr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">VecDeque</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">iter</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">repeat_with</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">take</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">256</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">collect</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> arr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод push добавляет новое сообщение в пул, обновляет </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// внутренние индексы и увеличивает кол-во сообщений. Если</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// кол-во сообщений в пуле больше 256, то сообщение на нулевом индексе</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// удаляется и в конец записывается новое.   </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">256</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// обновляем пул</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">pop_front</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_back</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// обновляем индексы</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> new_indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">HashMap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// enumerate - метод итератора, позволяющий преобразовать итератор</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в итератор, который вместе с текущим значением, отдаёт</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и текущую итерацию.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">enumerate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        new_indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> index </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">as</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">indexes </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> new_indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// "as u8" преобразует u16 в u8. Мы не можем поставить полю</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// length u8, потому что длина может быть равна 256, а оно </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// не входит в u8.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> index </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">as</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u8</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">index </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">as</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">usize</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Возвращает сообщения, начиная с определённого id</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и id последнего сообщения.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> found_index </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">indexes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Проверяет найдено сообщение с таким id в индексах или нет. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если нет, значит в один момент появилось много новых сообщений и их </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// не успели отправить пользователю. В таком случае читаем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщения с начала списка. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> found_index </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u16</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">as</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">u16</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> sliced_pool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> sliced_pool_last </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> sliced_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">len</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sliced_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sliced_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sliced_pool_last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> last_el </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> index </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> last_el </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> sliced_pool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sliced_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод проверяющий пул на наличие новых сообщений и возвращает их.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">has_new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vec</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> last_el </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> last_el </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Возвращает последнее сообщение в соответствии с текущей длиной пула.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> last_index </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">length</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> last_el </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">last_index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> last_el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">""</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">last_el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="чтение-сигналов-от-пользователя-на-сервере">Чтение сигналов от пользователя на сервере<a href="https://davy.page/rust-terminal-chat#%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D0%B8%D0%B3%D0%BD%D0%B0%D0%BB%D0%BE%D0%B2-%D0%BE%D1%82-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5" class="hash-link" aria-label="Прямая ссылка на Чтение сигналов от пользователя на сервере" title="Прямая ссылка на Чтение сигналов от пользователя на сервере">​</a></h2>
<p>Чтение сигналов от клиента на сервере будет аналогично чтению сигналов от сервера на клиенте, которое мы писали для структуры Connection. Единственное отличие, что привязываться метод чтения сигналов будет не к какой-то структуре, у которой внутри лежит <code>BufReader&lt;TcpStream&gt;</code>, а к нему напрямую через реализацию трейта <code>StreamReader</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Trait StreamReader (Файл server/src/reader.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/reader.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufRead</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">types</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">trait</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">StreamReader</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamReader</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> res_line </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> headers_read </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> buf_line </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> buf_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ConnectionAborted</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"boom boom"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ErrorKind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BrokenPipe</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"boom boom"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">m</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> m</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">buf_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">ends_with</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> headers_read </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        headers_read </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res_line</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="менеджер-подключений-основная-серверная-логика">Менеджер подключений (основная серверная логика)<a href="https://davy.page/rust-terminal-chat#%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80-%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B9-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%B0%D1%8F-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%BD%D0%B0%D1%8F-%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0" class="hash-link" aria-label="Прямая ссылка на Менеджер подключений (основная серверная логика)" title="Прямая ссылка на Менеджер подключений (основная серверная логика)">​</a></h2>
<p>Вся серверная логика будет существовать в рамках структуры <code>Manager</code>. Эта структура будет создаваться отдельно для каждого подключения и заниматься взаимодействием с ним.</p>
<p>Так как логика сама достаточно громоздкая, мы её поделим на два основных типа: работа с сокетом и работа с данными. Разделение это будет производиться за счёт разных <code>trait</code>’ов. То-есть по сути все методы будут привязаны к структуре <code>Manager</code>, но сигнатуры этих методов и реализации будут лежать в отдельных от <code>Manager</code>’а файлах.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Структура Manager (Файл server/src/managers/manager.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/managers/manager.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">messages_pool</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Подключеённый сокет с клиентом</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ридер, которые будет читать данные с сокета</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Состояние приложения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Общий пул сообщений</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Последнее прочитанное из пула сообщение</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> last_read_message_id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Имя присоединённого юзера</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Адрес присоединённого юзера</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> manager </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      last_read_message_id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Так как мы создали структуру <code>Manager</code> в отдельной папке, нам нужно определить эту папку как модуль, чтобы иметь возможность взаимодействовать с ней. Для этого в этой папке создайте файл mod.rs и выведите в публичный доступ структуру <code>Manager</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Файл server/src/mangers/mod.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/mangers/mod.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Файл server/src/mangers/mod.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">manager</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь нужно добавить модуль managers в список модулей в файле main.rs.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Обновление в файле server/src/main.rs</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/main.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Файл server/src/main.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">managers</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>После того как структура <code>Manager</code> и папка для неё были созданы, можно начинать писать два основных <code>trait</code>’а, которые и будут содержать весь функционал менеджера, а именно: <code>StreamManager</code> (взаимодействие с сокетом) и <code>DataManger</code> (взаимодействие с данными).</p>
<p>Начнём с трейта <code>DataManager</code>, так как большая часть его методов потом будет использоваться в <code>StreamManager</code>’е. Итак, он будет содержать следующий функционал: определение стоит или не стоит пускать юзера на сервер, удаление юзера из списка авторизованных и вывод сообщения о его выходе из чата, отправка юзеру новых сообщений и обработка полученных от него.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Код DataManager (Файл server/src/managers/data_manager.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/managers/data_manager.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token plain">thread</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">time</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Duration</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Библиотека для генерации уникальных идентификаторов.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">uuid</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Uuid</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">messages_pool</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">state</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">types</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthConnectionError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">IncomingMessageError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">super</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">manager</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// !! Будет описан ниже !!</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">super</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">stream_manager</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamManager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">trait</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">DataManager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляет клиенту сигнал о неудачной авторизации.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">deny_auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Пытается авторизовать пользоватяля </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// (проверяет есть ли юзер с таким ником на сервере или нет).</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Удаляет юзера из списка подключенных к серверу и </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// отправялет сообщение о его выходе.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">remove_user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В цикле просматривает пул сообщений и отправляет новые пользователю.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Receiver</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Проверяет сигнал нового сообщения и добавляет его в пул сообщений.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_incoming_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">DataManager</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">deny_auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> response </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">vec!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">DENIED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// !! Метод описан в StreamManager ниже !!</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthConnectionError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains_key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthConnectionError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">insert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">UserData</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Uuid</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new_v4</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{} joined the chat!"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            from_server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthConnectionError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connected_user_username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> response </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">vec!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AuthStatus</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token constant" style="color:hsl(29, 54%, 61%)">ACCEPTED</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// !! Метод описан в StreamManager ниже !!</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">remove_user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">contains_key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">users</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Uuid</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new_v4</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{username} left the chat!"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        from_server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Receiver</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Проверяем наличие сообщения от потока, слушающего </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщения от пользователя. Если сообщение есть, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// значит соединение потеряно и можно обрывать цикл. Подробнее </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// об этом в описании трейта StreamManager.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_recv</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как self.messages_pool это Arc, его данные не получиться</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// получить просто прописав self.messages_pool.clone().lock(),</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// из-за того что клоннированная ссылка на пул сообщений удалится</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сразу из-за отсутстивия владельца. Поэтому надо задать ему владельца</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// поместив в отдельную переменную lock_ref.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> lock_ref </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> pool_lock </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> lock_ref</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> messages </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> pool_lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">has_new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">last_read_message_id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> messages </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> v</span><span class="token number" style="color:hsl(29, 54%, 61%)">.1</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">last_read_message_id </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> last</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> message </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> v</span><span class="token number" style="color:hsl(29, 54%, 61%)">.0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> syg_vec </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">vec!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">from_server </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            syg_vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">ServerMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> response </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">syg_vec</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// !! Метод описан в StreamManager ниже !!</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ставим таймаут для цикла так, чтобы он работал быстро, но не слишком. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">sleep</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Duration</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_millis</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Простая проверка структуры сигнала на валидность сообщения.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_incoming_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">with_message </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_none</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">IncomingMessageError</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PoolMessage</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Uuid</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new_v4</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      from_server</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь трейт <code>StreamManager</code>. У него будет 4 основные задачи: обработка подключения, обработка отключения, передача данных юзеру и зацикленное чтение данных из сокета, то-есть сообщений приходящих от юзера.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Trait StreamManager (Файл server/src/managers/stream_manager.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/managers/stream_manager.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Write</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">time</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Duration</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  thread</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Sender</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">reader</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">types</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Импорт из super означает, что мы импортируем из </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// того же пространства имён, в котором находимся.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">super</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">manager</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Даём название новому трейтку и обозначаем, какие функции</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// будут в него входить.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">trait</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">StreamManager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызывается в момент получения нового соединения, то-есть</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сразу после создания инстанса структуры Manager.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызывается, когда соединение с клиентом разрывается.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_disconnection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляет данные в сокет, то-есть юзеру.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">send_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// В цикле в отдельном потоке читает данные с сокета,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// которые посылает юзер.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_signals</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Sender</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamManager</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"Connection established - {}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// С помощью метода read_signal, который мы реализовали для</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// BufReader'а с типом TcpStream, читаем данные, которые юзер</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// отправляет для входа на сервер. Если произошла ошибка, то</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// вызываем метод process_disconnection и прерываем выполнение функции.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> auth_data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_disconnection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Проверяем данные введённые пользователем, в случае если они</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// некорректные, то отсылаем пользователю сообщение с неудачным</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// подключением и обрываем соединение.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">auth_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">deny_auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_disconnection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём канал для общения между потоками. Нужно для того чтобы</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// можно было отправить receiver потоку (главному) сигнал о том, что</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// соединение с пользователем потеряно.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">channel_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> channel_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">mpsc</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">channel</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызываем метода для получения сигналов от пользователя.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_signals</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">channel_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Вызываем метод для мониторинга новых сообщений в пуле. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">channel_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Так как process_messages_pool будет цикличным, будет вызван </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в текущем потоке и его завершение будет означать конец соединения</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// с пользователем, то после него необходимо вызвать process_disconnection.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_disconnection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_disconnection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Удаляем юзера из списка подключённых пользователей</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и выводим в чат сообщением о его уходе.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">is_some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">remove_user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"Connection closed - {}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">send_data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Записываем в сокет через метод write строку в виде байтов.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">write</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">as_bytes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">process_signals</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Sender</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Клонируем переменные для дальнейшей передачи их в </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// новый поток.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> cloned_stream </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> cloned_messages_pool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создание нового потока. Так как переменные с сокетом и пулом</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// мы по сути переносим в новый поток, нам нужно перед объявлением </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// closure (анонимная функция) прописать слово move. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Создаём новый reader и в цикле читаем из него сигналы.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> reader </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">cloned_stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> data_from_socket </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Метод process_incoming_message статический, поэтому вызываем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// его не у инстанса, а у типа напрямую через Self.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">Self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_incoming_message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">cloned_messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> data_from_socket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"invalid message"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Если цикл остановился, значит соединение оборвалось. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Уведомляем основной поток менеджера об этом. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>После того, как у нас описаны два наших главных трейта для <code>Manager</code>’а, нужно вызвать метод process_connection в методе <code>new</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Финальный Manager (Файл server/src/managers/manager.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/managers/manager.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">messages_pool</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">super</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token module-declaration namespace">stream_manager</span><span class="token module-declaration namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">StreamManager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> last_read_message_id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Option</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpStream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> manager </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      reader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">BufReader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      last_read_message_id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      connected_user_username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      connected_peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">try_clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">peer_addr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">process_connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Финальный файл модуля managers (Файл server/src/managers/mod.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/managers/mod.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// Файл server/src/managers/mod.rs</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">stream_manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mod</span><span class="token plain"> </span><span class="token module-declaration namespace">data_manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">manager</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Осталось обновить наш метод run у структуры <code>Service</code>, так чтобы при каждом подключении создавался новый инстанс менеджера.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Финальный Service (Файл server/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">server/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">net</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> thread</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">sync</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">anyhow</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">parking_lot</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">managers</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">messages_pool</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">impl</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> listener </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TcpListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"0.0.0.0:{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">port</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> messages_pool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Arc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Mutex</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">MessagesPool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> con </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> listener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">incoming</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> cloned_state </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> cloned_messages_pool </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Manager</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">con</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> cloned_state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> cloned_messages_pool</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="отправка-и-вывод-сообщений-на-клиенте-основная-клиентская-логика">Отправка и вывод сообщений на клиенте (основная клиентская логика)<a href="https://davy.page/rust-terminal-chat#%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B0-%D0%B8-%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B9-%D0%BD%D0%B0-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D0%B5-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%B0%D1%8F-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%81%D0%BA%D0%B0%D1%8F-%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0" class="hash-link" aria-label="Прямая ссылка на Отправка и вывод сообщений на клиенте (основная клиентская логика)" title="Прямая ссылка на Отправка и вывод сообщений на клиенте (основная клиентская логика)">​</a></h2>
<p>Для того чтобы наш чат стал похож на чат необходимо реализовать считывание вводимых пользователем символов, отправку сообщений на сервер, а также вывод новых. Как оказалось это не так тривиально). Во время разработки этой части, в первую очередь я столкнулся со следующей проблемой: после ввода пользователем сообщения, и нажатия клавиши enter, результат его ввода выводится в терминал и засоряет чат, так как выводится он не в виде сообщения, а просто как строка, которую ввел юзер.</p>
<p>Решить эту проблему можно, переведя терминал в raw mode. В этом режиме программа будет сразу получать сигналы о нажатых кнопках, а так же выводиться в терминал пользователю ничего не будет. Мы будем обрабатывать сигналы о нажатых клавишах, и основываясь на них редактировать ввод пользователя, который хранится у нас в буфере. Собственно, для этого ранее мы и создали поле <code>user_input</code> в состоянии приложения.</p>
<p>Переводить в raw mode наш терминал, слушать нажимаемые пользователем клавиши, красить и стирать символы мы будем с помощью библиотеки <a href="https://crates.io/crates/termion" target="_blank" rel="noopener noreferrer">termion</a>. Всё это будет происходить в основном потоке приложения и описано в отдельном методе структуры <code>Service</code>.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Метод чтения вводимых юзером символов и отправки сообщений (Продолжение файла client/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  thread</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Write</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">FromStr</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">raw</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">IntoRawMode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">input</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">TermRead</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">crate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">settings</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">state</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">connection</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">types</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">read_inputs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Перевод терминала в raw mode через метод полученный </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// от ранее импортированного трейта IntoRawMode. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Обязательно должно быть присвоено к переменной, даже если она не </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// используется, так как в обратном случае он сразу после этой строки</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// снимет raw mode. stdout в данном случае это тип RawTerminal&lt;Stdout&gt;, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и для него отдельно реализован трейт Drop с методом drop,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// который выполняет сам Rust после того, как память выделенная под</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// данные была освобождена. Конкретно в нашем случае метод drop возвращает</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// терминал к прошлому состоянию.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> stdout </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">stdout</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">into_raw_mode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// С помощью метода keys, полученного от трейта TermRead, импортированного </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ранее, получаем итератор нажатых пользователем клавиш. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> stdin </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">stdin</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">keys</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// У всех итераторов есть метод next, которым можно получить</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// следующую итерацию чего-либо.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> input </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> stdin</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">next</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> input </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Определяем какая именно клавиша была нажата</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> key </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// При нажатии на Ctrl+C, останавливаем цикл.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">event</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ctrl</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token char" style="color:hsl(95, 38%, 62%)">'c'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// При нажатии на Enter формируем и отправляем на сервер новое </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщение, при этом очищая user_input. Или в случае, если</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// user_input это пустая строка, перерисовываем чат. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">event</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Char</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token char" style="color:hsl(95, 38%, 62%)">'\n'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> ms </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> ms </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">""</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляет сигнал второму потоку, занимающемуся выводом </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сообщений и пользовательского ввода (он будет ниже), </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// что чат нужно перерисовать. В случае, если получаем ошибку -</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// останавливаем цикл.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clear</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Формируем структуру сигнала.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> signal </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">vec!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">WithMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalHeader</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">ms</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Переводим сигнал в строку, затем в байты и записываем </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// в TcpStream, который является сокетом, соединённым с подключённым</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// сокетом на сервере. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">stream</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">write_all</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">as_bytes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// При нажатии Backspace удаляем из инпута последний символ </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и отправляем сигнал на перерисовывание чата вместе с выводом.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">event</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Backspace</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">pop</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// При нажатии клавиши, являющейся каким-то символом, добавляем его в </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// user_input и отправляем сигнал на </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// перерисовывание чата вместе с выводом.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">event</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Key</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Char</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">k</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">println!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{k}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">k</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Во всех остальных случаях переходим на следующую итерацию loop'а.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        _ </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">continue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>После того, как мы научились отправлять полученные от клиента сообщения на сервер, нужно научиться принимать уже сообщения от сервера. Делается это не очень сложно. В отдельном потоке запускаем цикл, который будет слушать сигналы, полученные от сервера, и новые сообщения добавлять в вектор messages, который мы ранее добавляли в <code>State</code> нашего приложения.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Метод получения новых сообщений от сервера (Продолжение файла client/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">proccess_incoming_messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> messages </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> tx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> connection </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Читаем сигнал из сокета</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> data_from_socket </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_signal</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> v</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> signal </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">from_str</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">data_from_socket</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ставим замок на сообщения, чтобы другие потоки </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// не могли к нему прикасаться</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> messages </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> signal </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Some</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">SignalType</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">NewMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">signal_type </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем разные сообщения в вектор messages в зависимости </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// от того, какого они типа. server_message означает, что </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// это сообщение от сервера, то-есть о выходе/входе пользователя,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// и у него другой немного формат и стили.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавление цветов и стилей сообщению</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token string" style="color:hsl(95, 38%, 62%)">"{}{}{}{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">style</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Faint</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">style</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Bold</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">style</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Reset</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">push</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">format!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                </span><span class="token string" style="color:hsl(95, 38%, 62%)">"&lt;{}&gt; {}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">                s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляем сигнал на перерисовывание чата.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> tx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Остался сам метод, который выводит сообщения и ввод пользователя в терминал. Работать сам метод будет очень просто. Он в отдельном потоке в цикле будет ждать сигналы от других потоков для перерисовки чата и, соответственно, перерисовывать его в момент получения сигнала. Единственная тонкость заключается в том, что этому методу нужно будет передавать в новый поток receiver канала, который используется для передачи сигналов других потоков этому. Суть в том, что receiver нельзя скопировать, так как он может быть только один, поэтому перенос это единственный вариант. Но просто взять и перенести из структуры <code>self</code> его не получится, поэтому этот метод будет брать текущую структуру <code>Service</code>, перетаскивать из неё receiver в поток и возвращать новую структуру <code>Service</code>, но уже без <code>reciever</code>’а.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Метод включения вывода сообщений и текущего ввода пользователя в терминал (Продолжение файла client/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">enable_print</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> rx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">unwrap</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> messages </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> user_input </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token namespace">thread</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">spawn</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token closure-params closure-punctuation punctuation" style="color:hsl(220, 14%, 71%)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Ждём сигналов от других потоков.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">match</span><span class="token plain"> rx</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">recv</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">_</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Очищаем полностью терминал.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">print!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">clear</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">All</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Выводим все сообщения. </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// lock поставит замок на сообщения, iter вернёт итератор, </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// а enumerate вернёт итератор, у которого на каждой итерации</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// дополнительно будет отдаваться и текущий номер итерации.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> m</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">iter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">enumerate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> index </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">print!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"\r\n{m}\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">print!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"{m}\r\n"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Добавляем вывод строки с вводом пользователя.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> input </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token macro property" style="color:hsl(355, 65%, 65%)">print!</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token string" style="color:hsl(95, 38%, 62%)">"{}{}{} &gt;{} {}"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">color</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Bg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">color</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">White</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">color</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Fg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">color</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Black</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token namespace">termion</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">style</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Reset</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        input</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Отправляем все строки из буфера, помещённые туда через </span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// макрос print! в stdout.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token namespace">std</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">stdout</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">flush</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Возвращаем новую структуру.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chat_reload_receiver</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">None</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">chat_reload_sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user_input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">self</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">clone</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Добавляем все написанные методы в методе run структуры <code>Service</code> и всё готово :)</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Финальный метод запуска сервиса клиента (Продолжение файла client/src/service.rs)</summary><div><div class="collapsibleContent_i85q"><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_Ktv7">client/src/service.rs</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">pub</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:hsl(207, 82%, 66%)">run</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">State</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">-&gt;</span><span class="token plain"> </span><span class="token namespace">io</span><span class="token namespace punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Result</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> connection </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">::</span><span class="token function" style="color:hsl(207, 82%, 66%)">new</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">server_address</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">to_owned</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;</span><span class="token plain">state</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">username</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">mut</span><span class="token plain"> instance </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Service</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    connection</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    settings</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    state</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">enable_print</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">proccess_incoming_messages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  instance</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">read_inputs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// +</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Ok</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Скопировать в буфер обмена" title="Скопировать" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>Теперь вы можете запустить клиент командой (только со своим портом) <code>cargo run -- -a 127.0.0.1:8080</code> и у вас откроется поле ввода никнейма, после которого вы перейдёте в чат вашего локального сервера.</p>
<hr>
<p>Спасибо за внимание! :)</p>
<p>Ссылка на полный код проекта — <a href="https://github.com/idavydoff/terminal-chat" target="_blank" rel="noopener noreferrer">https://github.com/idavydoff/terminal-chat</a>
Ссылка на клиент чата на сайте <a href="http://crates.io/" target="_blank" rel="noopener noreferrer">crates.io</a> (быстрая установка для тех, у кого установлен Rust на компьютере) — <a href="https://crates.io/crates/tchat" target="_blank" rel="noopener noreferrer">https://crates.io/crates/tchat</a></p>]]></content:encoded>
            <category>rust</category>
            <category>туториал</category>
        </item>
    </channel>
</rss>