Многопользовательские условия гонки на доске - PullRequest
5 голосов
/ 05 июня 2011

Представьте себе многопользовательскую доску, где несколько человек могут рисовать одновременно.Для простоты, скажем, на доске есть один объект, который может быть перемещен или удален любым пользователем.Не существует понятия о пользовательских объектах (т. Е. Важно, чтобы любому пользователю было разрешено манипулировать любым объектом ... это бесплатная доска для всех)

Моя проблема в этом ... если два пользователяпопробуйте одновременно выполнить другое действие над объектом, то есть один удаляет его, другой перемещает его, что происходит?

Прямо сейчас - просто пропуская сообщения, он выходит из строя.

Одна идея заключалась в том, чтобы иметь серверный элемент управления, который решает, кто имеет контроль над объектом, и ничто не может происходить на стороне клиента, пока этот конфликт не будет разрешен.Разрешение конфликтов может основываться на принципах «первым пришел - первым обслужен».

Несмотря на то, что это может произойти очень быстро, небольшая задержка (~ 50-300 мс) недопустима, поскольку перемещение должно быть мгновенным на стороне клиента,Например, вместо того, чтобы манипулировать объектами, подумайте о ручке.Чтобы была задержка, пока они уже не начали рисовать ... не хорошо!

Другая идея заключалась в том, чтобы иметь кнопку "запрос управления", которая запрашивает расширение на стороне сервера для управления .... та же идеякак и раньше, но теперь они не разочарованы начальной задержкой рисования пером.Это также не очень хорошо, потому что они должны нажимать на эту кнопку, чтобы сделать что-нибудь, и эта доска действительно предназначена для детей ...

Есть ли другие решения?:)

Ответы [ 3 ]

3 голосов
/ 05 июня 2011

Эта интересная проблема обычно решается с помощью комбинации разрешений на стороне клиента и сервера.Если вы знакомы с WoW, особенно в первые дни выпуска, вы помните сбой сервера, и все продолжают двигаться.Это делается клиентом, управляющим предикативными движениями и запрашивающим периодические обновления у сервера для фактических значений местоположения и поведения.

Аналогичная идея должна быть применима к вашей проблеме.Ваше разрешение на стороне сервера на основе fcfs кажется идеальным.Как вы упомянули, проблема заключается в уменьшении времени ожидания пользователя.Чтобы покончить с этим, почему бы не дать пользователю полный контроль на стороне клиента, а затем запросить обновление с сервера после операции?Поэтому, если вы переместите круг на 200 пикселей ниже, а я изменил цвет на зеленый, мы оба увидим мгновенное поведение на стороне клиента, но когда вы отпустите круг, вы также увидите, что он становится зеленым, как было сказано через сервер.1003 *

Очевидная проблема возникает, когда оба пользователя изменяют одни и те же свойства объекта.На этом этапе система fcfs должна будет принять решение относительно того, что делать, основываясь на использовании клиента.Должен ли он выполнять чистую дельту объекта?Стоит ли уведомлять пользователя, что другой пользователь изменил объект другим способом?Это скорее вопрос функциональности, чем технический.

0 голосов
/ 08 июня 2011

Вы могли бы сделать что-то, где вы показываете взаимодействие локальных предметов и то, что когда-либо видит кто-то еще.В начале вы показываете что-то вроде: прозрачный объект, с которым вы взаимодействуете или пишете, не является окончательным, все видят, что непрозрачные объекты / рисунки являются окончательными, и то, что когда-либо видят.

Когда вы обнаруживаете, что 2 пользователя перемещают объект одновременно, на их собственном экране они оба прозрачные, в ходе некоторых многопользовательских обновлений пользователь, который был определен как имеющий контроль, все еще перемещает объект,и вы можете показать какое-то событие (возможно, общий пуф) пользователя, который перемещал свой объект, который теперь был определен как не находящийся под его контролем.

таким образом вы получаете немедленный отклик на рисование и время от времени начинаете немного разочаровываться, когда они решают, что они не контролируют предмет.

0 голосов
/ 05 июня 2011

Действительно интересный вопрос! Состояние доски хранится на сервере (например, в БД). Есть 3 возможных действия на клиенте: startEditing, finishEditing, delete. Сразу после выполнения какого-либо действия вы должны отправить сообщение на сервер с описанием действия.

Если отправлено startEditing, прежде всего вы должны проверить, не заблокирован ли объект, который вы собираетесь редактировать. Если он разблокирован, вы должны поставить блокировку (блокировка должна содержать информацию о пользователе, который поставил блокировку). Затем вы должны отправить сообщение всем активным клиентам, чтобы сказать, что этот объект не должен редактироваться.

Если отправлено finishEditing (это должно содержать информацию об изменениях в объекте), вы должны изменить объект в БД, снять блокировку и отправить сообщение всем активным клиентам, сообщая об изменениях и снявшей блокировку.

Если отправлено delete. Если объект не заблокирован клиентом, отличным от того, который отправил сообщение, вы должны удалить объект из БД и отправить сообщение всем активным клиентам, заказавшим удалить этот объект с доски

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...