{"id":281473,"date":"2016-11-24T10:35:05","date_gmt":"2016-11-24T07:35:05","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=281473"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=281473","title":{"rendered":"WebRTC: \u0414\u0435\u043b\u0430\u0435\u043c peer to peer \u0438\u0433\u0440\u0443 \u043d\u0430 javascript"},"content":{"rendered":"<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u043d\u0435 \u0434\u043e\u0432\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u043c \u0432\u0438\u0434\u0435\u043e\u0447\u0430\u0442\u0430. \u042d\u0442\u043e \u0431\u044b\u043b \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0432\u043e\u0434 \u043f\u043e\u0431\u043b\u0438\u0436\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f\u043c\u0438 WebRTC \u0438 \u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043f\u0440\u043e WebRTC, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044e\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u0443\u0434\u0438\u043e- \u0438 \u0432\u0438\u0434\u0435\u043e\u0441\u0432\u044f\u0437\u0438, \u043d\u043e \u044d\u0442\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439. \u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c peer-to-peer \u0438\u0433\u0440\u0443 \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f. \u0412\u0438\u0434\u0435\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/8f4\/a22\/330\/8f4a223309db459695247a0d44ddb051.png\"\/><\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<div class=\"oembed\">\n<div>\n<div style=\"left: 0px; width: 100%; height: 0px; position: relative; padding-bottom: 56.2493%;\"><iframe src=\"https:\/\/www.youtube.com\/embed\/-kKUFLyCyJw?rel=0&amp;showinfo=1\" frameborder=\"0\" allowfullscreen=\"true\" webkitallowfullscreen=\"true\" mozallowfullscreen=\"true\" style=\"top: 0px; left: 0px; width: 100%; height: 100%; position: absolute;\"><\/iframe><\/div>\n<\/div>\n<\/div>\n<h4>\u0414\u0432\u0438\u0436\u043e\u043a \u0434\u043b\u044f \u0438\u0433\u0440\u044b<\/h4>\n<p>  \u041a\u0430\u043a-\u0442\u043e \u0434\u0430\u0432\u043d\u044b\u043c-\u0434\u0430\u0432\u043d\u043e \u043c\u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u043d\u0430 \u0433\u043b\u0430\u0437\u0430 \u0434\u0435\u043c\u043a\u0430 \u0438\u0433\u0440\u044b \u0441 \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u043f\u0438\u043a\u0441\u0435\u043b\u044c\u0430\u0440\u0442 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439. \u0418\u0433\u0440\u0430 \u0431\u044b\u043b\u0430 \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u043d\u0430 JavaScript-\u0434\u0432\u0438\u0436\u043a\u0435 <a href=\"http:\/\/impactjs.com\/\">Impact<\/a>. \u041f\u0440\u043e \u043d\u0435\u0433\u043e \u0434\u0430\u0436\u0435 \u043a\u0430\u043a-\u0442\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438 \u043d\u0430 <a href=\"https:\/\/habrahabr.ru\/post\/106241\/\">\u0425\u0430\u0431\u0440\u0435<\/a>. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c1d\/710\/f16\/c1d710f16f3c45a6b7ced0a517f3fb34.png\"\/><\/p>\n<p>  \u0414\u0432\u0438\u0436\u043e\u043a \u043f\u043b\u0430\u0442\u043d\u044b\u0439, \u044f \u043a\u0443\u043f\u0438\u043b \u0435\u0433\u043e \u0435\u0449\u0435 \u043f\u0430\u0440\u0443 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434, \u043d\u043e \u0442\u0430\u043a \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430 \u043d\u0435\u043c \u0438 \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u043b, \u0438 \u0432\u043e\u0442 \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043e\u043d \u043c\u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u043b\u0441\u044f. \u041d\u0430\u0434\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u044b \u043d\u0430 \u043d\u0435\u043c \u2014 \u043e\u0447\u0435\u043d\u044c \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435, \u0438 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439 \u0432\u0440\u043e\u0434\u0435 \u043c\u0435\u043d\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u044f\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u043e \u043e\u0449\u0443\u0442\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u043a\u0440\u0443\u0442\u044b\u043c\u0438 \u00ab\u0438\u0433\u0440\u043e\u0434\u0435\u043b\u0430\u043c\u0438\u00bb, \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432\u0448\u0438\u0441\u044c \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439 \u0441\u0432\u044f\u0437\u0438 \u0438 \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u0434\u0432\u0438\u0436\u043a\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041b\u0438\u0447\u043d\u043e \u044f \u043d\u0430\u0447\u0430\u043b \u0441 \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043a\u043e\u043c\u043d\u0430\u0442.<\/p>\n<h4>\u0418\u0433\u0440\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043d\u0430\u0442\u044b<\/h4>\n<p>  \u041a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0438\u0433\u0440\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0438\u0433\u0440\u0443 \u0438 \u043a\u0430\u043a \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u0432 \u043d\u0435\u0435 \u0441\u0432\u043e\u0438\u0445 \u0434\u0440\u0443\u0437\u0435\u0439? \u041c\u043d\u043e\u0433\u0438\u0435 \u043e\u043d\u043b\u0430\u0439\u043d-\u0438\u0433\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u043a\u043e\u043c\u043d\u0430\u0442\u044b \u0438\u043b\u0438 \u043a\u0430\u043d\u0430\u043b\u044b, \u0447\u0442\u043e\u0431\u044b \u0438\u0433\u0440\u043e\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u0438\u0433\u0440\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0441\u0430\u043c\u044b\u0435 \u043a\u043e\u043c\u043d\u0430\u0442\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\/\u0443\u0434\u0430\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0421\u0445\u0435\u043c\u0430 \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0438\u0433\u0440\u0443, \u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0438\u0433\u0440\u044b, \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ol>\n<li>\u043d\u043e\u0432\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438\u043c\u044f \u043a\u043e\u043c\u043d\u0430\u0442\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0438\u0433\u0440\u0430\u0442\u044c;<\/li>\n<li>\u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u044b;<\/li>\n<li>\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u0433\u0440\u043e\u043a\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430.<\/li>\n<\/ol>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/7e1\/1d0\/550\/7e11d05507f14aaab4d367c6bfb91e6a.png\"\/><\/p>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 node.js + socket.io. \u0422\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/gutnikov\/webrtc-shooter\/blob\/master\/signalling\/server.js\">\u0442\u0443\u0442<\/a>. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0438\u0433\u0440\u043e\u043a \u043f\u043e\u043f\u0430\u043b \u0432 \u0438\u0433\u0440\u043e\u0432\u0443\u044e \u043a\u043e\u043c\u043d\u0430\u0442\u0443, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c peer-to-peer \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0438\u0437 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0432 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u0435 \u0438\u0433\u0440\u043e\u043a\u043e\u0432. \u041d\u043e, \u0434\u043e \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 peer-to-peer \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u0435 \u044d\u0442\u043e \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<h4>\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/h4>\n<p>  \u0424\u043e\u0440\u043c\u0430\u0442 \u0438 \u0441\u043c\u044b\u0441\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438, \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0438\u0433\u0440\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 2D-\u0448\u0443\u0442\u0435\u0440, \u0433\u0434\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0431\u0435\u0433\u0430\u044e\u0442 \u0438 \u0441\u0442\u0440\u0435\u043b\u044f\u044e\u0442 \u0434\u0440\u0443\u0433 \u0432 \u0434\u0440\u0443\u0433\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u043c\u0435\u0441\u0442\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u043d\u0430 \u043a\u0430\u0440\u0442\u0435:<\/p>\n<pre><code>message PlayerPosition {     int16 x;     int16 y; } <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u044f \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u0434\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0433\u0440\u043e\u043a, \u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u043e\u043d \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u043a\u0430\u0440\u0442\u0438\u043d\u044b \u0441\u044e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0430\u044f \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u0438\u0433\u0440\u043e\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f, \u0432 \u043a\u0430\u043a\u043e\u043c \u043e\u043d\u0430 \u043a\u0430\u0434\u0440\u0435 \u0438 \u0432 \u043a\u0430\u043a\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043e\u043d \u0441\u043c\u043e\u0442\u0440\u0438\u0442:<\/p>\n<pre><code>message PlayerPositionAndAnimation {     int16 x;     int16 y;     int8 anim;     int8 animFrame;     bool flipped; } <\/code><\/pre>\n<p>  \u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u041a\u0430\u043a\u0438\u0435 \u0435\u0449\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f? \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0438\u0433\u0440\u0435, \u0443 \u0432\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u0432\u043e\u0439 \u043d\u0430\u0431\u043e\u0440, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\u0438\u0433\u0440\u043e\u043a \u0443\u043c\u0438\u0440\u0430\u0435\u0442 ();<\/li>\n<li>\u0438\u0433\u0440\u043e\u043a \u0440\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f ( int16 x, int16 y );<\/li>\n<li>\u0438\u0433\u0440\u043e\u043a \u0441\u0442\u0440\u0435\u043b\u044f\u0435\u0442 ( int16 x, int16 y, boolean flipped );<\/li>\n<li>\u0438\u0433\u0440\u043e\u043a \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0440\u0443\u0436\u0438\u0435 ( int8 weapon_id).<\/li>\n<\/ul>\n<h4>\u0422\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0445<\/h4>\n<p>  \u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0445 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <i>int16<\/i> \u2014 \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0439, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u0432 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u0437\u0430\u043e\u0434\u043d\u043e \u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e WebRTC API. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u043f\u0438\u0440\u0430\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <i>RTCDataChannel<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0443\u043c\u0435\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430 <i>USVString<\/i>, <i>BLOB<\/i>, <i>ArrayBuffer<\/i> \u0438\u043b\u0438 <i>ArrayBufferView<\/i>. \u041a\u0430\u043a \u0440\u0430\u0437 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <i>ArrayBufferView<\/i>, \u0438 \u043d\u0443\u0436\u043d\u043e \u0447\u0435\u0442\u043a\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043e\u043f\u0438\u0441\u0430\u0432 \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u0438\u0440\u0430\u043c\u0438. \u0417\u0434\u0435\u0441\u044c \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0430\u0442\u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0440\u0430\u0442\u043a\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u043e\u0433\u0443. \u0412\u043e\u043e\u0431\u0449\u0435, \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e WebRTC \u0432\u043e \u0432\u0441\u0435\u0445 \u0434\u0435\u0442\u0430\u043b\u044f\u0445 \u2014 \u0434\u043e\u043b\u0433\u043e\u0435 \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0447\u0442\u043e \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0435\u0441\u0442\u044c <a href=\"https:\/\/hpbn.co\/\">\u043a\u043d\u0438\u0433\u0430 \u0418\u043b\u044c\u0438 \u0413\u0440\u0438\u0433\u043e\u0440\u0438\u043a\u0430<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0430\u0434\u0435\u0437\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u0443 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0435\u043c\u044b, \u043a\u0430\u0441\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041c\u043e\u044f \u0436\u0435 \u0446\u0435\u043b\u044c, \u043a\u0430\u043a \u044f \u0443\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u043b, \u2014 \u0434\u0430\u0442\u044c \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 WebRTC, \u0441 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u043c\u0443. <\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0427\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0410 \u0438 \u0411 \u0441\u043c\u043e\u0433\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c peer-to-peer \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439? \u041d\u0443, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0438 \u043f\u043e\u0440\u0442, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0435\u0433\u043e \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041d\u043e \u043a\u0430\u043a \u0410 \u0438 \u0411 \u0441\u043e\u043e\u0431\u0449\u0430\u0442 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443 \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0435\u0441\u043b\u0438 \u0441\u0432\u044f\u0437\u044c \u0435\u0449\u0435 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430? \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0443\u0436\u0435\u043d \u0441\u0435\u0440\u0432\u0435\u0440. \u0412 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438 WebRTC \u043e\u043d \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f signalling-\u0441\u0435\u0440\u0432\u0435\u0440. \u0418 \u0442\u0430\u043a \u043a\u0430\u043a \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043a\u043e\u043c\u043d\u0430\u0442, \u0435\u0433\u043e \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 signalling-\u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043a\u0440\u043e\u043c\u0435 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0438 \u043f\u043e\u0440\u0442\u043e\u0432, \u0410 \u0438 \u0411 \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f \u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438.\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u043a\u043e\u0434\u0435\u043a\u043e\u0432 \u0438 \u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0430\u0443\u0434\u0438\u043e- \u0438 \u0432\u0438\u0434\u0435\u043e \u0441\u0432\u044f\u0437\u0438. \u0424\u043e\u0440\u043c\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f SDP \u2014 Session Description Protocol. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441 \u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u043d\u0430 <a href=\"https:\/\/webrtchacks.com\/sdp-anatomy\/\">webrtchacks.com<\/a>. \u0418\u0442\u0430\u043a, \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u044b\u0448\u0435\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 signalling \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<ol>\n<li>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0410 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0411;<\/li>\n<li>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0411 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 \u0410;<\/li>\n<li>\u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0410 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0439 IP, \u043f\u043e\u0440\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 \u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0411;<\/li>\n<li>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0411 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441, \u043f\u043e\u0440\u0442 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0435\u0441\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0410.<\/li>\n<\/ol>\n<p>  \u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u044d\u0442\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043e\u0431\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0437\u043d\u0430\u044e\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430 \u0438 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041d\u043e \u0434\u043e \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0441\u0442\u043e\u0438\u0442 \u0435\u0449\u0435 \u043a\u043e\u0435-\u0447\u0442\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043f\u0440\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u044b IP-\u0430\u0434\u0440\u0435\u0441 + \u043f\u043e\u0440\u0442. <\/p>\n<h4>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438<\/h4>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u043c\u0443 IP-\u0430\u0434\u0440\u0435\u0441\u0443 \u0438\u043b\u0438 \u043e\u0431\u0430 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0435\u0442\u0438 \u2014 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u0422\u043e\u0433\u0434\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u0432\u043e\u0439 IP \u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 signalling \u0441\u0432\u043e\u0435\u043c\u0443 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0443. \u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430 NAT, \u0438 \u0443 \u043d\u0435\u0433\u043e \u0434\u0432\u0430 \u0430\u0434\u0440\u0435\u0441\u0430: \u043e\u0434\u0438\u043d \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439, \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0434\u0441\u0435\u0442\u0438 (<b>192.168.1.1<\/b>), \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u0430\u0434\u0440\u0435\u0441 \u0441\u0430\u043c\u043e\u0433\u043e NAT (<b>50.76.44.114<\/b>)? \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u043c\u0443 \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0438 \u043f\u043e\u0440\u0442. <\/p>\n<p>  \u0418\u0434\u0435\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430: \u043d\u0443\u0436\u0435\u043d \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 \u043d\u0430\u0441, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430\u0448 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0438 \u043f\u043e\u0440\u0442. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/5c2\/5c2\/ab0\/5c25c2ab0b6f468e965cb33e119593e4.png\"\/><\/p>\n<p>  \u0422\u0430\u043a\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f STUN ( <a href=\"https:\/\/en.wikipedia.org\/wiki\/STUN\">Session Traversal Utilities for NAT<\/a> ). \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, coturn, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0432\u043e\u0435\u0433\u043e STUN-\u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u0435\u0449\u0435 \u043f\u0440\u043e\u0449\u0435 \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u043c\u0438 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442 Google.<\/p>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u0438 \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0443. \u041d\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0432\u0435\u0434\u044c \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u043e\u0442 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043c\u043e\u0436\u0435\u043c \u043b\u0438 \u043c\u044b \u0434\u043e\u0441\u0442\u0443\u0447\u0430\u0442\u044c\u0441\u044f \u0434\u043e \u043d\u0435\u0433\u043e \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443? <\/p>\n<p>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e STUN \u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0431\u0435\u0440\u0435\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f ICE (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Interactive_Connectivity_Establishment\">Interactive Connectivity Establishment<\/a>) \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u2014 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430. \u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\u2026<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u041f\u043e\u043d\u0430\u0447\u0430\u043b\u0443 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0439. \u041d\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0432\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u0430 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0437\u0430 \u043e\u0434\u043d\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c RTCPeerConnection, \u0438 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e peer-to-peer \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/gutnikov\/webrtc-shooter\/blob\/master\/lib\/net\/peer-connection.js\">\u0442\u0443\u0442<\/a>, \u0434\u0430\u043b\u044c\u0448\u0435 \u044f \u043f\u043e\u044f\u0441\u043d\u044e \u0435\u0433\u043e. <\/p>\n<p>  \u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u043b, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 SDP \u0438 ICE \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430\u043c\u0438 \u2014 \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 RTCPeerConnection. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/RTCPeerConnection\/RTCPeerConnection\">\u0442\u0443\u0442<\/a>. \u041d\u0430\u043c \u0436\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0434\u0440\u0435\u0441 STUN-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u0442 Google, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0432\u044b\u0448\u0435.<\/p>\n<pre><code class=\"javascript\">iceServers: [{     url: 'stun:stun.l.google.com:19302' }], connect: function() {     this.peerConnection = new RTCPeerConnection({       iceServers: this.iceServers     });     \/\/ ... } <\/code><\/pre>\n<p>  RTCPeerConnection \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043b\u0431\u0435\u043a\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f:  <\/p>\n<ol>\n<li> icecandidate \u2014 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430;<\/li>\n<li> iceconnectionstatechange \u2014 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f;<\/li>\n<li> datachannel \u2014 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u0430\u043d\u043d\u044b\u0445.<\/li>\n<\/ol>\n<pre><code class=\"javascript\">init: function(socket, peerUser, isInitiator) {     \/\/ ...     this.peerHandlers = {       'icecandidate': this.onLocalIceCandidate,       'iceconnectionstatechange': this.onIceConnectionStateChanged,       'datachannel': this.onDataChannel     };     this.connect();   },   connect: function() {     \/\/ ...     Events.listen(this.peerConnection, this.peerHandlers, this);     \/\/ .... } <\/code><\/pre>\n<h4>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435<\/h4>\n<p>  \u0412 \u0441\u043f\u0438\u0441\u043a\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u044b\u043c\u0438 \u0434\u0432\u0443\u043c\u044f \u043f\u0443\u043d\u043a\u0442\u0430\u043c\u0438 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041c\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u043d\u0430\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u044b, \u0442\u043e \u043a\u0442\u043e-\u0442\u043e \u0434\u0430\u043b \u0435\u043c\u0443 \u0441\u0441\u044b\u043b\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u0432\u044f\u0437\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043e\u0431\u043c\u0435\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438.<\/p>\n<h4>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0441\u0435\u0441\u0441\u0438\u0438<\/h4>\n<p>  \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0441\u0435\u0441\u0441\u0438\u0438 \u0432 <i>RTCPeerConnection<\/i> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043c\u0435\u0442\u043e\u0434\u044b <i>createOffer<\/i> \u2014 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u0438 <i>createAnswer<\/i> \u2014 \u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0439. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 SDP, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 signalling \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0443. <i>RTCPeerConnection<\/i> \u0445\u0440\u0430\u043d\u0438\u0442 \u043a\u0430\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438, \u0442\u0430\u043a \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0447\u0435\u0440\u0435\u0437 signalling \u043e\u0442 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b <i>setLocalDescription<\/i> \u0438 <i>setRemoteDescription<\/i>. \u0418\u0442\u0430\u043a, \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442 \u0410 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<p>  1. \u041a\u043b\u0438\u0435\u043d\u0442 \u0410 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 SDP-offer, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 \u0432 \u0441\u0432\u043e\u0435\u043c <i>RTCPeerConnection<\/i>, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0411:<\/p>\n<pre><code class=\"javascript\">connect: function() {     \/\/ ...     if (this.isInitiator) {       this.setLocalDescriptionAndSend();     }   },      setLocalDescriptionAndSend: function() {     var self = this;     self.getDescription()       .then(function(localDescription) {         self.peerConnection.setLocalDescription(localDescription)           .then(function() {             self.log('Sending SDP', 'green');             self.sendSdp(self.peerUser.userId, localDescription);           });       })       .catch(function(error) {         self.log('onSdpError: ' + error.message, 'red');       });   },    getDescription: function() {     return this.isInitiator ?       this.peerConnection.createOffer() :       this.peerConnection.createAnswer();   } <\/code><\/pre>\n<p>  2. \u041a\u043b\u0438\u0435\u043d\u0442 \u0411 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 offer \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0410 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u0442 SDP-answer, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0410:<\/p>\n<pre><code class=\"javascript\">setSdp: function(sdp) {     var self = this;     \/\/ Create session description from sdp data     var rsd = new RTCSessionDescription(sdp);     \/\/ And set it as remote description for peer connection     self.peerConnection.setRemoteDescription(rsd)       .then(function() {         self.remoteDescriptionReady = true;         self.log('Got SDP from remote peer', 'green');         \/\/ Add all received remote candidates         while (self.pendingCandidates.length) {           self.addRemoteCandidate(self.pendingCandidates.pop());         }         \/\/ Got offer? send answer         if (!self.isInitiator) {           self.setLocalDescriptionAndSend();         }       });   } <\/code><\/pre>\n<p>  4. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442 \u0410 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 SDP-answer \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0411, \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0438. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u043e\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/178\/990\/959\/1789909590094f9498e5e3b2851b7caf.png\"\/><\/p>\n<h4>\u0421\u0431\u043e\u0440 ICE-\u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u043e\u0432<\/h4>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043a\u043e\u0433\u0434\u0430 ICE-\u0430\u0433\u0435\u043d\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0410 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043d\u043e\u0432\u0443\u044e \u043f\u0430\u0440\u0443 IP+port, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438, \u0443 RTCPeerConnection \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <i>icecandidate<\/i>. \u0414\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <code>candidate:842163049 1 <b>udp<\/b> 1677729535 <b>94.221.38.159 60478 typ srflx raddr 192.168.1.157 rport 60478<\/b> generation 0 ufrag KadE network-cost 50<br \/>  <\/code><\/p>\n<p>  \u0412\u043e\u0442 \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u043b\u044f\u0434\u044f \u043d\u0430 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<ol>\n<li><b>udp<\/b>: \u0415\u0441\u043b\u0438 ICE-\u0430\u0433\u0435\u043d\u0442 \u0440\u0435\u0448\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438, \u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d udp \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442;<\/li>\n<li><b>typ srflx<\/b> \u2014 \u044d\u0442\u043e \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a STUN-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 NAT;<\/li>\n<li><b>94.221.38.159 60478<\/b> \u2014 \u0430\u0434\u0440\u0435\u0441 NAT \u0438 \u043f\u043e\u0440\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438;<\/li>\n<li><b>raddr 192.168.1.157 rport 60478 <\/b>\u2014 \u0430\u0434\u0440\u0435\u0441 \u0438 \u043f\u043e\u0440\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 NAT.<\/li>\n<\/ol>\n<p>  \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f ICE-\u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/tools.ietf.org\/html\/rfc5245#section-1\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  \u042d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 signalling \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0411, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0438\u0445 \u0432 \u0441\u0432\u043e\u0439 RTCPeerConnection. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0411, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u0430\u0440\u044b IP+port:<\/p>\n<pre><code class=\"javascript\"> \/\/ When ice framework discoveres new ice candidate, we should send it   \/\/ to opponent, so he knows how to reach us   onLocalIceCandidate: function(event) {     if (event.candidate) {       this.log('Send my ICE-candidate: ' + event.candidate.candidate, 'gray');       this.sendIceCandidate(this.peerUser.userId, event.candidate);     } else {       this.log('No more candidates', 'gray');     }   } <\/code><\/pre>\n<pre><code class=\"javascript\">  addRemoteCandidate: function(candidate) {     try {       this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));       this.log('Added his ICE-candidate:' + candidate.candidate, 'gray');     } catch (err) {       this.log('Error adding remote ice candidate' + err.message, 'red');     }   } <\/code><\/pre>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>  \u041d\u0443 \u0438, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u043d\u0430 \u0447\u0435\u043c \u0441\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u044d\u0442\u043e <i>RTCDataChannel<\/i>. \u042d\u0442\u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c API, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445: <\/p>\n<ul>\n<li>\u043f\u043e\u043b\u043d\u0443\u044e \u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0443\u044e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439;<\/li>\n<li>\u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u0443\u044e \u0438\u043b\u0438 \u043d\u0435\u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u0443\u044e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/li>\n<\/ul>\n<p>  \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043f\u0440\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e <i>RTCDataChannel<\/i> \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/RTCDataChannel\">\u0442\u0443\u0442<\/a>. \u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 ordered = false, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 UDP \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u0430\u043a \u0438 <i>RTCPeerConnection<\/i>, <i>RTCDataChannel<\/i> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u0418\u0437 \u043d\u0435\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f <i>open<\/i>, <i>close<\/i> \u0438 <i>message<\/i> \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f, \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e:<\/p>\n<pre><code class=\"javascript\">init: function(socket, peerUser, isInitiator) {     \/\/ ...     this.dataChannelHandlers = {       'open': this.onDataChannelOpen,       'close': this.onDataChannelClose,       'message': this.onDataChannelMessage     };     this.connect();   },   connect: function() {     \/\/ ...     if (this.isInitiator) {       this.openDataChannel(           this.peerConnection.createDataChannel(this.CHANNEL_NAME, {         ordered: false       }));     }   },   openDataChannel: function(channel) {     this.dataChannel = channel;     Events.listen(this.dataChannel, this.dataChannelHandlers, this);   } <\/code><\/pre>\n<p>  \u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. <\/p>\n<h4>\u0411\u043e\u043b\u044c\u0448\u0435 \u0438\u0433\u0440\u043e\u043a\u043e\u0432<\/h4>\n<p>  \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438, \u0438 \u044d\u0442\u043e\u0433\u043e, \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0433\u0440\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0430 \u043e\u0434\u0438\u043d. \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0432 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u043d\u0430\u0442\u0435 \u043c\u043e\u0433\u043b\u0438 \u0438\u0433\u0440\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432? \u0427\u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f? \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u2014 \u043d\u0438\u0447\u0435\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u0432\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435. \u0422.\u0435. \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0433\u0440\u0430\u0435\u0442\u0435 \u0432 \u043a\u043e\u043c\u043d\u0430\u0442\u0435 \u0435\u0449\u0435 \u0441 3 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438, \u0443 \u0432\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u043e 3 peer-to-peer \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0438\u0437 \u043d\u0438\u0445. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u0437\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u043e \u043a\u043e\u043c\u043d\u0430\u0442\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/gutnikov\/webrtc-shooter\/blob\/master\/lib\/net\/room-connection.js\">\u0442\u0443\u0442<\/a>. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/58b\/73e\/f9e\/58b73ef9e1274e6083b455e2ce8b98a8.png\"\/><\/p>\n<p>  \u0418\u0442\u0430\u043a, signalling-\u0441\u0435\u0440\u0432\u0435\u0440 c \u043a\u043e\u043c\u043d\u0430\u0442\u0430\u043c\u0438 \u0433\u043e\u0442\u043e\u0432, \u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043e\u0431\u0441\u0443\u0434\u0438\u043b\u0438, \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0438\u0433\u0440\u043e\u043a\u0438 \u0432\u0438\u0434\u0435\u043b\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430?<\/p>\n<h4>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0418\u0434\u0435\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043d\u0443\u0436\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0441\u0432\u043e\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0442\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0433\u0443\u0442 \u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u043d\u043e \u043e\u0442\u0440\u0430\u0436\u0430\u0442\u044c \u0442\u0432\u043e\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u041a\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f? \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0438\u0434\u0435\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u043a \u0436\u0435 \u0447\u0430\u0441\u0442\u043e, \u043a\u0430\u043a \u0438 \u0441\u0430\u043c \u0438\u0433\u0440\u043e\u043a, \u0442.\u0435. \u0435\u0441\u043b\u0438 \u0438\u0433\u0440\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0444\u0440\u0435\u0439\u043c\u0440\u0435\u0439\u0442\u043e\u043c 30-60 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u0442\u043e \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0442\u043e\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439. \u041d\u043e \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0430\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u043e\u0441\u0442\u0438 \u0441\u0430\u043c\u043e\u0439 \u0438\u0433\u0440\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u043e\u0438\u0442 \u043b\u0438 \u0442\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0440\u0430\u0437 \u0432 \u0434\u0435\u0441\u044f\u0442\u044c-\u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434? \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0438\u0437\u043b\u0438\u0448\u043d\u0435. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0443\u0442\u0435\u043c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0444\u0440\u0435\u0439\u043c. <\/p>\n<p>  \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">update: function() {     \/\/ ...     \/\/ Broadcast state     this.connection.broadcastMessage(MessageBuilder.createMessage(MESSAGE_STATE)       .setX(this.player.pos.x * 10)       .setY(this.player.pos.y * 10)       .setVelX((this.player.pos.x - this.player.last.x) * 10)       .setVelY((this.player.pos.y - this.player.last.y) * 10)       .setFrame(this.player.getAnimFrame())       .setAnim(this.player.getAnimId())       .setFlip(this.player.currentAnim.flip.x ? 1 : 0));     \/\/ ...   } <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">onPeerMessage: function(message, user, peer) {   \/\/ ...   switch (message.getType()) {       case MESSAGE_STATE:         this.onPlayerState(remotePlayer, message);         break;        \/\/ ...     }   },      onPlayerState: function(remotePlayer, message) {     remotePlayer.setState(message);   },      \/\/ in RemotePlayer class:   setState: function(state) {       var x = state.getX() \/ 10;       var y = state.getY() \/ 10;       this.dx = state.getVelX() \/ 10;        this.dy = state.getVelY() \/ 10;        this.pos = {         x: x,         y: y       };       this.currentAnim = this.getAnimById(state.getAnim());       this.currentAnim.frame = state.getFrame();       this.currentAnim.flip.x = !!state.getFlip();       this.stateUpdated = true;  } <\/code><\/pre>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0431\u043e \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0447\u043d\u0435\u0448\u044c \u0438\u0433\u0440\u0430\u0442\u044c \u0441 \u043a\u0435\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u043c, \u043a\u0442\u043e \u0441\u0438\u0434\u0438\u0442 \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043e\u043c \u0438 \u043d\u0435 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441 \u0442\u043e\u0431\u043e\u0439 \u0441\u0435\u0442\u0438. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/af3\/6af\/41f\/af36af41f2a548ba9ad601ca0e13b789.gif\"\/><\/p>\n<p>  \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 \u2014 \u0442\u043e\u0439 \u0436\u0435, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c. \u0414\u043e\u0441\u0442\u0438\u0447\u044c \u044d\u0442\u043e\u0433\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0442\u0430\u043a\u043e\u0439 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u0433\u043b\u0430\u0437\u0443 \u044d\u0444\u0444\u0435\u043a\u0442. \u041f\u043e\u0431\u0435\u0434\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/p>\n<h4>\u042d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442<\/h4>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0438\u0434\u0438\u0442 \u0438\u0433\u0440\u043e\u043a. \u0414\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u0438 \u0441 \u0440\u0430\u0432\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c, \u0431\u043b\u0438\u0437\u043a\u0438\u043c \u043a \u0447\u0430\u0441\u0442\u043e\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0438\u0433\u0440\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/168\/624\/109\/1686241090e646d090782ae48e585a14.png\"\/><\/p>\n<p>  \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0447\u0442\u043e \u0438\u043d\u043e\u0435. \u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043d\u0435\u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0441\u043a\u0430\u0447\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/253\/157\/fba\/253157fba877447f9e2842cc7949bc62.png\"\/><\/p>\n<p>  \u041f\u0440\u0438 \u0432\u0437\u0433\u043b\u044f\u0434\u0435 \u043d\u0430 \u0432\u0442\u043e\u0440\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f: \u0438\u0433\u0440\u043e\u043a \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0438\u0434\u0438\u0442 \u0437\u0430\u043c\u0438\u0440\u0430\u043d\u0438\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0440\u0435\u0437\u043a\u0438\u0439 \u0441\u043a\u0430\u0447\u043e\u043a. \u042d\u0442\u043e \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442. <\/p>\n<p>  \u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u043b\u0430\u0432\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u0431\u044b \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u043f\u0443\u0441\u0442\u044c \u0438 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u043d\u043e \u0442\u043e\u0447\u043d\u043e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/ca7\/24a\/997\/ca724a997ff74408883288b6dcacdcdb.png\"\/><\/p>\n<p>  \u0418 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u043e\u0432, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0440\u0435\u0437\u043a\u043e\u0439 \u0441\u043c\u0435\u043d\u044b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0438\u0445, \u0438\u0441\u0445\u043e\u0434\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043a\u0430\u0434\u0440\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u044d\u0442\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0435\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438. \u042f, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0432\u044b\u0431\u0440\u0430\u043b \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e \u0435\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438. \u0418 \u0442\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c \u043a\u0430\u0434\u0440\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442, \u0442\u043e \u043e\u043d\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438\u0433\u0440\u043e\u043a\u0430 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043a\u0430\u0434\u0440\u0435:<\/p>\n<pre><code class=\"javascript\">setState: function(state) { \tvar x = state.getX() \/ 10; \tvar y = state.getY() \/ 10; \tthis.dx = state.getVelX() \/ 10; \tthis.dy = state.getVelY() \/ 10; \tthis.pos = { \t\tx: x, \t\ty: y \t}; \tthis.currentAnim = this.getAnimById(state.getAnim()); \tthis.currentAnim.frame = state.getFrame(); \tthis.currentAnim.flip.x = !!state.getFlip(); \tthis.stateUpdated = true; }, update: function() { \tif (this.stateUpdated) { \t\tthis.stateUpdated = false; \t} else { \t\tthis.pos.x += this.dx; \t\tthis.pos.y += this.dy; \t} \tif( this.currentAnim ) { \t\tthis.currentAnim.update(); \t} } <\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u044d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/cc6\/2bb\/c4a\/cc62bbc4afab4e1092ca71b5b6417abb.gif\"\/><\/p>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u043a\u0443\u0447\u0435\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432, \u0438 \u043d\u0430 \u0441\u043e\u0432\u0441\u0435\u043c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\u0445 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/15a\/afc\/039\/15aafc03940543089da7b17aab8b95b2.gif\"\/><\/p>\n<p>  \u041d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0434\u0430\u043b\u0435\u043a\u043e \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c. <\/p>\n<h4>\u0414\u0440\u0443\u0433\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/h4>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u0430\u0440\u0442\u0435, \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u0442\u0440\u043e\u043d\u043e\u0432 \u0438 \u043a\u043e\u0433\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0437\u0430\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c. \u042f \u044d\u0442\u043e \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u0440\u044f\u0434 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0433\u0440\u043e\u043a \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0432 \u0438\u0433\u0440\u0435, \u0438 \u043e\u043d\u0438 \u0442\u043e\u0436\u0435 \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0442\u0430\u043c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0447\u0435\u043c \u0432 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f: \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0448\u043b\u044e\u0441\u044c \u043d\u0430 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. <\/p>\n<h4>\u0427\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435<\/h4>\n<p>  \u041a\u043e\u0434 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u0441\u0430\u043c\u043e\u0433\u043e ImpactJS) \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/gutnikov\/webrtc-shooter\">\u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<p>  \u0420\u0438\u0441\u043a\u043d\u0443 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0442 \u044d\u0442\u0443 \u0441\u0441\u044b\u043b\u043a\u0443, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/138.68.96.105\">\u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c<\/a>. \u041d\u0435 \u0437\u043d\u0430\u044e, \u0447\u0442\u043e \u0442\u0430\u043c \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441 \u043c\u043e\u0438\u043c single-core \u0434\u0440\u043e\u043f\u043b\u0435\u0442\u043e\u043c, \u043d\u043e \u0431\u0443\u0434\u044c \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 =)<\/p>\n<h4>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a<\/h4>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u2014 \u0441\u043f\u0430\u0441\u0438\u0431\u043e! \u0417\u043d\u0430\u0447\u0438\u0442, \u043c\u043e\u0439 \u0442\u0440\u0443\u0434 \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u043b \u0434\u0430\u0440\u043e\u043c \u0438 \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435. \u0412\u043e\u043f\u0440\u043e\u0441\u044b, \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.<\/p>\n<p>  \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0413\u0443\u0442\u043d\u0438\u043a\u043e\u0432, frontend \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, Badoo.<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:\/\/habrahabr.ru\/post\/315812\/\"> https:\/\/habrahabr.ru\/post\/315812\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u043d\u0435 \u0434\u043e\u0432\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u043c \u0432\u0438\u0434\u0435\u043e\u0447\u0430\u0442\u0430. \u042d\u0442\u043e \u0431\u044b\u043b \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0432\u043e\u0434 \u043f\u043e\u0431\u043b\u0438\u0436\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f\u043c\u0438 WebRTC \u0438 \u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043f\u0440\u043e WebRTC, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044e\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u0443\u0434\u0438\u043e- \u0438 \u0432\u0438\u0434\u0435\u043e\u0441\u0432\u044f\u0437\u0438, \u043d\u043e \u044d\u0442\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439. \u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c peer-to-peer \u0438\u0433\u0440\u0443 \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f. \u0412\u0438\u0434\u0435\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/8f4\/a22\/330\/8f4a223309db459695247a0d44ddb051.png\"\/><\/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-281473","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/281473","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=281473"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/281473\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=281473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=281473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=281473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}