-
Notifications
You must be signed in to change notification settings - Fork 0
/
readme.html
203 lines (173 loc) · 15.7 KB
/
readme.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Документация по игре «Крестики-нолики»</title>
<style type="text/css">
code {
display: block;
white-space: pre-wrap;
font-family: monospace;
border: 1px #aaa solid;
border-radius: 2px;
background-color: #f0f0f0;
padding: 8px;
}
</style>
</head>
<body>
<h1>Цель</h1>
<p>Написать клиентскую часть приложения «Крестики-нолики» с использованием предоставленного серверного API (<a href="https://ru.wikipedia.org/wiki/API#Web_API">application programming interface</a>)</p>
<p>Клиент должен реализовывать возможности </p>
<ol>
<li>войти в систему</li>
<li>выйти из системы</li>
<li>получить список существующих игр, находящихся в состоянии ожидания старта</li>
<li>создать новую игру с заданными параметрами</li>
<li>подключиться к существующей игре, находящейся в состоянии ожидания старта</li>
<li>делать ход на игровом поле</li>
<li>получать текущий игровой статус</li>
</ol>
<h2>Общие принципы и соглашения</h2>
<p>
Для реализации описанных возможностей следует использовать предоставленные серверные методы.
Методы обладают различными параметрами, описанными ниже, используют разные типы запросов и протоколов.
В случае корректного использования методы возвращают данные, согласно описанной для них документации, иначе возвращают сообщение об ошибке и закрывают соединение.
</p>
<p>
Кодировкой сообщений принимается utf-8.
Формат данных, используемых для взаимодействия — JSON.
Данные следует сериализовать в этот формат при отправке запросов на сервер (HTTP-POST, WebSocket). Получаемые с сервера данные также являются корректным JSON, доступным к десериализации.
</p>
<p>
HTTP-запросы имеют следующий фиксированный формат ответа:
status — может быть успешным (success) или неуспешным (fail)
В случае, если запрос успешен, кроме поля status возвращается объект data, содержимое которого зависит от запроса и документируется ниже.
В случае, если запрос неуспешен, кроме поля status возвращается поле message, содержащее описание причины неудачи в текстовом виде.
</p>
<p>WebSocket-запросы всегда должны обладать полем command, документированным ниже.</p>
<p>Точкой входа является http://welovehtml.ru:3000.</p>
<h2>Протокол взаимодействия</h2>
<p>При открытии страницы пользователь должен иметь возможность просмотреть существующие на сервере игры, находящиеся в ожидании старта, а также возможность войти в систему под некоторыми учетными данными.
Весь игровой функционал должен быть доступен только пользователю, осуществившему вход.</p>
<h3>Вход, сессия и продление сессии</h3>
<p>Для входа в систему пользователь должен указать желаемое имя, под которым он будет известен другим игрокам.
В результате отправки желаемого имени на сервер пользователь получает реальное имя (может отличаться от желаемого), а также уникальный идентификатор пользователя, необходимый при последующем взаимодействии с сервером.
В момент входа пользователя для него создается сессия, в течение которой он имеет право совершать игровые операции. Продолжительность сессии — 3 минуты.
После завершения сессии пользователь принудительно удаляется из системы, все созданные им игры удаляются, а игры, в которых он принимал участие, завершаются с оповещением других игроков.
Пользователь имеет возможность продлить сессию, отправив своё текущее реальное имя и идентификатор, еще на 3 минуты. Количество продлений не ограничено.</p>
<code>URL: /login
Протокол: HTTP
Метод запроса: POST
Данные запроса:
login: желаемое имя
[playerId]: идентификатор, опционально
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.id: идентификатор пользователя
result.data.name: реальное имя пользователя
result.data.loginTimeout: время, через которое сессия будет завершена, в миллисекундах (3 минуты)</code>
<h3>Выход</h3>
<p>Пользователь, обладающий активной игровой сессией, должен иметь возможность её завершить.
В результате завершения сессии все созданные им игры будут удалены, а игры, в которых он принимал участие, будут завершены с оповещением других игроков.
Для завершения игровой сессии следует отправить свой идентификатор.</p>
<code>URL: /logout
Протокол: HTTP
Метод запроса: POST
Данные запроса:
playerId: идентификатор пользователя
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась</code>
<h3>Получение списка игр, находящихся в ожидании старта</h3>
<p>Пользователь должен иметь возможность получать список игр, как обладая активной игровой сессией, так и в её отсутствие.
Пользователь, обладающий активной игровой сессией, не должен получать игр, в которые он уже играет или создал.
Для получения списка игр отправляется запрос без параметров; для получения отфильтрованного списка игр следует передать идентификатор пользователя.</p>
<code>URL: /games
Протокол: HTTP
Метод запроса: GET
Данные запроса:
[playerId]: идентификатор, опционально
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.games: список игр, находящихся в ожидании старта.
Каждая игра обладает следующей информацией (полями):
id: уникальный идентификатор игры
players: список игроков, находящихся в игре
maxPlayersCount: максимальное количество игроков
</code>
<h3>Создание новой игры</h3>
<p>Пользователь с активной игровой сессией имеет право создать новую игру с набором параметров. Параметры определяют размерность игровой доски и количество игроков.
Невозможно создать игру без игровых параметров или с некорректными параметрами. Принимается, что размерность доски может быть от 3 до 9 включительно, а количество игроков может быть от 2х до 4х.
Игра существует до тех пор, пока в ней находится ненулевое количество игроков, а также до тех пор, пока один из игроков не выйдет из игры.
В случае выхода игрока как из игровой сессии, так и из игры, соединение с другими игроками автоматически обрывается.
Предполагается, что игрок, создающий игру, должен присоединиться к ней сразу после создания. Автоматического присоединения не происходит. Игрок должен присоединиться к игре в течение не более 2х секунд после создания, иначе игра будет удалена.
</p>
<code>URL: /create
Протокол: HTTP
Метод запроса: POST
Данные запроса:
playerId: идентификатор пользователя
boardSize: размерность доски
playersCount: количество игроков
Данные ответа:
result.status: success или fail
result.message: сообщение об ошибке, если случилась
result.data.id: уникальный идентификатор игры
</code>
<h3>Присоединение к существующей игре</h3>
<p>Пользователь с активной игровой сессией имеет право присоединиться к существующей игре, если она находится в состоянии ожидания старта.
Формально не запрещено входить в одну игру одним и тем же пользователем дважды, но работоспособность игры при этом не гарантируется, поэтому такого сценария лучше избегать.
Присоединение к игре реализуется инициализацией WebSocket-соединения, которое остается открытым во время всей игры.
Игровой процесс описывается передачей данных по этому соединению и реакцией на них. Данные обязаны содержать имя игровой команды и её параметры.
</p>
<h4>Данные, передаваемые сервером клиенту:</h4>
<h5>Запрос хода</h5>
<p>Сервер уведомляет клиент, что тот имеет право сделать ход, а сервер и остальные игроки будут его ожидать.
Затем сделанный ход должен быть проверен сервером.</p>
<code>URL: /
Протокол: WebSocket
Данные:
command: MAKEMOVE
token: уникальный токен, обеспечивающий безопасность хода (ход может быть свершен не более одного раза)
board: текущее состояние доски в виде двумерного массива
</code>
<h5>Уведомление</h5>
<p>Сервер уведомляет клиент о каком-либо событии, которое клиент обязан показать пользователю</p>
<code>URL: /
Протокол: WebSocket
Данные:
command: NOTIFY
message: произвольная строка
board: текущее состояние доски в виде двумерного массива
</code>
<h4>Данные, передаваемые клиентом серверу:</h4>
<h5>Проверка хода</h5>
<p>После того, как пользователь сделал ход, клиент просит сервер проверить корректность сделанного хода.</p>
<code>URL: /
Протокол: WebSocket
Данные:
command: CHECKMOVE
token: уникальный токен, который до этого был выдан клиенту
x: координаты клетки,
y: в которую ходит пользователь
</code>
<h5>Проверка игрового статуса (опционально)</h5>
<p>Клиент может запрашивать сервер дополнительно о текущем статусе игры
</p>
<code>URL: /
Протокол: WebSocket
Данные:
command: GETSTATUS
</code>
<h3>Завершение существующей игры</h3>
<p>Завершение игрового процесса выполняется закрытием соединения. Соединение может быть закрыто как со стороны сервера, так и со стороны клиента. При закрытии соединения следует использовать и обрабатывать коды завершения соединения:
A CloseEvent is sent to clients using WebSockets when the connection is closed.</p>
<code>1000 — Никто не виноват, закрываем соединение, потому что хотим отключиться (Normal closure; the connection successfully completed whatever purpose for which it was created).
1001 — Сервер решил удалить игру, и дополнительно сообщит причину (The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection).
1003 — Виноват клиент — некорректные параметры запроса (The connection is being terminated because the endpoint received data of a type it cannot accept).
1006 — Соединение оборвалось (кто-то обновил страницу / пропал интернет) (Used to indicate that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected).
</code></body>
</html>