{"id":277437,"date":"2016-04-01T11:11:09","date_gmt":"2016-04-01T07:11:09","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=277437"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=277437","title":{"rendered":"[The Methanum project] \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0441 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u201c\u0417\u0432\u0435\u0437\u0434\u0430\u201d"},"content":{"rendered":"\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/306\/5f6\/5e7\/3065f65e7fee43d184d814e252f1cb47.png\"\/><\/div>\n<p>  \u0417\u0432\u0435\u0437\u0434\u0430 \u2014 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u0434\u0435\u043d\u044c \u0441\u0430\u043c\u0430\u044f \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u0430\u044f \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u044f \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439. \u0422\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0440\u044f\u0434\u043e\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432: \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c\u044e (\u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0442\u0440\u043e\u044f \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043d\u0435 \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445) \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0430\u0432\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0438 \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u043d\u0430 \u0441\u0443\u0434 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f .Net \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0441 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u0437\u0432\u0435\u0437\u0434\u0430. <a name=\"habracut\"><\/a><\/p>\n<p>  \u0421\u0438\u0441\u0442\u0435\u043c\u044b, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0430\u043a\u043e\u0439 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u043a \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043d\u0438\u0436\u0435.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/138\/e41\/f80\/138e41f80eb34073aee1bec633898cbd.jpg\"\/><\/div>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u043f\u0438\u0448\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f, \u0431\u0435\u0437 \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0444\u0438\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432 \u0441\u0432\u043e\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u0445 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c.<\/p>\n<h3>Methanum<\/h3>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/1c1\/d59\/dba\/1c1d59dba8fb45b499d2c364804e9d0a.jpg\"\/><\/div>\n<p>  \u041f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043a\u043e\u0434\u043e\u0432\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 Methanum \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0437-\u0437\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u043e\u0439 \u0441\u0445\u043e\u0436\u0435\u0441\u0442\u0438 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438 \u0441 \u043c\u043e\u043b\u0435\u043a\u0443\u043b\u043e\u0439 \u043c\u0435\u0442\u0430\u043d\u0430 :). \u0426\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0437\u0435\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u0440\u043e\u043b\u044c \u043a\u043e\u043c\u0443\u043d\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043d\u0430\u0437\u0432\u0430\u043d \u00abCore\u00bb. \u041a \u044f\u0434\u0440\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0438 \u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0422\u0430\u043a \u0436\u0435 \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0441\u0435\u0442\u0438. \u0421\u043e\u0431\u044b\u0442\u0438\u044f \u2014 \u044d\u0442\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Event, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. Event \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 2 \u043f\u043e\u043b\u044f \u2014 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 Destination, \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0438 \u043f\u043e\u043b\u0435 Data, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u044c key value. Key \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0438\u043c\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, Value \u2014 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f object \u0438 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b (int, double, bool\u2026). \u0414\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043c\u043e\u0447\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445. <\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u201cmethanum\u201d \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043d\u0430 C# \u0438 \u043f\u043e \u0445\u043e\u0434\u0443 \u0442\u0435\u043a\u0441\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u044b.<\/p>\n<h3>Event<\/h3>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/356\/f6e\/a36\/356f6ea361ce4418b04d862dbe6ffe91.jpg\"\/><\/div>\n<p>  \u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u2014 \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u043f\u043e\u043b\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 Data \u0438 \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Destination. \u0422\u0430\u043a\u0436\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0435\u0449\u0435 \u0434\u0432\u0430 \u043f\u043e\u043b\u044f: Id \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 DataTime \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u042d\u0442\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043d\u0443\u0436\u043d\u044b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043b\u043e\u0433\u043e\u0432. \u041a\u043b\u0430\u0441\u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0442\u0430\u043a \u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0436\u0438\u0437\u043d\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430, \u0438\u0445 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u0443\u043c\u0430\u044e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0438\u0437 \u043a\u043e\u0434\u0430 \u0438 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Event.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Web.Script.Serialization;  namespace methanum {     [DataContract]     [KnownType(typeof(List&lt;DateTime&gt;))]     public class Event {         \/\/\/ &lt;summary&gt;         \/\/\/ A unique id of the event         \/\/\/ &lt;\/summary&gt;         [DataMember]         public Guid Id { set; get; }          \/\/\/ &lt;summary&gt;         \/\/\/ DateTime of event creation         \/\/\/ &lt;\/summary&gt;         [DataMember]         public DateTime DataTime { get; set; }          \/\/\/ &lt;summary&gt;         \/\/\/ Target         \/\/\/ &lt;\/summary&gt;         [DataMember]         public string Destination { get; set; }           \/\/\/ &lt;summary&gt;         \/\/\/ Data container         \/\/\/ &lt;\/summary&gt;         [DataMember]         public Dictionary&lt;string, object&gt; Data { get; set; }          public Event() {             Init();         }          public Event(string destination) {             Init();             Destination = destination;         }          private void Init() {             Data = new Dictionary&lt;string, object&gt;();             Id = Guid.NewGuid();             DataTime = DateTime.Now;         }           public override string ToString() {              var properties = GetType().GetProperties();              var sb = new StringBuilder();             sb.AppendFormat(&quot;[{0}]&quot;, GetType().Name);              foreach (var property in properties) {                 if (property.Name == &quot;Data&quot;) {                     sb.Append(&quot;\\nData = &quot;);                     string s = string.Format(&quot; {0}&quot;, '{');                     s = Data.Keys.Aggregate(s,                         (current, key) =&gt; current + String.Format(&quot;\\n  {0}\\t:{1}&quot;, key, Data[key]));                     sb.AppendFormat(&quot;{0}\\n{1}&quot;, s, '}');                  }                 else sb.AppendFormat(&quot;\\n{0} = {1};&quot;, property.Name, property.GetValue(this, null));             }              return sb.ToString();         }          public void SetData(string key, object obj) {             Data[key] = obj;         }          public object GetObj(string key) {             return !Data.ContainsKey(key) ? null : Data[key];         }          public double GetDbl(string key) {             return !Data.ContainsKey(key) ? Double.NaN : Convert.ToDouble(Data[key]);         }          public int GetInt(string key) {             return !Data.ContainsKey(key) ? Int32.MinValue : Convert.ToInt32(Data[key]);         }          public bool GetBool(string key) {             return Data.ContainsKey(key) && Convert.ToBoolean(Data[key]);         }           public string GetStr(string key) {             return !Data.ContainsKey(key) ? null : Convert.ToString(Data[key]);         }          public void SetCustomData(string key, object value) {             var serializer = new JavaScriptSerializer();             var str = serializer.Serialize(value);             SetData(key, str);         }          public object GetCustom(string key, Type valueType) {             if (!Data.ContainsKey(key))                 return null;              if (Data[key].GetType() != typeof(string))                 return null;              var serializer = new JavaScriptSerializer();             var str = (string) Data[key];             var obj = serializer.Deserialize(str, valueType);              return obj;         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h3>Gate<\/h3>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/67c\/1ad\/397\/67c1ad3977774724a11ffb1f567f03c6.jpg\"\/><\/div>\n<p>  \u0421\u0443\u0442\u044c \u044f\u0434\u0440\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e \u00ab\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432\u043e\u0440\u043e\u0442\u00bb. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u0432\u043e\u0440\u043e\u0442 \u2014 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u044b\u043b\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043e\u0431\u043e\u0438\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 (\u043e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a \u044f\u0434\u0440\u0443 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e). <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">IGate.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System.ServiceModel;  namespace methanum {     [ServiceContract(CallbackContract = typeof(IListener))]     public interface IGate {         [OperationContract]         void Subscribe();          [OperationContract]         void KillConnection();          [OperationContract]         void Fire(Event evt);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443 \u043d\u0430\u0441 \u0434\u0443\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439, \u0432 \u043f\u0440\u044f\u043c\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u2014 \u043e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a \u044f\u0434\u0440\u0443 \u2014 \u0441\u0442\u0440\u0435\u043b\u044f\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0447\u0435\u0440\u0435\u0437 IGate \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 void Fire(Event evt). \u041e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u2014 \u043e\u0442 \u044f\u0434\u0440\u0430 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u2014 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 IListener \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0437\u0436\u0435.<br \/>  \u0412\u043e\u0440\u043e\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443. \u041a\u043e\u0433\u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u044f\u0434\u0440\u043e, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 Gate, \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IGate. \u0412 Gate \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 _subscribers, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u044f\u0434\u0440\u0443. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 Subscribe(), \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0435\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e. \u041c\u0435\u0442\u043e\u0434 KillConnection() \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0421\u0430\u043c\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 Fire(Event evt), \u043d\u043e \u0438 \u0432 \u043d\u0435\u043c \u043d\u0435\u0442 \u043d\u0438 \u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. \u041f\u043e\u043b\u043e\u0432\u0438\u043d\u0443 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043e\u043a\u0430\u043f\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u0434\u043e Ip \u0430\u0434\u0440\u0435\u0441\u0430 \u0438 \u043f\u043e\u0440\u0442\u0430, \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c. \u042f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u043c \u0430\u0434\u0440\u0435\u0441\u0430\u043c. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u0445\u043e\u0434\u0435 \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 Receive \u0443 \u0438\u0445 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0435\u0439 IListener. \u0415\u0441\u043b\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0442\u043e \u0435\u0433\u043e \u043d\u0435\u0437\u0430\u043c\u0435\u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Gate.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Channels;  namespace methanum {     public class Gate : IGate {         private static List&lt;OperationContext&gt; _subscribers;          public Gate() {             if (_subscribers == null)                 _subscribers = new List&lt;OperationContext&gt;();         }          public void Subscribe() {             var oc = OperationContext.Current;              if (!_subscribers.Exists(c =&gt; c.SessionId == oc.SessionId)) {                 _subscribers.Add(oc);                 Console.WriteLine(&quot;(subscribe \\&quot;{0}\\&quot;)&quot;, oc.SessionId);             }         }          public void KillConnection() {             var oc = OperationContext.Current;             _subscribers.RemoveAll(c =&gt; c.SessionId == oc.SessionId);              Console.WriteLine(&quot;(kill \\&quot;{0}\\&quot;)&quot;, oc.SessionId);         }          public void Fire(Event evt) {             var currentOperationContext = OperationContext.Current;             var remoteEndpointMessageProperty =                 currentOperationContext.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as                     RemoteEndpointMessageProperty;             var ip = &quot;&quot;;             var port = 0;              if (remoteEndpointMessageProperty != null) {                 ip = remoteEndpointMessageProperty.Address;                 port = remoteEndpointMessageProperty.Port;             }              Console.WriteLine(&quot;(Fire (event . \\&quot;{0}\\&quot;) (from . \\&quot;{1}:{2}\\&quot;) (subscribers . {3}))&quot;, evt.Id, ip, port, _subscribers.Count);              for (var i = _subscribers.Count - 1; i &gt;= 0; i--) {                 var oc = _subscribers[i];                  if (oc.Channel.State == CommunicationState.Opened) {                     var channel = oc.GetCallbackChannel&lt;IListener&gt;();                       try {                         ((DelegateReceive) (channel.Receive)).BeginInvoke(evt, null, null);                     }                     catch (Exception e) {                         Console.WriteLine(e.Message);                     }                 }                 else {                     _subscribers.RemoveAt(i);                     Console.WriteLine(&quot;(dead . \\&quot;{0}\\&quot;)&quot;, oc.SessionId);                 }             }         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h3>Listener<\/h3>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/023\/839\/be7\/023839be78ae45a092487ec9c7db4c30.jpg\"\/><\/div>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u044f\u0434\u0440\u0430 \u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 Receive, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 IListener. <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">IListener.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System.ServiceModel;  namespace methanum {     public delegate void DelegateReceive(Event evt);     interface IListener {         [OperationContract(IsOneWay = true)]         void Receive(Event evt);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IListener \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 Connector, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u044f\u0434\u0440\u0430. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u044f\u0434\u0440\u0443, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u044f\u0434\u0440\u0430. \u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0432 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 Destination. \u0424\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 if-then-else \u0438\u043b\u0438 switch-case \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044e \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0422\u0430\u043a\u043e\u0435 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 Dictionary&lt;string, CbHandler&gt; _handlers;. \u041a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u043e, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 \u0438, \u0435\u0441\u043b\u0438 \u043a\u043b\u044e\u0447 \u043d\u0430\u0439\u0434\u0435\u043d, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u043d\u0438\u0436\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f. \u0415\u0435 \u0441\u0443\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043c\u0438\u043d\u0443\u044f \u044f\u0434\u0440\u043e.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Connector.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.ServiceModel; using System.Threading;  namespace methanum {     public delegate void CbHandler(Event evt);      public class Connector : IListener {         private Dictionary&lt;string, CbHandler&gt; _handlers;         private NetTcpBinding _binding;         private EndpointAddress _endpointToAddress;         private InstanceContext _instance;         private DuplexChannelFactory&lt;IGate&gt; _channelFactory;         private IGate _channel;         private Thread _fireThread;         private List&lt;Event&gt; _eventQueue;          public event CbHandler ReceiveEvent;          private bool _isSubscribed;          private object _channelSync = new object();          protected virtual void OnReceive(Event evt) {             CbHandler handler = ReceiveEvent;             if (handler != null) handler.BeginInvoke(evt, null, null);         }          \/\/localhost:2255         public Connector(string ipAddress) {             init(ipAddress);         }          private void init(string ipAddress) {             _handlers = new Dictionary&lt;string, CbHandler&gt;();             _binding = new NetTcpBinding();             _endpointToAddress = new EndpointAddress(string.Format(&quot;net.tcp:\/\/{0}&quot;, ipAddress));             _instance = new InstanceContext(this);              Conect();              _eventQueue = new List&lt;Event&gt;();                          _fireThread = new Thread(FireProc);             _fireThread.IsBackground = true;             _fireThread.Start();         }          private void Conect() {             _isSubscribed = false;              while (!_isSubscribed) {                 try {                     _channelFactory = new DuplexChannelFactory&lt;IGate&gt;(_instance, _binding, _endpointToAddress);                                          _channel = _channelFactory.CreateChannel();                      _channel.Subscribe();                     _isSubscribed = true;                 }                 catch (Exception e) {                     if (!(e is EndpointNotFoundException)) throw e;                      Thread.Sleep(1000);                 }             }         }          private void ReConect() {             lock (_channelSync) {                 try {                     _channel.KillConnection();                 }                 catch (Exception e) {                     Console.WriteLine(&quot;(ReConect-exception  \\&quot;{0}\\&quot;&quot;, e.Message);                 }                 Conect();             }         }          public void Fire(Event evt) {             if (_handlers.ContainsKey(evt.Destination)) {                  _handlers[evt.Destination].BeginInvoke(evt, null, null);                 return;             }              lock (_eventQueue) {                 _eventQueue.Add(evt);             }         }          private void FireProc() {             while (true) {                 var isHasEventsToFire = false;                  lock (_eventQueue) {                     isHasEventsToFire = _eventQueue.Any();                 }                  if (_isSubscribed && isHasEventsToFire) {                     Event evt;                      lock (_eventQueue) {                         evt = _eventQueue.First();                     }                      try {                         lock (_eventQueue) {                             _eventQueue.Remove(evt);                         }                          _channel.Fire(evt);                      }                     catch (Exception) {                         if (_isSubscribed)                             _isSubscribed = false;                         ReConect();                     }                 } else Thread.Sleep(10);             }         }          public void SetHandler(string destination, CbHandler handler) {             _handlers[destination] = handler;         }          public void DeleteHandler(string destination) {             if(_handlers.ContainsKey(destination)) _handlers.Remove(destination);         }          public void Receive(Event evt) {             if (_handlers.ContainsKey(evt.Destination)) {                 _handlers[evt.Destination].BeginInvoke(evt, null, null);             }              OnReceive(evt);         }          static public void HoldProcess() {             var processName = Process.GetCurrentProcess().ProcessName;             var defColor = Console.ForegroundColor;              Console.ForegroundColor = ConsoleColor.Green;              Console.WriteLine(&quot;The {0} is ready&quot;, processName);             Console.WriteLine(&quot;Press &lt;Enter&gt; to terminate {0}&quot;, processName);              Console.ForegroundColor = defColor;              Console.ReadLine();         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043b\u0430\u0441\u0441, \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">SrvRunner.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.ServiceModel;  namespace methanum {     public class SrvRunner {         private ServiceHost _sHost;          public void Start(int port) {             var uris = new[] { new Uri(string.Format(&quot;net.tcp:\/\/0.0.0.0:{0}&quot;, port)) };                          _sHost = new ServiceHost(typeof (Gate), uris);              _sHost.Open();              foreach (var uri2 in _sHost.BaseAddresses) {                 Console.WriteLine(&quot;Start on: {0}&quot;, uri2.ToString());             }         }          public void Stop() {             _sHost.Close();         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h3>Core<\/h3>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/264\/c2c\/9c6\/264c2c9c6d7f4ad0b8af34e00c3f7902.jpg\"\/><\/div>\n<p>  \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0432\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044f\u0434\u0440\u043e, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u201cCore\u201d \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a \u043d\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443 methanum. \u0412\u043e\u043e\u0431\u0449\u0435, \u043c\u044b \u0443\u0436\u0435 \u0432\u0441\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">CoreMain.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Linq; using methanum;  namespace Core {     internal class CoreMain {         private static void Main(string[] args) {             int port = 0;             if ((!args.Any()) || (!int.TryParse(args[0], out port))) {                 Console.WriteLine(&quot;Usage:&quot;);                 Console.WriteLine(&quot;Core.exe port&quot;);                 Environment.Exit(1);             }              try {                 var coreSrv = new SrvRunner();                 coreSrv.Start(port);                  Console.WriteLine(&quot;The Core is ready.&quot;);                 Console.WriteLine(&quot;Press &lt;ENTER&gt; to terminate Core.&quot;);                 Console.ReadLine();                  coreSrv.Stop();             }             catch (Exception e) {                 Console.WriteLine(e.Message);             }         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <b>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/b><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/49b\/040\/6f9\/49b0406f95c34bc1907fc5cc68c43b6a.jpg\"\/><\/div>\n<p>  \u0414\u043b\u044f \u0434\u0435\u043c\u043e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0435\u0441\u0435\u043d\u0434\u0436\u0435\u0440: \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u043d\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 methanum \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 Program.cs.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Program.cs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Linq; using methanum;  namespace ClentExamle {     class Program {         static void Main(string[] args) {              if ((!args.Any())) {                 Console.WriteLine(&quot;Usage:&quot;);                 Console.WriteLine(&quot;ClentExample.exe coreAddress:port&quot;);                 Environment.Exit(1);             }              var userName = &quot;&quot;;              while (String.IsNullOrWhiteSpace(userName)) {                 Console.WriteLine(&quot;Please write user name:&quot;);                 userName = Console.ReadLine();                }              try {                 var maingate = new Connector(args[0]);                  maingate.SetHandler(&quot;message&quot;, MsgHandler);                  Console.WriteLine(&quot;Hello {0}, now you can send messages&quot;, userName);                  while (true) {                     var msg = Console.ReadLine();                     var evt = new Event(&quot;message&quot;);                     evt.SetData(&quot;name&quot;, userName);                     evt.SetData(&quot;text&quot;, msg);                      maingate.Fire(evt);                 }             }             catch (Exception e) {                 Console.WriteLine(e.Message);             }         }          static private void MsgHandler(Event evt) {             Console.WriteLine(&quot;[{0}] &gt;&gt; {1}&quot;, evt.GetStr(&quot;name&quot;), evt.GetStr(&quot;text&quot;));         }      } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Core.exe \u0443\u043a\u0430\u0437\u0430\u0432 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u043f\u043e\u0440\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u201cCore 2255\u201d. \u0417\u0430\u0442\u0435\u043c \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 ClentExample.exe \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u201cClentExample localhost:2255\u201d. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442 \u0432\u0432\u0435\u0441\u0442\u0438 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u043a \u044f\u0434\u0440\u0443. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0435\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0447\u0430\u0442: \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u043c maingate.Fire(evt), \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 MsgHandler(Event evt). <\/p>\n<p>  \u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 \u0433\u0438\u0445\u0430\u0431\u0435 <a href=\"https:\/\/github.com\/Beetle-ru\/methanum\">methanum<\/a>.               <\/p>\n<div class=\"clear\"><\/div>\n<p> \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:\/\/habrahabr.ru\/post\/280640\/\"> https:\/\/habrahabr.ru\/post\/280640\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div style=\"text-align:center;\"><img decoding=\"async\"  src=\"https:\/\/habrastorage.org\/files\/306\/5f6\/5e7\/3065f65e7fee43d184d814e252f1cb47.png\"\/><\/div>\n<p>  \u0417\u0432\u0435\u0437\u0434\u0430 \u2014 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u0434\u0435\u043d\u044c \u0441\u0430\u043c\u0430\u044f \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u0430\u044f \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u044f \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439. \u0422\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0440\u044f\u0434\u043e\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432: \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c\u044e (\u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0442\u0440\u043e\u044f \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043d\u0435 \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445) \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0430\u0432\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0438 \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u043d\u0430 \u0441\u0443\u0434 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f .Net \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0441 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u0437\u0432\u0435\u0437\u0434\u0430. <\/p>\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-277437","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/277437","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=277437"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/277437\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=277437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=277437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=277437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}