Latest posts on Выдача лога на удалённом компьютере через сокеты topichttp://python.su/forum/topic/32450/2017-03-29T15:47:49+03:00Общий :: Network :: Выдача лога на удалённом компьютере через сокеты
2017-03-29T15:47:49+03:00Non_Stop177531Здравствуйте. Столкнулся со следующей задачей: Есть сервер, к которому через вебсокет подключаются клиенты. Один клиент - отдалённый компьютер, который подключается к серверу при открывании HTML файла. Далее код:<br/><br/><br/> HTML файл, который с помощью JS через сокет подключается к серверному и просто выводит каждое полученное от него сообщение. Код:<br/><div class="code"><pre> <span class="cp"><!DOCTYPE html></span>
<span class="p"><</span><span class="nt">html</span><span class="p">></span>
<span class="p"><</span><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">title</span><span class="p">></span>SGW UI<span class="p"></</span><span class="nt">title</span><span class="p">></span>
<span class="p"></</span><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">body</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span><span class="p">></span>
<span class="kd">var</span> <span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s2">"ws://130.83.40.174:5678/"</span><span class="p">),</span>
<span class="nx">messages</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'ul'</span><span class="p">);</span>
<span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">messages</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">'ul'</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span>
<span class="nx">message</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'li'</span><span class="p">),</span>
<span class="nx">content</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createTextNode</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="nx">message</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span>
<span class="nx">messages</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
<span class="p">};</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">messages</span><span class="p">);</span>
<span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"></</span><span class="nt">body</span><span class="p">></span>
<span class="p"></</span><span class="nt">html</span><span class="p">></span>
</pre></div><br/>Остальные клиенты это баш-скрипты, которые так же подключаются к серверу, передают какое то сообщение и отключаются. Эти сообщения сервер собственно и должен передавать первому браузерному клиенту. Проблемы у меня возникли с написанием сервера. Я нашёл <a href="http://websockets.readthedocs.io/en/stable/intro.html">простенькую библиотеку</a> для сокетов. Первая идея была в том, чтобы браузерный клиент подключался первым, его сокетный объект сохранялся и при последующих подключениях клинтов (баш-скрипты) сообщение просто отправлялось сохранённому сокету. <br/><br/>Код сервера:<br/><div class="code"><pre> <span class="ch">#!/usr/bin/python3.4</span>
<span class="kn">import</span> <span class="nn">asyncio</span>
<span class="c1">#!/usr/bin/python3.4</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">websockets</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">browser_client</span> <span class="o">=</span> <span class="bp">None</span>
<span class="nd">@asyncio.coroutine</span>
<span class="k">def</span> <span class="nf">socket_handler</span><span class="p">(</span><span class="n">websocket</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
<span class="k">global</span> <span class="n">browser_client</span>
<span class="k">if</span><span class="p">(</span><span class="n">browser_client</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">):</span>
<span class="n">browser_client</span> <span class="o">=</span> <span class="n">websocket</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">m</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">websocket</span><span class="o">.</span><span class="n">recv</span><span class="p">()</span>
<span class="n">browser_client</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
<span class="n">start_server</span> <span class="o">=</span> <span class="n">websockets</span><span class="o">.</span><span class="n">serve</span><span class="p">(</span><span class="n">socket_handler</span><span class="p">,</span> <span class="s1">'130.83.40.174'</span><span class="p">,</span> <span class="mi">5678</span><span class="p">)</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">start_server</span><span class="p">)</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span><span class="o">.</span><span class="n">run_forever</span><span class="p">()</span>
</pre></div><br/><br/>В итоге это решение не работало, на stackoverflow прочитал, что объекты сокетов сохранять нельзя. Тогда в голову пришёл такой вариант:<br/><div class="code"><pre> <span class="n">browser_client</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">messages</span> <span class="o">=</span> <span class="p">[]</span>
<span class="nd">@asyncio.coroutine</span>
<span class="k">def</span> <span class="nf">socket_handler</span><span class="p">(</span><span class="n">websocket</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
<span class="k">global</span> <span class="n">browser_client</span>
<span class="k">if</span><span class="p">(</span><span class="n">browser_client</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">):</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">if</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">messages</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">):</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">messages</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">yield from</span> <span class="n">websocket</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">m</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">websocket</span><span class="o">.</span><span class="n">recv</span><span class="p">()</span>
<span class="n">messages</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
</pre></div><br/>Но до обслуживания других клентов кроме браузерного не доходило и сервер находился постоянно в while цикле первого клиента, видимо я не до конца понимаю суть @asyncio.coroutine. <br/><br/>Ну и код с которым я имитировал других (баш) клиентов:<br/><br/><div class="code"><pre> <span class="ch">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">websockets</span>
<span class="nd">@asyncio.coroutine</span>
<span class="k">def</span> <span class="nf">hello</span><span class="p">():</span>
<span class="n">websocket</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">websockets</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">u'ws://130.83.40.174:5678'</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="s2">"Test"</span>
<span class="k">yield from</span> <span class="n">websocket</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">yield from</span> <span class="n">websocket</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">hello</span><span class="p">())</span>
</pre></div><br/>В итоге я зашёл в тупик. Был бы признателен, если бы кто нибудь подсказал как можно решить эту задачу именно с сокетами) <br/><br/>П.С. используется версия языка python3.4