Найти - Пользователи
Полная версия: Архитектура websocket-приложения
Начало » Network » Архитектура websocket-приложения
1
Hyyudu
Добрый день, уважаемые форумчане!
Решил создать веб-приложение: клиент на JS, сервер на Python, обмен данными через websockets. Приложение - наподобие карточной игры: в одной партии конечное число участников (до 5), количество одновременно играемых партий на сервере ограничено только мощностью (по факту вряд ли больше 10 одновременно будет), одна партия конечной продолжительности. Клиенты внутри одной партии должны иметь доступ к одному и тому же набору данных, наборы данных в двух разных партиях никак не связаны между собой.
Как бы вы посоветовали строить схему взаимодействия “клиент-сервер” в такой системе? Обязательно ли для каждого подключившегося клиента делать threading.Thread(…).start(), или можно как-то обойтись одним главным потоком, получать данные параллельно со всех подключенных клиентов и обрабатывать их? Сервер сам по себе не генерирует никаких событий, а выдает некий объем информации всем участникам партии только в ответ на пришедший с одного из клиентов запрос.
Hyyudu
За ссылки спасибо, но хочется сначала самому попробовать на вкус всю эту низкоуровневую кухню, а потом уже пробовать 100500 фреймворков.
Hyyudu
Первые шаги сделаны, все-таки решил обойтись без Tornado и Flask (тем более, что у меня все равно стоит Apache, и Питон работает под ним же). Написан клиент, написан (в самом базовом виде) сервер: в бесконечном цикле делается socket.accept() и для каждого нового клиента запускается thread, в котором крутится следующая функция:
def userloop(conn, addr):
	data = conn.recv(1024);
	if len(data) ==0:
		return;
	conn.send(create_handshake(data))
	print "Handshake with",addr[1],'ok!'
	while 1:
		data = conn.recv(1024);
		if len(data)>2:
			msg = unpack_frame(data)['payload'];
		else:
			msg = '';
		if (msg== ''):
			print addr[1],' disconnected!'
			break;
		else:
			 process_msg(msg, conn, addr)
Клиенты подключаются, отправляют сообщения, получают на них ответы, все прекрасно. Проблема теперь состоит в следующем: если клиент со своей стороны посылает socket.close(), то корректно завершается его собственный thread, не трогая все остальные. Но если в браузере закрыть вкладку или обновить страницу, то сначала от этого клиента приходит кусок данных, начинающийся с байтов 136,130, а потом всем клиентам приходит сообщение от сервера, что они отсоединены, а на сервер от всех клиентов начинают бесконечным потоком идти пустые блоки данных (в моем случае этот бесконечный поток сразу обрывается, поскольку отрабатывает секция print addr,' disconnected!'; break
Кто знает, как корректно обработать на сервере ситуацию, когда на клиенте происходит перезагрузка или закрытие страницы?
Hyyudu
Спасение оказалось в паре строк на стороне клиента:
window.onbeforeunload = function() {
socket.close();
}
o7412369815963
Hyyudu
Обязательно ли для каждого подключившегося клиента делать threading.Thread(…).start(), или можно как-то обойтись одним главным потоком, получать данные параллельно со всех подключенных клиентов и обрабатывать их?
Можно, для этого есть асинхронные фреймворки, (один поток и куча висящих клиентов).
Пример asyncio (стандартный модуль из py3.4) + websockets, для каждого клиента будет запущен свой “message”, для этого не нужен свой велосипед.
import asyncio
import websockets
 
@asyncio.coroutine
def message(websocket, path):
    while True:
        data = yield from websocket.recv()
        yield from websocket.send(data)
 
start_server = websockets.serve(message, 'localhost', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Hyyudu
Спасибо!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB