{"id":404718,"date":"2024-06-29T17:52:53","date_gmt":"2024-06-29T17:52:53","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=404718"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T17:52:53","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=404718","title":{"rendered":"<span>\u0427\u0430\u0442 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043d\u0430 Rust<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014  \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0447\u0430\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f) \u043d\u0430 Rust, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b TCP \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Rust. \u0421\u0430\u043c \u0447\u0430\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0435\u0441\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/IDSaves\/terminal-chat\" rel=\"noopener noreferrer nofollow\">\u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/008\/e51\/b4d\/008e51b4dba38a946787e2a2829f27e8.gif\" alt=\"\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0430\u0442\u0430\" title=\"\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0430\u0442\u0430\" width=\"586\" height=\"328\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/008\/e51\/b4d\/008e51b4dba38a946787e2a2829f27e8.gif\"\/><\/p>\n<div><figcaption>\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0430\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<h2> \u041d\u0430\u0447\u0430\u043b\u043e  <\/h2>\n<blockquote>\n<p>\u041c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043a \u043a\u043e\u0434\u0443.<\/p>\n<\/blockquote>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 2 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u043a \u0447\u0430\u0442\u0443, \u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044e\u0437\u0435\u0440\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u044e\u0437\u0435\u0440\u0430. \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>cargo new &lt;name><\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0442\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0439 \u0441\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u0447\u043d\u0451\u043c \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/crates.io\/crates\/clap\" rel=\"noopener noreferrer nofollow\">clap<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0424\u0430\u0439\u043b server\/src\/settings.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/settings.rs  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0439\u0442\u0430 \u0438\u0437 clap use clap::Parser;  \/\/ \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432.  \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e derive \u043c\u0430\u043a\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u0430\u043a\u0440\u043e\u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e  \/\/ \u0442\u0440\u0435\u0439\u0442\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c  \/\/ \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0443\u0436\u043d\u044b\u0439 impl c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c Parser'\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Args. #[derive(Parser)] pub struct Args {   \/\/ \u041c\u0430\u043a\u0440\u043e\u0441 arg \u0442\u0430\u043a \u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437 clap \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438   \/\/ \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430.   \/\/ short \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043a\u0440\u0430\u0449\u0451\u043d\u043d\u043e   \/\/ \u0432\u043e\u0442 \u0442\u0430\u043a \"-p 8080\". long, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c    \/\/ \u043f\u043e\u043b\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \"--port 8080\". \u0410 help \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439    \/\/ \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 --help   #[arg(short, long, help = \"Port that the server will serve\")]   pub port: u16, }  \/\/ \u0422\u0440\u0435\u0439\u0442 Debug \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0447\u0435\u0440\u0435\u0437 print \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0430  \/\/ Clone \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u043b\u044f \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \/\/ \u0412 derive \u043c\u044b \u043e\u043f\u044f\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u044d\u0442\u0438\u0445 \u0442\u0440\u0435\u0439\u0442\u043e\u0432 \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043d\u0430\u043c \/\/ impl'\u044b \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 Debug \u0438 Clone, \u0447\u0442\u043e\u0431\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e. #[derive(Debug, Clone)] pub struct Settings {   pub port: u16, }  \/\/ \u0412\u043d\u0443\u0442\u0440\u0438 impl \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b impl Settings {   pub fn new() -> Settings {     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0442 \u0442\u0440\u0435\u0439\u0442\u0430 Parser      let args = Args::parse();      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e     Settings {        port: args.port,      }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Settings \u0432 \u043d\u0430\u0448 main.rs. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0430 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u043f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 server\/src\/main.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  \/\/ anyhow \u044d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 enum Result,  \/\/ \u043f\u043e\u0447\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 Result'\u0443 \u0438\u0437 std, \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442  \/\/ \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 use anyhow::Result;  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b use settings::Settings;  \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f, \u0438\u043d\u0430\u0447\u0435 \u0444\u0430\u0439\u043b \u0432\u0438\u0434\u0435\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 mod settings;  fn main() -> Result&lt;()> {   \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043d\u0441\u0442\u0440\u043e\u0435\u043a   let settings = Settings::new();      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 Result::Ok() \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (State) \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u0435\u0440\u0432\u0435\u0440, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0442\u043e \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0451\u0440\u043d\u0443\u0442\u044b \u0432 Arc \u0438 Mutex, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u043a\u043e\u0434\u0435. <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b State \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0424\u0430\u0439\u043b server\/src\/state.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/state.rs  use std::{   \/\/ Arc (Atomic Reference Counter) \u044d\u0442\u043e smart pointer, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442    \/\/ \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0422\u043e-\u0435\u0441\u0442\u044c, \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 Arc \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u043d\u0443\u0442 \u043f\u043e\u043a\u0430 \u0435\u0441\u0442\u044c    \/\/ \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043a\u043b\u043e\u043d \u044d\u0442\u043e\u0433\u043e Arc'\u0430. \u041f\u043e \u0441\u0443\u0442\u0438, \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438    \/\/ Rc (Reference Counter), \u043d\u043e Rc \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c.   sync::Arc,    collections::HashMap };  \/\/ \u042d\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433 Mutex'\u0430 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435.  \/\/ \u0421\u0430\u043c Mutex \u044d\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \/\/ \u0435\u0441\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043e\u043d\u0430 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. \u0418 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f  \/\/ \u043e\u043d\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e  \/\/ \u0440\u0430\u0441\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438.  use parking_lot::{Mutex, MutexGuard};  use crate::settings::Settings;  \/\/ \u041a\u0430\u0436\u0434\u044b\u0439 \u044e\u0437\u0435\u0440 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0435\u0439\u0442, \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 UserData \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0437\u0430\u043f\u0438\u0441\u044c  \/\/ \u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u043c \u044e\u0437\u0435\u0440\u0435.  #[derive(Debug, Clone)] pub struct UserData {   \/\/ Ip \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f + \u0435\u0433\u043e \u0441\u043e\u043a\u0435\u0442\u0430   pub address: String, }  #[derive(Debug, Clone)] pub struct StateData {   \/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435   pub settings: Settings,   \/\/ HashMap'\u0430 \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0445 \u044e\u0437\u0435\u0440\u0430\u0445, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u044d\u0442\u043e \u043d\u0438\u043a\u043d\u0435\u0439\u043c,   \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e UserData    pub users: HashMap&lt;String, UserData>, }  \/\/ Arc, \u043a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043d\u043e \u043e\u043d \u043d\u0435 \/\/ \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u043d\u044f\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043c\u044b \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c StateData \u0432 Mutex. pub struct State(Arc&lt;Mutex&lt;StateData>>);  impl State {   pub fn new(settings: Settings) -> State {     State(       Arc::new(Mutex::new(StateData {          settings,          users: HashMap::new()       }))     )   }    \/\/ \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c. \u041e\u043d \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 Mutex \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441    \/\/ \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u0418 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 MutexGuard. \u041f\u043e\u043a\u0430 MutexGuard   \/\/ \u0436\u0438\u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.   pub fn get(&amp;self) -> MutexGuard&lt;StateData> {     self.0.lock()   } }  \/\/ \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u0439\u0442\u0430 Clone \u0434\u043b\u044f State. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0435\u0441\u0438\u0442\u044c \u043c\u0430\u043a\u0440\u043e\u0441 \u0442\u0440\u0435\u0439\u0442\u0430 Clone  \/\/ \u0447\u0435\u0440\u0435\u0437 derive \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 Arc. \/\/ \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f Clone \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u0440\u0443\u0447\u043d\u0443\u044e.   impl Clone for State {   fn clone(&amp;self) -> Self {     State(Arc::clone(&amp;self.0))   }    fn clone_from(&amp;mut self, source: &amp;Self) {     *self = source.clone();   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p> \u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a \u0436\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0451\u043c State \u0432 \u043d\u0430\u0448\u0443 main \u0444\u0443\u043d\u043a\u0446\u0438\u044e.   <\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0424\u0430\u0439\u043b server\/src\/main.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  use anyhow::Result;  use settings::Settings; use state::State; \/\/ +  mod settings; mod state; \/\/ +  fn main() -> Result&lt;()> {   let settings = Settings::new();   let state = State::new(settings)); \/\/ +      Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0433\u043e\u0442\u043e\u0432\u044b, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/settings.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/settings.rs  use clap::Parser;  #[derive(Parser)] pub struct Args { \/\/ \u0410\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u043f\u043e\u0440\u0442\u043e\u043c, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435   #[arg(short, long, help = \"Server address\")]   pub address: String, }  #[derive(Debug, Clone)] pub struct Settings {   pub server_address: String, }  impl Settings {   pub fn new() -> Settings {     let args = Args::parse();          Settings {        server_address: args.address     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>State \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0441\u0443\u0442\u044c \u0442\u0430 \u0436\u0435. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0435\u0433\u043e \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432. <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b State \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/state.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/state.rs  use std::{   sync::{     \/\/ mpsc \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443 \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438.     \/\/ \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u0432\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 (\u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439), \u043e\u0434\u0438\u043d \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445     \/\/ \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443 mpsc.     mpsc::{       Sender,        Receiver,        self     },      Arc   },    io::{     self,      \/\/ BufReader \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 tcp \u0441\u043e\u043a\u0435\u0442\u0430.      \/\/ \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443: \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0435\u0434\u043a\u0438\u0435, \u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u044b\u0435 read     \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u0444\u0430\u0439\u043b \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u0443 \u0438 \u0434\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u043e, \u0447\u0442\u043e \u043e\u043d \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b.     \/\/ \u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0438\u0437 tcp \u0441\u043e\u043a\u0435\u0442\u0430 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.     BufReader,   \/\/ \u0414\u0432\u0430 \u0442\u0440\u0435\u0439\u0442\u0430. \u041e\u0434\u0438\u043d \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 BufReader'\u0430, \u0434\u0440\u0443\u0433\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0444\u0430\u0439\u043b \/\/ (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u0441\u043e\u043a\u0435\u0442).      BufRead,      Write   } };  use parking_lot::Mutex;  pub struct State {   \/\/ \u041d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044e\u0437\u0435\u0440 \u0432\u0432\u0435\u0434\u0451\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   pub username: String,    \/\/ \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u0430 mpsc. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   \/\/ \u0443\u043a\u0430\u0437\u0430\u043d unit (\u043f\u0443\u0441\u0442\u043e\u0439 tuple), \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u0430\u043c \u0444\u0430\u043a\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u044f    \/\/ \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0435\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443\u0442.   \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a Option, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443 \u0438    \/\/ \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438 \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f None.    pub chat_reload_receiver: Option&lt;Receiver&lt;()>>,    \/\/ \u0427\u0430\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u0430 mpsc, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443.   pub chat_reload_sender: Sender&lt;()>,    \/\/ \u0412 user_input'\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u0432\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u0440\u0438\u043c\u0435\u0440:   \/\/ \u044e\u0437\u0435\u0440 \u043f\u0438\u0448\u0435\u0442 \"\u043f\u0440\u0438\u0432\u0435\u0442\", \u043d\u043e \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0447\u0430\u0442. \"\u043f\u0440\u0438\u0432\u0435\" \u043b\u0435\u0436\u0438\u0442    \/\/ \u0432 user_input'\u0435. \u041e\u0431\u044b\u0447\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043d\u043e \u0443 \u043d\u0430\u0441 \u0447\u0430\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u0442   \/\/ \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0430\u0442, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439    \/\/ \u0432\u0432\u043e\u0434 \u044e\u0437\u0435\u0440\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0432\u0432\u043e\u0434 \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u0430\u043b, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e   \/\/ \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043c\u0435\u0441\u0442\u0443   \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.    pub user_input: Arc&lt;Mutex&lt;String>>,    \/\/ \u041c\u0430\u0441\u0441\u0438\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.   pub messages: Arc&lt;Mutex&lt;Vec&lt;String>>> }  impl State {   pub fn new() -> io::Result&lt;State> {     \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 mpsc \u043a\u0430\u043d\u0430\u043b\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0435\u0440\u043d\u0451\u0442 tuple, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e     \/\/ \u0441\u0440\u0430\u0437\u0443 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u0434\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     let (sx, rx) = mpsc::channel::&lt;()>();      let user_input = Arc::new(Mutex::new(String::new()));     let messages = Arc::new(Mutex::new(Vec::&lt;String>::new()));      let mut instance = State {       username: String::new(),       chat_reload_receiver: Some(rx),       chat_reload_sender: sx,       user_input,       messages,     };      \/\/ \u0412\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f username'\u0430     instance.read_username()?;      Ok(instance)   }    \/\/ \u041c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0443 user'\u0430 \u0432\u0432\u043e\u0434 \u0435\u0433\u043e \u043d\u0438\u043a\u0430 \u0438   \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 state.   fn read_username(&amp;mut self) -> io::Result&lt;()> {     \/\/ \u0414\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u043c, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c termion.     \/\/ \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \"\u0441\u0442\u0438\u0440\u0430\u0442\u044c\" \u0432\u0441\u0435 \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430, \u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442,     \/\/ \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u0443 stdout'\u0430 (\u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435) \u0438 \u0442\u0434.      \/\/ \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b.      println!(\"{}\", termion::clear::All); print!(\"Username: \");      \/\/ \u041c\u0430\u043a\u0440\u043e\u0441 print! \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u0431\u0443\u0444\u0435\u0440 \u0442\u0435\u043a\u0441\u0442, \u043d\u043e \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 flush     \/\/ \u0438 \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f print! \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0432\u044b      \/\/ \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442\u0435. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c flush \u0432\u0440\u0443\u0447\u043d\u0443\u044e.     std::io::stdout().flush()?;      let mut username = String::new();      \/\/ \u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 stdin \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0432 username     \/\/ \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 username \u0432 read_line.     io::stdin().read_line(&amp;mut username)?;      \/\/ \u041e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438 \u043a\u043e\u043d\u0446\u0430 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b      \/\/ (\u043f\u0440\u043e\u0431\u0435\u043b\u044b, \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0442\u0434) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043d\u0430\u0448 \u043e\u0431\u044a\u0435\u043a\u0442 State.     self.username = username.trim().to_owned();      \/\/ \u0421\u043d\u043e\u0432\u0430 \u0432\u0441\u0451 \u043e\u0447\u0438\u0449\u0430\u0435\u043c.     println!(\"{}\", termion::clear::All);      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/main.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/main.rs  use std::io;  use crate::{   settings::Settings,    state::State };  mod settings; mod state;  fn main() -> io::Result&lt;()> {   let settings = Settings::new();   let state = State::new()?;    Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0449\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0433\u043e\u0442\u043e\u0432\u044b \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0434\u0435\u043b\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>\u0418 \u0442\u0430\u043a, \u0443 \u043d\u0430\u0441 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0438 \u0442\u043e\u043c \u0436\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u042d\u0442\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u201c\u0441\u0438\u0433\u043d\u0430\u043b\u044b\u201d. \u0421\u0430\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 http, \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d.<\/p>\n<p>\u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0438\u0434\u0443\u0442 \u0445\u0435\u0434\u0435\u0440\u044b (\u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0438\u0436\u0435). \u0425\u0435\u0434\u0435\u0440\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u201c\\r\\n\u201d.<\/p>\n<pre><code class=\"rust\">\/*   \u041a\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442         \u041f\u043e\u043b\u0435                 \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435    USER                   USERNAME             \u0421\u0442\u0440\u043e\u043a\u0430   SERVER                 AUTH_STATUS          \"ACCEPTED\", \"DECLINED\"   USER+SERVER            WITH_MESSAGE         \u041d\u0435\u0442   USER+SERVER            SIGNAL_TYPE          \"CONNECTION\", \"NEW_MESSAGE\"   SERVER                 SERVER_MESSAGE       \u041d\u0435\u0442 *\/  \/*   \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0445\u0435\u0434\u0435\u0440\u043e\u0432    USERNAME         \u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   AUTH_STATUS      \u0421\u0442\u0430\u0442\u0443\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438   WITH_MESSAGE     \u0412 \u0441\u0438\u0433\u043d\u0430\u043b\u0435 \u0435\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   SIGNAL_TYPE      \u0422\u0438\u043f \u0441\u0438\u0433\u043d\u0430\u043b\u0430: \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   SERVER_MESSAGE   \u0421\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 *\/<\/code><\/pre>\n<p>\u041f\u043e\u0442\u043e\u043c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0432 \u0445\u0435\u0434\u0435\u0440\u0430\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0435\u0441\u0442\u044c \u201cWITH_MESSAGE\u201d, \u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0445\u0435\u0434\u0435\u0440\u043e\u0432 \u0438\u0434\u0435\u0442 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u201c\\r\\n\u201d \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u201c\\r\\n\\r\\n\u201d.<\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u0438 \u043b\u0435\u0433\u043a\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u044f\u0434 \u0442\u0438\u043f\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448\u0443 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u043e\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 (\u043d\u0430\u0447\u0430\u043b\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 &lt;client &amp; server>\/src\/types.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b &lt;client &amp; server>\/src\/types.rs  use std::{   \/\/ \u0418\u043c\u043f\u043e\u0440\u0442 \u0443\u0442\u0438\u043b\u0438\u0442 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u043e\u043a   fmt,     \/\/ \u0418\u043c\u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u0439\u0442\u0430 Error (\u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0435\u0433\u043e \u0438\u043c\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0442\u044c)   error::Error };  \/\/ \u0422\u0440\u0435\u0439\u0442 Debug \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u0434\u043b\u044f Error, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u0435\u043c  \/\/ \u043c\u0430\u043a\u0440\u043e\u0441 Debug \u043d\u0430 \u043d\u0430\u0448\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. #[derive(Debug)] pub struct ParseSignalDataError;  \/\/ impl Error \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0412\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0435  \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. impl Error for ParseSignalDataError {}  \/\/ Error \u0442\u0430\u043a \u0436\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0440\u0435\u0439\u0442\u0430 fmt::Display impl fmt::Display for ParseSignalDataError {   fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -> fmt::Result {     write!(f, \"invalid signal data\")   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0442\u0438\u043f\u044b. \u041f\u0435\u0440\u0432\u044b\u043c \u0438\u0437 \u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0435 enum SignalType. \u041e\u043d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u0430: Connection (\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0443), NewMessage (\u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0438\u0445 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443).<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 enum\u2019\u0430 SignalType (\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 &lt;client &amp; server>\/src\/types.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b &lt;client &amp; server>\/src\/types.rs  \/\/ ...  #[derive(Debug, Clone, Copy)] pub enum SignalType {   Connection,   NewMessage, }  \/\/ \u0422\u0440\u0435\u0439\u0442 FromStr \u0438\u0434\u0435\u0442 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \/\/ \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438. impl FromStr for SignalType {   type Err = ParseSignalDataError;    fn from_str(s: &amp;str) -> Result&lt;Self, Self::Err> {     match s {       \"CONNECTION\" => Ok(SignalType::Connection),       \"NEW_MESSAGE\" => Ok(SignalType::NewMessage),       _ => Err(ParseSignalDataError)     }   } }  \/\/ \u0422\u0440\u0435\u0439\u0442 ToString \u0442\u0430\u043a\u0436\u0435 \u0438\u0434\u0451\u0442 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \/\/ \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0436\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0442\u0438\u043f\u0430. impl ToString for SignalType {   fn to_string(&amp;self) -> String {     match self {       \/\/ .to_owned() \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0437 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 (\u0441\u0441\u044b\u043b\u043a\u0438), \u0432\u043b\u0430\u0434\u0435\u044e\u0449\u0438\u0439.       \/\/ \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0437 &amp;str String. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c       \/\/ \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0443. \u041b\u0443\u0447\u0448\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e       \/\/ ownership \u043c\u043e\u0434\u0435\u043b\u044c \u0432 Rust.       SignalType::Connection => \"CONNECTION\".to_owned(),       SignalType::NewMessage => \"NEW_MESSAGE\".to_owned(),     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0451\u0442 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 enum AuthStatus. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u044e\u0437\u0435\u0440\u043e\u043c. ACCEPTED \u2014 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, DENIED \u2014 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0430. \u041f\u043e\u0441\u043b\u0435 DENIED \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f. <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 enum\u2019\u0430 AuthStatus  (\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 &lt;client &amp; server>\/src\/types.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b &lt;client &amp; server>\/src\/types.rs  \/\/ ...  #[derive(Debug, Clone, Copy)] pub enum AuthStatus {   ACCEPTED,   DENIED }  impl FromStr for AuthStatus {   type Err = ParseSignalDataError;    fn from_str(s: &amp;str) -> Result&lt;Self, Self::Err> {     match s {       \"ACCEPTED\" => Ok(AuthStatus::ACCEPTED),       \"DENIED\" => Ok(AuthStatus::DENIED),       _ => Err(ParseSignalDataError)     }   } }  impl ToString for AuthStatus {   fn to_string(&amp;self) -> String {     match self {       AuthStatus::ACCEPTED => \"ACCEPTED\".to_owned(),       AuthStatus::DENIED => \"DENIED\".to_owned()     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c enum SignalHeader. \u042d\u0442\u043e \u0443\u0436\u0435 \u0442\u0438\u043f \u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435, \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0445\u0435\u0434\u0435\u0440\u044b \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442.  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a\u0438\u0435 \u0435\u0441\u0442\u044c \u0445\u0435\u0434\u0435\u0440\u044b \u0438 \u043a\u0430\u043a\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u044d\u0442\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0443 \u0437\u0430\u043e\u0441\u0442\u0440\u044f\u0442\u044c \u043e\u0441\u043e\u0431\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 enum\u2019\u0430 SignalHeader  (\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 &lt;client &amp; server>\/src\/types.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b &lt;client &amp; server>\/src\/types.rs  \/\/ ...  pub enum SignalHeader {   Username(String),   AuthStatus(AuthStatus),   SignalType(SignalType),   WithMessage,   ServerMessage }  impl FromStr for SignalHeader {   type Err = ParseSignalDataError;    fn from_str(s: &amp;str) -> Result&lt;Self, Self::Err> {     let (header, value) = s.split_once(':').unwrap_or((s, s));      match header {       \"USERNAME\" => Ok(SignalHeader::Username(value.trim().to_owned())),       \"AUTH_STATUS\" => {         match AuthStatus::from_str(value.trim()) {           Ok(v) => return Ok(SignalHeader::AuthStatus(v)),           Err(_) => Err(ParseSignalDataError)         }       },       \"SIGNAL_TYPE\" => {         match SignalType::from_str(value.trim()) {           Ok(v) => return Ok(SignalHeader::SignalType(v)),           Err(_) => Err(ParseSignalDataError)         }       }       \"WITH_MESSAGE\" => Ok(SignalHeader::WithMessage),       \"SERVER_MESSAGE\" => Ok(SignalHeader::ServerMessage),       _ => Err(ParseSignalDataError)     }   } }  impl ToString for SignalHeader {   fn to_string(&amp;self) -> String {     match self {       SignalHeader::Username(v) => format!(\"USERNAME: {v}\\r\\n\"),       SignalHeader::AuthStatus(v) => format!(\"AUTH_STATUS: {}\\r\\n\", v.to_string()),       SignalHeader::SignalType(v) => format!(\"SIGNAL_TYPE: {}\\r\\n\", v.to_string()),       SignalHeader::WithMessage => \"WITH_MESSAGE\\r\\n\".to_owned(),       SignalHeader::ServerMessage => \"SERVER_MESSAGE\\r\\n\".to_owned()     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c\u0443\u044e \u0432\u0430\u0436\u043d\u0443\u044e \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b. \u041e\u043d\u0430 \u0441\u0430\u043c\u0430\u044f \u043e\u0431\u044a\u0451\u043c\u043d\u0430\u044f \u0432 \u043f\u043b\u0430\u043d\u0435 \u043a\u043e\u0434\u0430 \u0432 \u0444\u0430\u0439\u043b\u0435 types.rs. \u0425\u043e\u0442\u044f \u0441\u0430\u043c \u043a\u043e\u0434 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b SignalData (\u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 &lt;client &amp; server>\/src\/types.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b &lt;client &amp; server>\/src\/types.rs  \/\/ ...  #[derive(Debug, Clone)] pub struct SignalData {   pub username: Option&lt;String>,   pub password: Option&lt;String>,   pub key: Option&lt;String>,   pub auth_status: Option&lt;AuthStatus>,   pub signal_type: Option&lt;SignalType>,   pub with_message: bool,   pub message: Option&lt;String>,   pub server_message: bool }  impl SignalData {   \/\/ \u041c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 SignalData. \u0412 \u043d\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f    \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0445\u0435\u0434\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.    \/\/ \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0431\u044b\u0442\u044c, \u0442\u043e \u0442\u0438\u043f\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f   \/\/ enum Option. \u042d\u0442\u043e\u0442 enum \u0438\u0434\u0435\u0442 \u0441 \u0440\u0430\u0441\u0442\u043e\u043c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0438 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   \/\/ Some(v) \u0438 None.   pub fn new(headers: Vec&lt;SignalHeader>, message: Option&lt;&amp;str>) -> SignalData {     let mut data = SignalData {       username: None,       password: None,       key: None,       auth_status: None,       signal_type: None,       with_message: false,       message: None,       server_message: false     };      for header in headers {       match header {         SignalHeader::Username(v) => {           data.username = Some(v);         },         SignalHeader::AuthStatus(v) => {           data.auth_status = Some(v);         },         SignalHeader::SignalType(v) => {           data.signal_type = Some(v);         },         SignalHeader::WithMessage => {           data.with_message = true;           data.message = Some(message.unwrap_or(\"\").to_owned());         },         SignalHeader::ServerMessage => {           data.server_message = true;         }       }     }      data   } }  impl FromStr for SignalData {   type Err = ParseSignalDataError;    \/\/ \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u0430.    fn from_str(s: &amp;str) -> Result&lt;Self, Self::Err> {     let mut data = SignalData {        username: None,        password: None,        key: None,        auth_status: None,        signal_type: None,       with_message: false,       message: None,       server_message: false,     };     let splitted = s.split(\"\\r\\n\");     for string in splitted {       let header = match SignalHeader::from_str(string) {         Ok(v) => v,         Err(_) => continue       };        match header {         SignalHeader::Username(v) => {           data.username = Some(v);         },         SignalHeader::AuthStatus(v) => {           data.auth_status = Some(v);         },         SignalHeader::SignalType(v) => {           data.signal_type = Some(v);         }         SignalHeader::WithMessage => {           data.with_message = true;         },         SignalHeader::ServerMessage => {           data.server_message = true;         }       }     }      if data.with_message {       let splitted = s.split_once(\"\\r\\n\\r\\n\");       if let Some(v) = splitted {         if v.1.ends_with(\"\\r\\n\\r\\n\") {           let string = v.1.to_owned();           data.message = Some(string[..string.len() - 4].to_owned());         }         else {           data.message = Some(v.1.to_owned());         }       }       else {         return Err(ParseSignalDataError);       }     }      if let None = data.signal_type {       return Err(ParseSignalDataError)     }      Ok(data)   } }  impl ToString for SignalData {   \/\/ \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0434\u043b\u044f   \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0443\/\u0441\u0435\u0440\u0432\u0435\u0440\u0443.   fn to_string(&amp;self) -> String {     let mut res_str = String::new();      if let Some(v) = &amp;self.username {       res_str.push_str(&amp;SignalHeader::Username(v.to_owned()).to_string());     }     if let Some(v) = &amp;self.auth_status {       res_str.push_str(&amp;SignalHeader::AuthStatus(v.clone()).to_string());     }     if let Some(v) = &amp;self.signal_type {       res_str.push_str(&amp;SignalHeader::SignalType(v.clone()).to_string());     }     if self.server_message {       res_str.push_str(&amp;SignalHeader::ServerMessage.to_string());     }     if self.with_message {       if let Some(v) = &amp;self.message {         res_str.push_str(&amp;SignalHeader::WithMessage.to_string());         res_str.push_str(\"\\r\\n\");         res_str.push_str(&amp;v);       }     }     res_str.push_str(\"\\r\\n\\r\\n\");      res_str   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c  <\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0430\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c TCP \u0441\u043e\u043a\u0435\u0442\u044b. \u0421\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d listening (\u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u044e\u0449\u0438\u0439) \u0441\u043e\u043a\u0435\u0442 (\u0441\u043e\u043a\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435), \u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u043a\u0435\u0442\u0443.<\/p>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u043a\u0435\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Service, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u041c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c state, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0443\u0436\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041e\u0442\u0442\u0443\u0434\u0430 \u043e\u043d \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0432\u0441\u0451 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 (\u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0440\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0432\u044f\u0436\u0435\u0442\u0441\u044f \u043a \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u044e\u0449\u0435\u043c\u0443 \u0441\u043e\u043a\u0435\u0442\u0443).<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Service \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0424\u0430\u0439\u043b server\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/service.rs  use std::{net::TcpListener, thread, sync::Arc}; use anyhow::Result; use parking_lot::Mutex;  use crate::state::State;  pub struct Service;  impl Service {   pub fn run(state: State) -> Result&lt;()> {     \/\/ \u041c\u0435\u0442\u043e\u0434 bind \u0443 TcpListener \u0441\u043e\u0437\u0434\u0430\u0441\u0442 tcp \u0441\u043e\u043a\u0435\u0442, \u043f\u0440\u0438\u0432\u044f\u0436\u0435\u0442 \u043a \u043d\u0435\u043c\u0443      \/\/ \u0430\u0434\u0440\u0435\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438, \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0435\u0433\u043e \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u044f.     let listener = TcpListener::bind(format!(\"0.0.0.0:{}\", state.get().settings.port))?;      \/\/ \u041c\u0435\u0442\u043e\u0434 incoming \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e     \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0443 tcpListener'\u0430 \u043c\u0435\u0442\u043e\u0434 .accept().     \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u0436\u0434\u0451\u0442 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f     \/\/ \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u043d \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0446\u0438\u043a\u043b     \/\/ \u043d\u0435 \u0443\u043c\u0440\u0435\u0442, \u043f\u043e\u043a\u0430 \u0436\u0438\u0432 tcpListener.     for con in listener.incoming() {        \/\/ \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c       \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435,        \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043d\u0435\u0433\u043e \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043d\u0435       \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f)) \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435.       thread::spawn(move || -> Result&lt;()> {          \/\/ \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0430\u043c \u0441 \u0441\u0430\u043c\u0438\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0447\u0435\u0433\u043e, \u0442\u0430\u043a \u0447\u0442\u043e          \/\/ \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043a\u0435\u0442\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430.          \/\/ \"?\" \u043d\u0443\u0436\u0435\u043d \u0442\u0443\u0442 \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0438\u0437 enum'\u0430 Result \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.         \/\/ \u0422\u0430\u043a \u043a\u0430\u043a con \u044d\u0442\u043e enum Result&lt;TcpStream, Error>, \u0430 \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442         \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f Ok(v) \u0438 Err(e), \u0442\u043e \"?\" \u0432\u0435\u0440\u043d\u0451\u0442 \u043d\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 Ok,          \/\/ \u0442\u043e-\u0435\u0441\u0442\u044c TcpStream. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 con \u044d\u0442\u043e Err, \u0442\u043e          \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442\u0441\u044f \u0432\u0432\u0435\u0440\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044e.          println!(\"{:?}\", con?.peer_addr());          Ok(())       });     }      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p> \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 run \u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main. <\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0424\u0430\u0439\u043b server\/src\/main.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  use anyhow::Result;  use service::Service; use settings::Settings; use state::State;  mod settings; mod state; mod service;  fn main() -> Result&lt;()> {   let settings = Settings::new();   let state = State::new(settings);       Service::run(state)?; \/\/ +      Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435. \u0412\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 cargo run &#8212; &#8212;port 8080 (&#8212;port \u044d\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043b\u0438 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 Settings). \u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 curl (\u043a\u043e\u043c\u0430\u043d\u0434\u0430 curl 127.0.0.1:8080) \u0438 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u0432\u044b\u0432\u043e\u0434\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435.   <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/531\/869\/d8a\/531869d8af80d0fa364031355f15372c.png\" alt=\"\u0412\u044b\u0432\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\" title=\"\u0412\u044b\u0432\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\" width=\"992\" height=\"346\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/531\/869\/d8a\/531869d8af80d0fa364031355f15372c.png\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0432\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0430\u043c \u0430\u0434\u0440\u0435\u0441\u0430 TCP \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432. \u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043b\u044e\u0431\u043e\u0433\u043e TCP \u0441\u043e\u043a\u0435\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u043e\u0440\u0442, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0443 \u0442\u043e\u0433\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u0430\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0434\u0430\u0441\u0442 \u0435\u043c\u0443 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043f\u043e\u0440\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0432\u044b\u0432\u043e\u0434\u0435 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u0445\u043e\u0441\u0442 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438.<\/p>\n<h2>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443  <\/h2>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442\u043e \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Connection. \u0412 \u043d\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0441\u0430\u043c TcpStream (\u0441\u043e\u043a\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443) \u0438 BufReader, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430. \u041f\u0440\u043e \u043d\u0435\u0433\u043e \u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u0432\u044b\u0448\u0435 \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b State \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<p>Connection \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c 2 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (\u044e\u0437\u0435\u0440\u043d\u0435\u0439\u043c\u0430 \u0438 \u0442\u0438\u043f\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0430) \u0438 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b new \u0438 read_signal \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Connection \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/connection.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/connection.rs  use std::{   net::TcpStream,    io::{     self,      Write,     Error,      ErrorKind,      BufRead,      BufReader   }, };  use crate::types::{   SignalType,    SignalHeader,    SignalData,   AuthStatus };  pub struct Connection {   pub stream: TcpStream,    \/\/ \u0438\u043d\u0441\u0442\u0430\u043d\u0441 BufReader'\u0430 \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f,   \/\/ \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430   reader: io::BufReader&lt;TcpStream> }  impl Connection {   pub fn new(address: &amp;str, username: &amp;str) -> io::Result&lt;Connection> {     \/\/ \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u0430. \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0442\u0438\u043f \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0438 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f,      \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f.     let signal = SignalData::new(       vec![         SignalHeader::SignalType(SignalType::Connection),         SignalHeader::Username(username.to_owned())       ],       None     );      \/\/ \u041c\u0435\u0442\u043e\u0434 connect \u0443 TcpStream \u0441\u043e\u0437\u0434\u0430\u0441\u0442 TCP \u0441\u043e\u043a\u0435\u0442, \u0438     \/\/ \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u043e\u043a\u0435\u0442\u0443, \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e      \/\/ \u0431\u044b\u043b \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c.     let mut connection = TcpStream::connect(address)?;      \/\/ \u041c\u0435\u0442\u043e\u0434 write_all \u0437\u0430\u043f\u0438\u0448\u0435\u0442 \u0431\u0430\u0439\u0442\u044b \u0432 \u0441\u043e\u043a\u0435\u0442 \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442      \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0441\u043e\u043a\u0435\u0442\u0443 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043e\u043d\u0446\u0435, \u0442\u043e-\u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u0443.     connection.write_all(signal.to_string().as_bytes())?;      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 BufReader'\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u0430.     let reader = BufReader::new(connection.try_clone()?);      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 Connection     let mut instance = Connection {       stream: connection,       reader     };      \/\/ \u0421 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0438\u0439\u0442\u0438 AuthStatus. \u0416\u0434\u0451\u043c \u0435\u0433\u043e \u0438 \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442     \/\/ \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430, \u043b\u0438\u0431\u043e \u043e\u0442\u0434\u0430\u0451\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u043b\u0438\u0431\u043e \u043e\u0442\u0434\u0430\u0451\u043c      \/\/ \u0438\u043d\u0441\u0442\u0430\u043d\u0441 Connection.     let data_from_socket = instance.read_signal()?;     if data_from_socket.contains(&amp;AuthStatus::DENIED.to_string()) {       return Err(Error::new(ErrorKind::ConnectionAborted, \"Access denied\"));     }        return Ok(instance)   }    pub fn read_signal(&amp;mut self) -> io::Result&lt;String> {     let mut res_line = String::new();      \/\/ \u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0445\u0435\u0434\u0435\u0440\u044b \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u044b     let mut headers_read = false;     loop {       let mut buf_line = String::new();        \/\/ \u0420\u0438\u0434\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u0431\u0443\u0444\u0435\u0440\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e.       \/\/ \u0415\u0441\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0442\u043e \u0432\u0441\u0451 \u0432\u044b\u043b\u0435\u0442\u0430\u0435\u0442. \u0415\u0441\u043b\u0438 \u043e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 0 \u0431\u0430\u0439\u0442, \u0442\u043e       \/\/ \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043e (\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043e\u043a\u0435\u0442\u043e\u0432).       match self.reader.read_line(&amp;mut buf_line) {         Err(e) => panic!(\"Got an error: {}\", e),         Ok(0) => return Err(Error::new(ErrorKind::BrokenPipe, \"Connection closed\")),         Ok(_) => (),       };       res_line.push_str(&amp;buf_line);          \/\/ \u0415\u0441\u043b\u0438 \u043e\u043d \u043d\u0430\u0442\u044b\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \"\\r\\n\\r\\n\", \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0445\u0435\u0434\u0435\u0440\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438\u0441\u044c       \/\/ \u0438 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0445\u0435\u0434\u0435\u0440\u0430 WITH_MESSAGE, \u0442\u043e \u0441\u0438\u0433\u043d\u0430\u043b \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u043c       \/\/ \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0435\u0433\u043e. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c, \u0442\u043e \u0446\u0438\u043a\u043b \u0443\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043a\u0440\u0443\u0433        \/\/ \u0438 \u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.       if res_line.ends_with(\"\\r\\n\\r\\n\"){         if !res_line.contains(&amp;SignalHeader::WithMessage.to_string()) || headers_read {           break;         }         headers_read = true;       }     }        Ok(res_line)   } }  \/\/ \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u0439\u0442\u0430 Clone \u0434\u043b\u044f Connection. \u041f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c  \/\/ \u043c\u0430\u043a\u0440\u043e\u0441 \u0434\u043b\u044f Clone \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0447\u0443\u0442\u044c \u0438\u043d\u0430\u0447\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \/\/ TcpStream \u0438 BufReader.  impl Clone for Connection {   fn clone(&amp;self) -> Self {     Connection {        stream: self.stream.try_clone().unwrap(),        reader: BufReader::new(self.stream.try_clone().unwrap())     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 Service. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043d\u043e \u0442\u0430\u043c \u043d\u0430 \u043d\u0435\u0451 \u043b\u043e\u0436\u0438\u0442\u044c\u0441\u044f \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043d\u0430\u043c \u0442\u043e\u0436\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a.   <\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0447\u0430\u043b\u043e \u0444\u0430\u0439\u043b\u0430 client\/src\/service.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/service.rs  use std::io; use crate::{   settings::Settings,    state::State,    connection::Connection };  pub struct Service {   pub connection: Connection,   pub settings: Settings,   pub state: State, }  impl Service {   pub fn run(settings: Settings, state: State) -> io::Result&lt;()> {     let connection = Connection::new(       &amp;settings.server_address.to_owned(),        &amp;state.username     )?;      let mut instance = Service {       connection,       settings,       state     };      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u044b\u0437\u043e\u0432 \u043d\u0430\u0448\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 main \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041f\u043e\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043a\u0440\u043e\u0435\u0442\u0441\u044f. \u0411\u043e\u043b\u0435\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 main\u2019\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.  <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 main \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/main.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/main.rs  use std::io;  use service::Service;  use crate::{   settings::Settings,    state::State };  mod settings; mod types; mod connection; mod state; mod service;  fn main() -> io::Result&lt;()> {   let settings = Settings::new();   let state = State::new()?;      Service::run(settings, state)?;   Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0443\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (MessagesPool)  <\/h2>\n<p>\u041d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u043e 2 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u0430: \u043d\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0442 \u043d\u0435\u0433\u043e \u0438 \u043d\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0435\u043c\u0443 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u041d\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0447\u0430\u0442\u0430, \u0442\u043e-\u0435\u0441\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0438\u043c \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u0447\u0430\u0442\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044e\u0437\u0435\u0440\u0443.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u043c 256 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041f\u043e\u0442\u043e\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u044e\u0437\u0435\u0440\u0443 \u0431\u0443\u0434\u0443\u0442 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0433\u043e. \u0410 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0442\u043e\u043a\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0431\u0443\u0434\u0443\u0442 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u043f\u0438\u0441\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u0442\u0438\u043f \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0443\u043b\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0447\u0430\u043b\u043e \u0444\u0430\u0439\u043b\u0430 server\/src\/messages_pool.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/messages_pool.rs  use std::{collections::{HashMap, VecDeque}, iter};  #[derive(Debug, Clone)] pub struct PoolMessage {   \/\/ \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f   pub id: String,    pub username: String,   pub message: String,    \/\/ \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f true. \u042d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f    \/\/ \u043e \u0432\u0445\u043e\u0434\u0435 \u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.   pub from_server: bool, }  impl PoolMessage {   fn new() -> PoolMessage {     PoolMessage {       id: String::new(),       username: String::new(),       message: String::new(),       from_server: false,     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0443\u043b\u0430. \u041f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u043f\u0443\u043b &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 (256 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439). \u041a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043d\u0435\u0446, \u0430 \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u0443\u043b\u0435 256, \u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e.   <\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 server\/src\/messages_pool.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/messages_pool.rs  \/\/...  pub struct MessagesPool {   \/\/ \u0412\u0435\u043a\u0442\u043e\u0440 \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f VecDeque, \u0430 \u043d\u0435 Vec    \/\/ \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f   \/\/ \u0438 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430.   pool: VecDeque&lt;PoolMessage>,    \/\/ \u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0432\u0435\u043a\u0442\u043e\u0440\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f    \/\/ \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435.   indexes: HashMap&lt;String, u8>,    \/\/ \u041a\u043e\u043b-\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u0443\u043b\u0435.   length: u16, }  impl MessagesPool {   pub fn new() -> MessagesPool {     \/\/ \u0421\u043e\u0437\u0434\u0451\u043c \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u0430 256 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u041c\u0435\u0442\u043e\u0434 repeat_with \u0441\u043e\u0437\u0434\u0430\u0441 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439  \/\/ \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435\u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0414\u0430\u043b\u0435\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \/\/ take \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u0432 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435. \u0418      \/\/ collect'\u043e\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e (\u0432 VecDeque \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435).     let arr: VecDeque&lt;PoolMessage> = iter::repeat_with(|| PoolMessage::new())       .take(256)       .collect();      MessagesPool {        pool: arr,        indexes: HashMap::new(),       length: 0     }   }    \/\/ \u041c\u0435\u0442\u043e\u0434 push \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0443\u043b, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442    \/\/ \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b-\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0415\u0441\u043b\u0438   \/\/ \u043a\u043e\u043b-\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u0443\u043b\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 256, \u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u043d\u0443\u043b\u0435\u0432\u043e\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u0435   \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0435.      pub fn push(&amp;mut self, v: PoolMessage) {     if self.length == 256 {    \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0443\u043b       self.pool.pop_front();       self.pool.push_back(v);    \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u044b       let mut new_indexes: HashMap&lt;String, u8> = HashMap::new();    \/\/ enumerate - \u043c\u0435\u0442\u043e\u0434 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440       \/\/ \u0432 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043e\u0442\u0434\u0430\u0451\u0442   \/\/ \u0438 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e.       for (index, message) in self.pool.iter().enumerate() {         new_indexes.insert(message.id.clone(), index as u8);       }       self.indexes = new_indexes;     }     else {   \/\/ \"as u8\" \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 u16 \u0432 u8. \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044e   \/\/ length u8, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u043b\u0438\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u0430 256, \u0430 \u043e\u043d\u043e    \/\/ \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 u8.       let index = self.length as u8;       self.pool[index as usize] = v.clone();       self.length += 1;       self.indexes.insert(v.id.clone(), index);     }   }    \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e id   \/\/ \u0438 id \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.   fn read_from(&amp;self, id: &amp;str) -> (Vec&lt;PoolMessage>, Option&lt;String>) {     let found_index = self.indexes.get(id);  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0442\u0430\u043a\u0438\u043c id \u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0445 \u0438\u043b\u0438 \u043d\u0435\u0442.      \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043e\u0434\u0438\u043d \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043c\u043d\u043e\u0433\u043e \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445      \/\/ \u043d\u0435 \u0443\u0441\u043f\u0435\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0438\u0442\u0430\u0435\u043c      \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043f\u0438\u0441\u043a\u0430.      match found_index {       Some(v) => {         let index: u16 = v.to_owned() as u16 + 1;         let sliced_pool = &amp;Vec::from(self.pool.clone())[index.into()..self.length.into()];         let sliced_pool_last = {           if sliced_pool.len() == 0 {             None           }           else {             Some(sliced_pool.last().unwrap().clone().id)           }         };         return (sliced_pool.clone().into(), sliced_pool_last)       },       None => {         let last_el = self.last();         let index = match last_el {           Some(v) => Some(v.id.clone()),           None => None         };         let sliced_pool = &amp;Vec::from(self.pool.clone())[..self.length.into()];         return (sliced_pool.into(), index)       }     }   }    \/\/ \u041c\u0435\u0442\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u043f\u0443\u043b \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445.   pub fn has_new(&amp;self, id: &amp;str) -> Option&lt;(Vec&lt;PoolMessage>, Option&lt;String>)> {     let last_el = self.last();     match last_el {       Some(_) => Some(self.read_from(id)),       None => None,     }   }    \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0434\u043b\u0438\u043d\u043e\u0439 \u043f\u0443\u043b\u0430.   fn last(&amp;self) -> Option&lt;PoolMessage> {     let last_index = {       if self.length > 0 {         self.length - 1       } else {         self.length       }     };      let last_el = &amp;self.pool[last_index.into()];     if last_el.id == \"\".to_owned() {       None     } else {       Some(last_el.to_owned())     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435  <\/h2>\n<p>\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0447\u0442\u0435\u043d\u0438\u044e \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Connection. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043a \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043b\u0435\u0436\u0438\u0442 BufReader&lt;TcpStream>, \u0430 \u043a \u043d\u0435\u043c\u0443 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0440\u0435\u0439\u0442\u0430 StreamReader.  <\/p>\n<details class=\"spoiler\">\n<summary>Trait StreamReader (\u0424\u0430\u0439\u043b server\/src\/reader.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/reader.rs  use std::{io::{BufReader, self, BufRead, Error, ErrorKind}, self, net::TcpStream};  use crate::types::SignalHeader;  pub trait StreamReader {   fn read_signal(&amp;mut self) -> io::Result&lt;String>; }  impl StreamReader for BufReader&lt;TcpStream> {   fn read_signal(&amp;mut self) -> io::Result&lt;String> {     let mut res_line = String::new();     let mut headers_read = false;     loop {       let mut buf_line = String::new();       match self.read_line(&amp;mut buf_line) {         Err(_) => return Err(Error::new(ErrorKind::ConnectionAborted, \"boom boom\")),         Ok(0) => return Err(Error::new(ErrorKind::BrokenPipe, \"boom boom\")),         Ok(m) => m,       };       res_line.push_str(&amp;buf_line);          if res_line.ends_with(\"\\r\\n\\r\\n\"){         if !res_line.contains(&amp;SignalHeader::WithMessage.to_string()) || headers_read {           break;         }         headers_read = true;       }     }        Ok(res_line)   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (\u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430)  <\/h2>\n<p>\u0412\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Manager. \u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u0441 \u043d\u0438\u043c.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u0430\u043c\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0430\u044f, \u043c\u044b \u0435\u0451 \u043f\u043e\u0434\u0435\u043b\u0438\u043c \u043d\u0430 \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u0430: \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0441\u043e\u043a\u0435\u0442\u043e\u043c \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0437\u0430 \u0441\u0447\u0451\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 trait\u2019\u043e\u0432. \u0422\u043e-\u0435\u0441\u0442\u044c \u043f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 Manager, \u043d\u043e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u044d\u0442\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u0442 Manager\u2019\u0430 \u0444\u0430\u0439\u043b\u0430\u0445.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 Manager (\u0424\u0430\u0439\u043b server\/src\/managers\/manager.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/managers\/manager.rs  use std::{   net::TcpStream,    io::BufReader,    sync::Arc }; use parking_lot::Mutex; use anyhow::Result;  use crate::{state::State, messages_pool::MessagesPool};  pub struct Manager {   \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u0451\u043d\u043d\u044b\u0439 \u0441\u043e\u043a\u0435\u0442 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c   pub stream: TcpStream,    \/\/ \u0420\u0438\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u0430   pub reader: BufReader&lt;TcpStream>,    \/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   pub state: State,    \/\/ \u041e\u0431\u0449\u0438\u0439 \u043f\u0443\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439   pub messages_pool: Arc&lt;Mutex&lt;MessagesPool>>,    \/\/ \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0435 \u0438\u0437 \u043f\u0443\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   pub last_read_message_id: String,    \/\/ \u0418\u043c\u044f \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430   pub connected_user_username: Option&lt;String>,    \/\/ \u0410\u0434\u0440\u0435\u0441 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430   pub connected_peer_addr: String }  impl Manager {   pub fn new(stream: TcpStream, state: State, messages_pool: Arc&lt;Mutex&lt;MessagesPool>>) -> Result&lt;()> {     let mut manager = Manager {       stream: stream.try_clone()?,       reader: BufReader::new(stream.try_clone()?),       state,       messages_pool,       last_read_message_id: String::new(),       connected_user_username: None,       connected_peer_addr: stream.try_clone()?.peer_addr()?.to_string()     };      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Manager \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0430\u043f\u043a\u0443 \u043a\u0430\u043a \u043c\u043e\u0434\u0443\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043d\u0435\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b mod.rs \u0438 \u0432\u044b\u0432\u0435\u0434\u0438\u0442\u0435 \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Manager.  <\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0430\u0439\u043b server\/src\/mangers\/mod.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/mangers\/mod.rs mod manager;  pub use manager::Manager;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c managers \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0444\u0430\u0439\u043b\u0435 main.rs.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 server\/src\/main.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  \/\/ ... mod managers; \/\/ ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 Manager \u0438 \u043f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u043d\u0435\u0451 \u0431\u044b\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 trait\u2019\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e: StreamManager (\u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u043e\u043c) \u0438 DataManger (\u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438).<\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0442\u0440\u0435\u0439\u0442\u0430 DataManager, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u043e\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 StreamManager\u2019\u0435. \u0418\u0442\u0430\u043a, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b: \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0438\u0442 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u043f\u0443\u0441\u043a\u0430\u0442\u044c \u044e\u0437\u0435\u0440\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u044e\u0437\u0435\u0440\u0430 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0438 \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e \u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u0447\u0430\u0442\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u044e\u0437\u0435\u0440\u0443 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u043d\u0435\u0433\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 DataManager (\u0424\u0430\u0439\u043b server\/src\/managers\/data_manager.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/managers\/data_manager.rs  use std::sync::Arc; use std::sync::mpsc::Receiver; use std::thread; use std::time::Duration; use std::str::FromStr; use anyhow::Result; use parking_lot::Mutex;  \/\/ \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432. use uuid::Uuid;  use crate::messages_pool::{PoolMessage, MessagesPool}; use crate::state::UserData; use crate::types::{   AuthStatus,    SignalData,    SignalHeader,    AuthConnectionError,   IncomingMessageError,   SignalType };  use super::manager::Manager;  \/\/ !! \u0411\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d \u043d\u0438\u0436\u0435 !! use super::stream_manager::StreamManager;  pub trait DataManager {   \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0441\u0438\u0433\u043d\u0430\u043b \u043e \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.   fn deny_auth(&amp;mut self) -> Result&lt;()>;    \/\/ \u041f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044f\u043b\u044f    \/\/ (\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0435\u0441\u0442\u044c \u043b\u0438 \u044e\u0437\u0435\u0440 \u0441 \u0442\u0430\u043a\u0438\u043c \u043d\u0438\u043a\u043e\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438\u043b\u0438 \u043d\u0435\u0442).   fn auth(&amp;mut self, signal: String) -> Result&lt;()>;    \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u044e\u0437\u0435\u0440\u0430 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438    \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u044f\u043b\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0435.   fn remove_user(&amp;mut self, username: String) -> Result&lt;()>;    \/\/ \u0412 \u0446\u0438\u043a\u043b\u0435 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043f\u0443\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.   fn process_messages_pool(&amp;mut self, receiver: Receiver&lt;()>) -> Result&lt;()>;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u043b \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u043f\u0443\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.   fn process_incoming_message(messages_pool: Arc&lt;Mutex&lt;MessagesPool>>, signal: String) -> Result&lt;()>; }  impl DataManager for Manager {   fn deny_auth(&amp;mut self) -> Result&lt;()> {     let response = SignalData::new(       vec![SignalHeader::AuthStatus(AuthStatus::DENIED)],       None     );  \/\/ !! \u041c\u0435\u0442\u043e\u0434 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 StreamManager \u043d\u0438\u0436\u0435 !!     self.send_data(&amp;response.to_string())?;     Ok(())   }    fn auth(&amp;mut self, signal: String) -> Result&lt;()> {     let data = SignalData::from_str(&amp;signal)?;      match data.signal_type.unwrap() {         SignalType::Connection => {           if let None = data.username {             return Err(AuthConnectionError.into());           }           let mut state = self.state.get();           if state.users.contains_key(&amp;data.username.clone().unwrap()) {             return Err(AuthConnectionError.into())           }           state.users.insert(data.username.clone().unwrap().to_owned(), UserData {             address: self.stream.peer_addr()?.to_string(),           });           self.messages_pool.lock().push(PoolMessage {             id: Uuid::new_v4().to_string(),             username: String::new(),             message: format!(\"{} joined the chat!\", data.username.clone().unwrap()),             from_server: true           });         }         _ => return Err(AuthConnectionError.into()),     }      self.connected_user_username = Some(data.username.unwrap());      let response = SignalData::new(       vec![SignalHeader::AuthStatus(AuthStatus::ACCEPTED)],       None     );      \/\/ !! \u041c\u0435\u0442\u043e\u0434 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 StreamManager \u043d\u0438\u0436\u0435 !!     self.send_data(&amp;response.to_string())?;     Ok(())   }    fn remove_user(&amp;mut self, username: String) -> Result&lt;()> {     let mut state = self.state.get();      if state.users.contains_key(&amp;username) {       state.users.remove(&amp;username);       self.messages_pool.lock().push(PoolMessage {         id: Uuid::new_v4().to_string(),         username: String::new(),         message: format!(\"{username} left the chat!\"),         from_server: true       });     }     Ok(())   }    fn process_messages_pool(&amp;mut self, receiver: Receiver&lt;()>) -> Result&lt;()> {     loop {       \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u043f\u043e\u0442\u043e\u043a\u0430, \u0441\u043b\u0443\u0448\u0430\u044e\u0449\u0435\u0433\u043e        \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c,        \/\/ \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043e \u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u044b\u0432\u0430\u0442\u044c \u0446\u0438\u043a\u043b. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435        \/\/ \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0442\u0440\u0435\u0439\u0442\u0430 StreamManager.       if let Ok(()) = receiver.try_recv() {         break;       };        \/\/ \u0422\u0430\u043a \u043a\u0430\u043a self.messages_pool \u044d\u0442\u043e Arc, \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f       \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0432 self.messages_pool.clone().lock(),       \/\/ \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043a\u043b\u043e\u043d\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0443\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f       \/\/ \u0441\u0440\u0430\u0437\u0443 \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0438\u0432\u0438\u044f \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0435\u043c\u0443 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430       \/\/ \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e lock_ref.       let lock_ref = self.messages_pool.clone();       let pool_lock = lock_ref.lock();        let messages = pool_lock.has_new(&amp;self.last_read_message_id);       if let Some(v) = messages {         if let Some(last) = v.1 {           self.last_read_message_id = last;         }         for message in v.0 {           let mut syg_vec = vec![             SignalHeader::SignalType(SignalType::NewMessage),             SignalHeader::Username(message.username.clone()),             SignalHeader::WithMessage           ];           if message.from_server {             syg_vec.push(SignalHeader::ServerMessage);           }           let response = SignalData::new(syg_vec, Some(&amp;message.message));            \/\/ !! \u041c\u0435\u0442\u043e\u0434 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 StreamManager \u043d\u0438\u0436\u0435 !!           self.send_data(&amp;response.to_string())?;         }       }        \/\/ \u0421\u0442\u0430\u0432\u0438\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0434\u043b\u044f \u0446\u0438\u043a\u043b\u0430 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c.        thread::sleep(Duration::from_millis(10));     }      Ok(())   }    \/\/ \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.   fn process_incoming_message(messages_pool: Arc&lt;Mutex&lt;MessagesPool>>, signal: String) -> Result&lt;()> {     let data = SignalData::from_str(&amp;signal)?;        if !data.with_message || data.username.is_none() {       return Err(IncomingMessageError.into())     }        messages_pool.lock().push(PoolMessage {       id: Uuid::new_v4().to_string(),       username: data.username.clone().unwrap(),       message: data.message.clone().unwrap().trim().to_owned(),       from_server: false     });        Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0440\u0435\u0439\u0442 StreamManager. \u0423 \u043d\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 4 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438: \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u044e\u0437\u0435\u0440\u0443 \u0438 \u0437\u0430\u0446\u0438\u043a\u043b\u0435\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430, \u0442\u043e-\u0435\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043e\u0442 \u044e\u0437\u0435\u0440\u0430.  <\/p>\n<details class=\"spoiler\">\n<summary>Trait StreamManager (\u0424\u0430\u0439\u043b server\/src\/managers\/stream_manager.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/managers\/stream_manager.rs  use std::{    io::{     Write, BufReader   },    time::Duration,    thread,   sync::{     mpsc::{       self,        Sender     }   } }; use anyhow::Result;  use crate::{reader::StreamReader, types::SignalType};  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442 \u0438\u0437 super \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0438\u0437  \/\/ \u0442\u043e\u0433\u043e \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438\u043c\u0451\u043d, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f. use super::manager::Manager;  \/\/ \u0414\u0430\u0451\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u043c\u0443 \u0442\u0440\u0435\u0439\u0442\u043a\u0443 \u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \/\/ \u0431\u0443\u0434\u0443\u0442 \u0432 \u043d\u0435\u0433\u043e \u0432\u0445\u043e\u0434\u0438\u0442\u044c. pub trait StreamManager { \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0442\u043e-\u0435\u0441\u0442\u044c   \/\/ \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Manager.   fn process_connection(&amp;mut self) -> Result&lt;()>;    \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f.   fn process_disconnection(&amp;mut self) -> Result&lt;()>;    \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043e\u043a\u0435\u0442, \u0442\u043e-\u0435\u0441\u0442\u044c \u044e\u0437\u0435\u0440\u0443.   fn send_data(&amp;mut self, data: &amp;str) -> Result&lt;()>;    \/\/ \u0412 \u0446\u0438\u043a\u043b\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u0430,   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 \u044e\u0437\u0435\u0440.   fn process_signals(&amp;mut self, sender: Sender&lt;()>) -> Result&lt;()>; }  impl StreamManager for Manager {   fn process_connection(&amp;mut self) -> Result&lt;()> {     println!(\"Connection established - {}\", self.connected_peer_addr);      \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 read_signal, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u043b\u044f     \/\/ BufReader'\u0430 \u0441 \u0442\u0438\u043f\u043e\u043c TcpStream, \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044e\u0437\u0435\u0440     \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0442\u043e     \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 process_disconnection \u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.     let auth_data = match BufReader::new(       self.stream.try_clone()?     ).read_signal() {       Ok(v) => v,       Err(_) => {         self.process_disconnection()?;         return Ok(())       }     };      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0438     \/\/ \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435, \u0442\u043e \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u043c     \/\/ \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u043e\u0431\u0440\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435.     if self.auth(auth_data.clone()).is_err() {       self.deny_auth()?;       self.process_disconnection()?;       return Ok(())     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u0430\u043d\u0430\u043b \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438. \u041d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b     \/\/ \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c receiver \u043f\u043e\u0442\u043e\u043a\u0443 (\u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443) \u0441\u0438\u0433\u043d\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e     \/\/ \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043e.     let (channel_sender, channel_receiver) = mpsc::channel::&lt;()>();      \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.     self.process_signals(channel_sender)?;      \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u0443\u043b\u0435.      self.process_messages_pool(channel_receiver)?;      \/\/ \u0422\u0430\u043a \u043a\u0430\u043a process_messages_pool \u0431\u0443\u0434\u0435\u0442 \u0446\u0438\u043a\u043b\u0438\u0447\u043d\u044b\u043c, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d      \/\/ \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u0435\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0446 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f     \/\/ \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c process_disconnection.     self.process_disconnection()?;     Ok(())   }    fn process_disconnection(&amp;mut self) -> Result&lt;()> {     \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u044e\u0437\u0435\u0440\u0430 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439     \/\/ \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0432 \u0447\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e \u0435\u0433\u043e \u0443\u0445\u043e\u0434\u0435.     if self.connected_user_username.is_some() {       self.remove_user(self.connected_user_username.clone().unwrap())?;     }     println!(\"Connection closed - {}\", self.connected_peer_addr);     Ok(())   }    fn send_data(&amp;mut self, data: &amp;str) -> Result&lt;()> {     \/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043e\u043a\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 write \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0432\u0438\u0434\u0435 \u0431\u0430\u0439\u0442\u043e\u0432.     self.stream.write(data.as_bytes())?;     Ok(())   }    fn process_signals(&amp;mut self, sender: Sender&lt;()>) -> Result&lt;()> {     \/\/ \u041a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0445 \u0432      \/\/ \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a.     let cloned_stream = self.stream.try_clone()?;     let cloned_messages_pool = self.messages_pool.clone();      \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u0441\u043e\u043a\u0435\u0442\u043e\u043c \u0438 \u043f\u0443\u043b\u043e\u043c     \/\/ \u043c\u044b \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c      \/\/ closure (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f) \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u043e move.      thread::spawn(move || -> Result&lt;()> {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 reader \u0438 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u044b.        let mut reader = BufReader::new(cloned_stream.try_clone()?);       loop {         let data_from_socket = match reader.read_signal() {           Ok(s) => s,           Err(_) => {             break;           }         };          \/\/ \u041c\u0435\u0442\u043e\u0434 process_incoming_message \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c          \/\/ \u0435\u0433\u043e \u043d\u0435 \u0443 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430, \u0430 \u0443 \u0442\u0438\u043f\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0447\u0435\u0440\u0435\u0437 Self.         match Self::process_incoming_message(cloned_messages_pool.clone(), data_from_socket) {           Ok(_) => (),           Err(_) => println!(\"invalid message\")         };       }        \/\/ \u0415\u0441\u043b\u0438 \u0446\u0438\u043a\u043b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u043e\u0440\u0432\u0430\u043b\u043e\u0441\u044c.        \/\/ \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043e\u0431 \u044d\u0442\u043e\u043c.        sender.send(())?;        Ok(())     });      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0434\u0432\u0430 \u043d\u0430\u0448\u0438\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0442\u0440\u0435\u0439\u0442\u0430 \u0434\u043b\u044f Manager\u2019\u0430, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 process_connection \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 new.   <\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 Manager (\u0424\u0430\u0439\u043b server\/src\/managers\/manager.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/managers\/manager.rs  use std::{   net::TcpStream,    io::BufReader,    sync::Arc }; use parking_lot::Mutex; use anyhow::Result;  use crate::{state::State, messages_pool::MessagesPool}; use super::stream_manager::StreamManager; \/\/ +  pub struct Manager {   pub stream: TcpStream,   pub reader: BufReader&lt;TcpStream>,   pub state: State,   pub messages_pool: Arc&lt;Mutex&lt;MessagesPool>>,   pub last_read_message_id: String,   pub connected_user_username: Option&lt;String>,   pub connected_peer_addr: String }  impl Manager {   pub fn new(stream: TcpStream, state: State, messages_pool: Arc&lt;Mutex&lt;MessagesPool>>) -> Result&lt;()> {     let mut manager = Manager {       stream: stream.try_clone()?,       reader: BufReader::new(stream.try_clone()?),       state,       messages_pool,       last_read_message_id: String::new(),       connected_user_username: None,       connected_peer_addr: stream.try_clone()?.peer_addr()?.to_string()     };      manager.process_connection()?; \/\/ +     Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043c\u043e\u0434\u0443\u043b\u044f managers (\u0424\u0430\u0439\u043b server\/src\/managers\/mod.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/managers\/mod.rs mod manager; mod stream_manager; \/\/ + mod data_manager; \/\/ +  pub use manager::Manager;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434 run \u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Service, \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 Service (\u0424\u0430\u0439\u043b server\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/service.rs  use std::{net::TcpListener, thread, sync::Arc}; use anyhow::Result; use parking_lot::Mutex;  use crate::{state::State, managers::Manager, messages_pool::MessagesPool}; \/\/ +  pub struct Service;  impl Service {   pub fn run(state: State) -> Result&lt;()> {     let listener = TcpListener::bind(format!(\"0.0.0.0:{}\", state.get().settings.port))?;      let messages_pool = Arc::new(Mutex::new(MessagesPool::new())); \/\/ +      for con in listener.incoming() {       let cloned_state = state.clone(); \/\/ +       let cloned_messages_pool = messages_pool.clone(); \/\/ +       thread::spawn(move || -> Result&lt;()> {         Manager::new(con?, cloned_state, cloned_messages_pool)?; \/\/ +          Ok(())       });     }      Ok(())   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438 \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 (\u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430)  <\/h2>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u0447\u0430\u0442 \u0441\u0442\u0430\u043b \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0447\u0430\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u0438\u043c\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0432\u043e\u0434 \u043d\u043e\u0432\u044b\u0445. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e). \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439: \u043f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0448\u0438 enter, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0435\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0438 \u0437\u0430\u0441\u043e\u0440\u044f\u0435\u0442 \u0447\u0430\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043d \u043d\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0432\u0435\u043b \u044e\u0437\u0435\u0440.<\/p>\n<p>\u0420\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e, \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u044f \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0432 raw mode. \u0412 \u044d\u0442\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u043e \u043d\u0430\u0436\u0430\u0442\u044b\u0445 \u043a\u043d\u043e\u043f\u043a\u0430\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u043e \u043d\u0430\u0436\u0430\u0442\u044b\u0445 \u043a\u043b\u0430\u0432\u0438\u0448\u0430\u0445, \u0438 \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u043d\u0438\u0445 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0432\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0443 \u043d\u0430\u0441 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u043d\u0435\u0435 \u043c\u044b \u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u043e\u043b\u0435 user_input \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0432 raw mode \u043d\u0430\u0448 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0448\u0438, \u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0438 \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/crates.io\/crates\/termion\" rel=\"noopener noreferrer nofollow\">termion<\/a>. \u0412\u0441\u0451 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Service.<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0435\u0442\u043e\u0434 \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0432\u043e\u0434\u0438\u043c\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 client\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/service.rs  use std::{   thread,    io::{     self,      Write   },   str::FromStr }; use termion::{   raw::IntoRawMode,    input::TermRead }; use crate::{   settings::Settings,    state::State,    connection::Connection,    types::{     SignalType,      SignalData,      SignalHeader   } };  \/\/ ...  pub fn read_inputs(&amp;mut self) {   \/\/ \u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430 \u0432 raw mode \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439    \/\/ \u043e\u0442 \u0440\u0430\u043d\u0435\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0439\u0442\u0430 IntoRawMode.    \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043e \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u043d\u0435    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438   \/\/ \u0441\u043d\u0438\u043c\u0435\u0442 raw mode. stdout \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0442\u0438\u043f RawTerminal&lt;Stdout>,    \/\/ \u0438 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0442\u0440\u0435\u0439\u0442 Drop \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c drop,   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u0430\u043c Rust \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0434   \/\/ \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0430 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0430. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u0442\u043e\u0434 drop \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442   \/\/ \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u043a \u043f\u0440\u043e\u0448\u043b\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e.   let stdout = io::stdout().into_raw_mode().unwrap();     \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 keys, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442 \u0442\u0440\u0435\u0439\u0442\u0430 TermRead, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e    \/\/ \u0440\u0430\u043d\u0435\u0435, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430\u0436\u0430\u0442\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0448.    let mut stdin = io::stdin().keys();    loop {     \/\/ \u0423 \u0432\u0441\u0435\u0445 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 next, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c     \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e.     let input = stdin.next();      if let Some(Ok(key)) = input {       \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u043a\u0430\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u0436\u0430\u0442\u0430       match key {         \/\/ \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 Ctrl+C, \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0446\u0438\u043a\u043b.         termion::event::Key::Ctrl('c') => break,          \/\/ \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 Enter \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u043e\u0432\u043e\u0435          \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0447\u0438\u0449\u0430\u044f user_input. \u0418\u043b\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438         \/\/ user_input \u044d\u0442\u043e \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0447\u0430\u0442.          termion::event::Key::Char('\\n') => {           let ms = self.state.user_input.lock().clone().trim().to_owned();           if ms == \"\" {             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u043b \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443, \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u043c\u0443\u0441\u044f \u0432\u044b\u0432\u043e\u0434\u043e\u043c              \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 (\u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u0436\u0435),              \/\/ \u0447\u0442\u043e \u0447\u0430\u0442 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 -             \/\/ \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0446\u0438\u043a\u043b.             match self.state.chat_reload_sender.send(()) {               Ok(_) => {},               Err(_) => break,              };              continue;           }           self.state.user_input.lock().clear();            \/\/ \u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u0430.           let signal = SignalData::new(             vec![               SignalHeader::SignalType(SignalType::NewMessage),               SignalHeader::WithMessage,               SignalHeader::Username(self.state.username.to_owned())             ],             Some(&amp;ms)           );            \/\/ \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0437\u0430\u0442\u0435\u043c \u0432 \u0431\u0430\u0439\u0442\u044b \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c            \/\/ \u0432 TcpStream, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043a\u0435\u0442\u043e\u043c, \u0441\u043e\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u043c \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c           \/\/ \u0441\u043e\u043a\u0435\u0442\u043e\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.            self.connection.stream.write_all(signal.to_string().as_bytes()).unwrap();         },          \/\/ \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 Backspace \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0438\u043d\u043f\u0443\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b          \/\/ \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c.         termion::event::Key::Backspace => {           self.state.user_input.lock().pop();           match self.state.chat_reload_sender.send(()) {             Ok(_) => {},             Err(_) => continue,            };         }          \/\/ \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0438, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432          \/\/ user_input \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u043d\u0430          \/\/ \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c.         termion::event::Key::Char(k) => {           println!(\"{k}\");           self.state.user_input.lock().push_str(&amp;k.to_string());           match self.state.chat_reload_sender.send(()) {             Ok(_) => {},             Err(_) => continue,            };         },          \/\/ \u0412\u043e \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e loop'\u0430.         _ => {           continue;         }       }     }   } }  \/\/ ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0443\u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0446\u0438\u043a\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438 \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 messages, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 \u0432 State \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 client\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/service.rs  \/\/ ...  pub fn proccess_incoming_messages(&amp;self) {   let messages = self.state.messages.clone();   let tx = self.state.chat_reload_sender.clone();   let mut connection = self.connection.clone();    thread::spawn(move || -> io::Result&lt;()> {     loop {       \/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u0438\u0437 \u0441\u043e\u043a\u0435\u0442\u0430       let data_from_socket = match connection.read_signal() {         Ok(v) => v,         Err(_) => break       };        let signal = SignalData::from_str(&amp;data_from_socket);        \/\/ \u0421\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u043c\u043e\u043a \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438        \/\/ \u043d\u0435 \u043c\u043e\u0433\u043b\u0438 \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u043a\u0430\u0441\u0430\u0442\u044c\u0441\u044f       let mut messages = messages.lock();        if let Ok(s) = signal {         if let Some(SignalType::NewMessage) = s.signal_type {           \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 messages \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438            \/\/ \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0433\u043e \u043e\u043d\u0438 \u0442\u0438\u043f\u0430. server_message \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e            \/\/ \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0442\u043e-\u0435\u0441\u0442\u044c \u043e \u0432\u044b\u0445\u043e\u0434\u0435\/\u0432\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f,           \/\/ \u0438 \u0443 \u043d\u0435\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442 \u0438 \u0441\u0442\u0438\u043b\u0438.           if s.server_message {             messages.push(               \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u043e\u0432 \u0438 \u0441\u0442\u0438\u043b\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e               format!(                 \"{}{}{}{}\",                 termion::style::Faint,                 termion::style::Bold,                 s.message.unwrap(),                 termion::style::Reset,               )             );           }           else {             messages.push(               format!(                 \"&lt;{}> {}\",                  s.username.unwrap(),                  s.message.unwrap()               )             );           }         }       }       \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b \u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0442\u0430.       match tx.send(()) {         Ok(_) => {},         Err(_) => break       };     }      Ok(())   }); }  \/\/ ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u0442\u0430\u043b\u0441\u044f \u0441\u0430\u043c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0432\u0432\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b. \u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0430\u043c \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u041e\u043d \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0447\u0430\u0442\u0430 \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u0430. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a receiver \u043a\u0430\u043d\u0430\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u044d\u0442\u043e\u043c\u0443. \u0421\u0443\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e receiver \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u044d\u0442\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442. \u041d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b self \u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Service, \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0435\u0451 receiver \u0432 \u043f\u043e\u0442\u043e\u043a \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Service, \u043d\u043e \u0443\u0436\u0435 \u0431\u0435\u0437 reciever\u2019\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0435\u0442\u043e\u0434 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b (\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 client\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/service.rs  \/\/ ...  pub fn enable_print(self) -> Service {   let rx = self.state.chat_reload_receiver.unwrap();   let messages = self.state.messages.clone();   let user_input = self.state.user_input.clone();   let username = self.state.username.clone();    thread::spawn(move || -> io::Result&lt;()> {     loop {       \/\/ \u0416\u0434\u0451\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432.       match rx.recv() {         Ok(()) => {},         Err(_) => break       };        \/\/ \u041e\u0447\u0438\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b.       print!(\"{}\", termion::clear::All);        \/\/ \u0412\u044b\u0432\u043e\u0434\u0438\u043c \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.        \/\/ lock \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0437\u0430\u043c\u043e\u043a \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, iter \u0432\u0435\u0440\u043d\u0451\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440,        \/\/ \u0430 enumerate \u0432\u0435\u0440\u043d\u0451\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438       \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043d\u043e\u043c\u0435\u0440 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438.       for (index, m) in messages.lock().iter().enumerate() {         if index == 0 {           print!(\"\\r\\n{m}\\r\\n\");         }         else {           print!(\"{m}\\r\\n\");         }       }        \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u0432\u0432\u043e\u0434\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.       let input = user_input.lock().clone();       print!(         \"{}{}{} >{} {}\",          termion::color::Bg(termion::color::White),          termion::color::Fg(termion::color::Black),          username,          termion::style::Reset,         input       );              \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0430, \u043f\u043e\u043c\u0435\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0443\u0434\u0430 \u0447\u0435\u0440\u0435\u0437        \/\/ \u043c\u0430\u043a\u0440\u043e\u0441 print! \u0432 stdout.       std::io::stdout().flush()?;     }     Ok(())   });    \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.   Service {      connection: self.connection,     settings: self.settings,      state: State {       username: self.state.username.clone(),       chat_reload_receiver: None,       chat_reload_sender: self.state.chat_reload_sender.clone(),       user_input: self.state.user_input.clone(),       messages: self.state.messages.clone(),     }   } }  \/\/ ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 run \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Service \u0438 \u0432\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e \ud83d\ude42 <\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 client\/src\/service.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/service.rs  \/\/ ...  pub fn run(settings: Settings, state: State) -> io::Result&lt;()> {   let connection = Connection::new(     &amp;settings.server_address.to_owned(),      &amp;state.username   )?;    let mut instance = Service {     connection,     settings,     state   }.enable_print(); \/\/ +    instance.proccess_incoming_messages(); \/\/ +   instance.read_inputs(); \/\/ +    Ok(()) }  \/\/ ...<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 (\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u043f\u043e\u0440\u0442\u043e\u043c) <code>cargo run -- -a 127.0.0.1:8080<\/code> \u0438 \u0443 \u0432\u0430\u0441 \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u043d\u0438\u043a\u043d\u0435\u0439\u043c\u0430, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u0442\u0435 \u0432 \u0447\u0430\u0442 \u0432\u0430\u0448\u0435\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430.  <\/p>\n<hr\/>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435! \ud83d\ude42<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u2014 <a href=\"https:\/\/github.com\/IDSaves\/terminal-chat\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/IDSaves\/terminal-chat<\/a><br \/>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0447\u0430\u0442\u0430 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"http:\/\/crates.io\" rel=\"noopener noreferrer nofollow\">crates.io<\/a> (\u0431\u044b\u0441\u0442\u0440\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0434\u043b\u044f \u0442\u0435\u0445, \u0443 \u043a\u043e\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d Rust \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435) \u2014 <a href=\"https:\/\/crates.io\/crates\/tchat\" rel=\"noopener noreferrer nofollow\">https:\/\/crates.io\/crates\/tchat<\/a><\/p>\n<p>P.S. \u0417\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0438\u043d\u044f\u044e\u0441\u044c \u0437\u0430 \u043e\u0440\u0444\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043a \u043a\u043e\u0434\u0443. <\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/728870\/\"> https:\/\/habr.com\/ru\/articles\/728870\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014  \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0447\u0430\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f) \u043d\u0430 Rust, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b TCP \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Rust. \u0421\u0430\u043c \u0447\u0430\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0435\u0441\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/IDSaves\/terminal-chat\" rel=\"noopener noreferrer nofollow\">\u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0430\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<h2> \u041d\u0430\u0447\u0430\u043b\u043e  <\/h2>\n<blockquote>\n<p>\u041c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043a \u043a\u043e\u0434\u0443.<\/p>\n<\/blockquote>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 2 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u043a \u0447\u0430\u0442\u0443, \u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044e\u0437\u0435\u0440\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u044e\u0437\u0435\u0440\u0430. \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>cargo new &lt;name><\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0442\u0438\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0439 \u0441\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u0447\u043d\u0451\u043c \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/crates.io\/crates\/clap\" rel=\"noopener noreferrer nofollow\">clap<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0424\u0430\u0439\u043b server\/src\/settings.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/settings.rs  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0439\u0442\u0430 \u0438\u0437 clap use clap::Parser;  \/\/ \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432.  \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e derive \u043c\u0430\u043a\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u0430\u043a\u0440\u043e\u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e  \/\/ \u0442\u0440\u0435\u0439\u0442\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c  \/\/ \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0443\u0436\u043d\u044b\u0439 impl c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c Parser'\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Args. #[derive(Parser)] pub struct Args {   \/\/ \u041c\u0430\u043a\u0440\u043e\u0441 arg \u0442\u0430\u043a \u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437 clap \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438   \/\/ \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430.   \/\/ short \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043a\u0440\u0430\u0449\u0451\u043d\u043d\u043e   \/\/ \u0432\u043e\u0442 \u0442\u0430\u043a \"-p 8080\". long, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c    \/\/ \u043f\u043e\u043b\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \"--port 8080\". \u0410 help \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439    \/\/ \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 --help   #[arg(short, long, help = \"Port that the server will serve\")]   pub port: u16, }  \/\/ \u0422\u0440\u0435\u0439\u0442 Debug \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0447\u0435\u0440\u0435\u0437 print \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0430  \/\/ Clone \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u043b\u044f \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \/\/ \u0412 derive \u043c\u044b \u043e\u043f\u044f\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u044d\u0442\u0438\u0445 \u0442\u0440\u0435\u0439\u0442\u043e\u0432 \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043d\u0430\u043c \/\/ impl'\u044b \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 Debug \u0438 Clone, \u0447\u0442\u043e\u0431\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e. #[derive(Debug, Clone)] pub struct Settings {   pub port: u16, }  \/\/ \u0412\u043d\u0443\u0442\u0440\u0438 impl \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b impl Settings {   pub fn new() -> Settings {     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0442 \u0442\u0440\u0435\u0439\u0442\u0430 Parser      let args = Args::parse();      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e     Settings {        port: args.port,      }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Settings \u0432 \u043d\u0430\u0448 main.rs. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0430 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u043f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 server\/src\/main.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  \/\/ anyhow \u044d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 enum Result,  \/\/ \u043f\u043e\u0447\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 Result'\u0443 \u0438\u0437 std, \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442  \/\/ \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 use anyhow::Result;  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b use settings::Settings;  \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f, \u0438\u043d\u0430\u0447\u0435 \u0444\u0430\u0439\u043b \u0432\u0438\u0434\u0435\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 mod settings;  fn main() -> Result&lt;()> {   \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043d\u0441\u0442\u0440\u043e\u0435\u043a   let settings = Settings::new();      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 Result::Ok() \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (State) \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u0435\u0440\u0432\u0435\u0440, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0442\u043e \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0451\u0440\u043d\u0443\u0442\u044b \u0432 Arc \u0438 Mutex, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u043a\u043e\u0434\u0435. <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b State \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0424\u0430\u0439\u043b server\/src\/state.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/state.rs  use std::{   \/\/ Arc (Atomic Reference Counter) \u044d\u0442\u043e smart pointer, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442    \/\/ \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0422\u043e-\u0435\u0441\u0442\u044c, \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 Arc \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u043d\u0443\u0442 \u043f\u043e\u043a\u0430 \u0435\u0441\u0442\u044c    \/\/ \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043a\u043b\u043e\u043d \u044d\u0442\u043e\u0433\u043e Arc'\u0430. \u041f\u043e \u0441\u0443\u0442\u0438, \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438    \/\/ Rc (Reference Counter), \u043d\u043e Rc \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c.   sync::Arc,    collections::HashMap };  \/\/ \u042d\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433 Mutex'\u0430 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435.  \/\/ \u0421\u0430\u043c Mutex \u044d\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \/\/ \u0435\u0441\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043e\u043d\u0430 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. \u0418 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f  \/\/ \u043e\u043d\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e  \/\/ \u0440\u0430\u0441\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438.  use parking_lot::{Mutex, MutexGuard};  use crate::settings::Settings;  \/\/ \u041a\u0430\u0436\u0434\u044b\u0439 \u044e\u0437\u0435\u0440 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0435\u0439\u0442, \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 UserData \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0437\u0430\u043f\u0438\u0441\u044c  \/\/ \u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u043c \u044e\u0437\u0435\u0440\u0435.  #[derive(Debug, Clone)] pub struct UserData {   \/\/ Ip \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f + \u0435\u0433\u043e \u0441\u043e\u043a\u0435\u0442\u0430   pub address: String, }  #[derive(Debug, Clone)] pub struct StateData {   \/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435   pub settings: Settings,   \/\/ HashMap'\u0430 \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0445 \u044e\u0437\u0435\u0440\u0430\u0445, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u044d\u0442\u043e \u043d\u0438\u043a\u043d\u0435\u0439\u043c,   \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e UserData    pub users: HashMap&lt;String, UserData>, }  \/\/ Arc, \u043a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043d\u043e \u043e\u043d \u043d\u0435 \/\/ \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u043d\u044f\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043c\u044b \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c StateData \u0432 Mutex. pub struct State(Arc&lt;Mutex&lt;StateData>>);  impl State {   pub fn new(settings: Settings) -> State {     State(       Arc::new(Mutex::new(StateData {          settings,          users: HashMap::new()       }))     )   }    \/\/ \u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c. \u041e\u043d \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 Mutex \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441    \/\/ \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u0435. \u0418 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 MutexGuard. \u041f\u043e\u043a\u0430 MutexGuard   \/\/ \u0436\u0438\u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.   pub fn get(&amp;self) -> MutexGuard&lt;StateData> {     self.0.lock()   } }  \/\/ \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u0439\u0442\u0430 Clone \u0434\u043b\u044f State. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0435\u0441\u0438\u0442\u044c \u043c\u0430\u043a\u0440\u043e\u0441 \u0442\u0440\u0435\u0439\u0442\u0430 Clone  \/\/ \u0447\u0435\u0440\u0435\u0437 derive \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 Arc. \/\/ \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f Clone \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u0440\u0443\u0447\u043d\u0443\u044e.   impl Clone for State {   fn clone(&amp;self) -> Self {     State(Arc::clone(&amp;self.0))   }    fn clone_from(&amp;mut self, source: &amp;Self) {     *self = source.clone();   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p> \u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a \u0436\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0451\u043c State \u0432 \u043d\u0430\u0448\u0443 main \u0444\u0443\u043d\u043a\u0446\u0438\u044e.   <\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0424\u0430\u0439\u043b server\/src\/main.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b server\/src\/main.rs  use anyhow::Result;  use settings::Settings; use state::State; \/\/ +  mod settings; mod state; \/\/ +  fn main() -> Result&lt;()> {   let settings = Settings::new();   let state = State::new(settings)); \/\/ +      Ok(()) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0433\u043e\u0442\u043e\u0432\u044b, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b Settings \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/settings.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/settings.rs  use clap::Parser;  #[derive(Parser)] pub struct Args { \/\/ \u0410\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u043f\u043e\u0440\u0442\u043e\u043c, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435   #[arg(short, long, help = \"Server address\")]   pub address: String, }  #[derive(Debug, Clone)] pub struct Settings {   pub server_address: String, }  impl Settings {   pub fn new() -> Settings {     let args = Args::parse();          Settings {        server_address: args.address     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>State \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0441\u0443\u0442\u044c \u0442\u0430 \u0436\u0435. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0435\u0433\u043e \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432. <\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b State \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b client\/src\/state.rs)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ \u0424\u0430\u0439\u043b client\/src\/state.rs  use std::{   sync::{     \/\/ mpsc \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443 \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438.     \/\/ \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u0432\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 (\u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439), \u043e\u0434\u0438\u043d \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445     \/\/ \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u043f\u043e \u043a\u0430\u043d\u0430\u043b\u0443 mpsc.     mpsc::{       Sender,        Receiver,        self     },      Arc   },    io::{     self,      \/\/ BufReader \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 tcp \u0441\u043e\u043a\u0435\u0442\u0430.      \/\/ \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443: \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0435\u0434\u043a\u0438\u0435, \u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u044b\u0435 read     \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u0444\u0430\u0439\u043b \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u0443 \u0438 \u0434\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u043e, \u0447\u0442\u043e \u043e\u043d \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b.     \/\/ \u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0438\u0437 tcp \u0441\u043e\u043a\u0435\u0442\u0430 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.     BufReader,   \/\/ \u0414\u0432\u0430 \u0442\u0440\u0435\u0439\u0442\u0430. \u041e\u0434\u0438\u043d \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 BufReader'\u0430, \u0434\u0440\u0443\u0433\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0444\u0430\u0439\u043b \/\/ (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u0441\u043e\u043a\u0435\u0442).      BufRead,      Write   } };  use parking_lot::Mutex;  pub struct State {   \/\/ \u041d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044e\u0437\u0435\u0440 \u0432\u0432\u0435\u0434\u0451\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   pub username: String,    \/\/ \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u0430 mpsc. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   \/\/ \u0443\u043a\u0430\u0437\u0430\u043d unit (\u043f\u0443\u0441\u0442\u043e\u0439 tuple), \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u0430\u043c \u0444\u0430\u043a\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u044f    \/\/ \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0435\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443\u0442.   \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a Option, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443 \u0438    \/\/ \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438 \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f None.    pub chat_reload_receiver: Option&lt;Receiver&lt;()>>,    \/\/ \u0427\u0430\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u0430 mpsc, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u0442\u043e\u043a\u0443.   pub chat_reload_sender: Sender&lt;()>,    \/\/ \u0412 user_input'\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u0432\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u0440\u0438\u043c\u0435\u0440:   \/\/ \u044e\u0437\u0435\u0440 \u043f\u0438\u0448\u0435\u0442 \"\u043f\u0440\u0438\u0432\u0435\u0442\", \u043d\u043e \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0447\u0430\u0442. \"\u043f\u0440\u0438\u0432\u0435\" \u043b\u0435\u0436\u0438\u0442    \/\/ \u0432 user_input'\u0435. \u041e\u0431\u044b\u0447\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043d\u043e \u0443 \u043d\u0430\u0441 \u0447\u0430\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u0442   \/\/ \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0430\u0442, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439    \/\/ \u0432\u0432\u043e\u0434 \u044e\u0437\u0435\u0440\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0432\u0432\u043e\u0434 \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u0430\u043b, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e   \/\/ \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043c\u0435\u0441\u0442\u0443   \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.    pub user_input: Arc&lt;Mutex&lt;String>>,    \/\/ \u041c\u0430\u0441\u0441\u0438\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.   pub messages: Arc&lt;Mutex&lt;Vec&lt;String>>> }  impl State {   pub fn new() -> io::Result&lt;State> {     \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 mpsc \u043a\u0430\u043d\u0430\u043b\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0435\u0440\u043d\u0451\u0442 tuple, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e     \/\/ \u0441\u0440\u0430\u0437\u0443 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u0434\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     let (sx, rx) = mpsc::channel::&lt;()>();      let user_input = Arc::new(Mutex::new(String::new()));     let messages = Arc::new(Mutex::new(Vec::&lt;String>::new()));      let mut instance = State {       username: String::new(),       chat_reload_receiver: Some(rx),       chat_reload_sender: sx,       user_input,       messages,     };      \/\/ \u0412\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f username'\u0430     instance.read_username()?;      Ok(instance)   }    \/\/ \u041c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0443 user'\u0430 \u0432\u0432\u043e\u0434 \u0435\u0433\u043e<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-404718","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/404718","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=404718"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/404718\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=404718"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=404718"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=404718"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}