Столкнулся со следующей задачей: Есть сервер, к которому через вебсокет подключаются клиенты. Один клиент - отдалённый компьютер, который подключается к серверу при открывании HTML файла. HTML файл, который с помощью JS через сокет подключается к серверному и просто выводит каждое полученное от него сообщение. Код:
<!DOCTYPE html>
<html>
<head>
<title>SGW UI</title>
</head>
<body>
<script>
var ws = new WebSocket("ws://130.83.40.174:5678/"),
messages = document.createElement('ul');
ws.onmessage = function (event) {
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode(event.data);
message.appendChild(content);
messages.appendChild(message);
};
document.body.appendChild(messages);
</script>
</body>
</html>
Остальные клиенты это баш-скрипты, которые так же подключаются к серверу, передают какое то сообщение и отключаются. Эти сообщения сервер собственно и должен передавать первому браузерному клиенту. Проблемы у меня возникли с написанием сервера. Я нашёл простенькую библиотеку для сокетов. Первая идея была в том, чтобы браузерный клиент подключался первым, его сокетный объект сохранялся и при последующих подключениях клинтов (баш-скрипты) сообщение просто отправлялось сохранённому сокету.
Код сервера:
#!/usr/bin/python3.4
import asyncio
#!/usr/bin/python3.4
import datetime
import random
import websockets
import sys
browser_client = None
@asyncio.coroutine
def socket_handler(websocket, path):
global browser_client
if(browser_client is None):
browser_client = websocket
else:
m = yield from websocket.recv()
browser_client.send(m)
start_server = websockets.serve(socket_handler, '130.83.40.174', 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
В итоге это решение не работало, на stackoverflow прочитал, что объекты сокетов сохранять нельзя. Тогда в голову пришёл такой вариант:
browser_client = None
messages = []
@asyncio.coroutine
def socket_handler(websocket, path):
global browser_client
if(browser_client is None):
while True:
if(len(messages) > 0):
msg = messages.pop()
yield from websocket.send(msg)
else:
m = yield from websocket.recv()
messages.append(m)
Но до обслуживания других клентов кроме браузерного не доходило и сервер находился постоянно в while цикле первого клиента, видимо я не до конца понимаю суть @asyncio.coroutine.
Ну и код с которым я имитировал других (баш) клиентов:
#!/usr/bin/env python
import asyncio
import websockets
@asyncio.coroutine
def hello():
websocket = yield from websockets.connect(u'ws://130.83.40.174:5678')
name = "Test"
yield from websocket.send(name)
yield from websocket.close()
asyncio.get_event_loop().run_until_complete(hello())
В итоге я зашёл в тупик. Был бы признателен, если бы кто нибудь подсказал как можно решить эту задачу именно с сокетами)
П.С. используется версия языка python3.4