Просмотр полной версии : редактор квестов
Доброе время суток, уважаемые форумчане. решил я тут собрать редактор квестов. при попытке связать область выполнения с менеджером кнопок, возникло пару вопросов(моя память говорит, что где-то я уже видел реализацию всего этого, но из-за разных мыслей не могу придумать толковое описание каждого из вопросов):
1) можно ли повесить внешнего(относительно класса) слушателя событий на изменение переменной без использования EnterFrame?{есть у меня менеджер кнопок, в зависимости от нажатой кнопки на цене выполняется действие. номер нажатой кнопки хранится во внутренней переменной(доступной внешне только для чтения) можно ли отслеживать изменение переменной с главной сцены, не добавляя обработчик EnterFrame?}
2) что менее нагрузит систему: HitTest или слушатель клика мыши?{на сцене, локации отображаются точками. что будет выигрышнее: 1-повесить на всю сцену слушателя клика мыши, и искать локацию, на которую кликнули hitTest ом или же повесить на каждую локацию свой собственный слушатель клика мыши?}
Akopalipsis
20.09.2013, 02:57
Мне кажется, что для отслеживания изменения какой либо переменной есть только два способа - сделать сеттер и при его изменении посылать событие. И ещё есть биндинг http://blog.diestro.ru/binding-v-actionscript-1/
И наверное лучше повесить слушателя на мышь и там проверять target.
Мне кажется, что для отслеживания изменения какой либо переменной есть только два способа - сделать сеттер и при его изменении посылать событие. И ещё есть биндинг http://blog.diestro.ru/binding-v-actionscript-1/
dispatchEvent() уже побывал, у меня почему-то не хочет установить связь между 2 предками одного родителя...
И наверное лучше повесить слушателя на мышь и там проверять target.
спасибо, совсем упустил из вида target(хотя буквально в соседнем классе активно его использую);
появился еще 1 вопрос: возможно ли использовать строку, как строку ввода логических условий?{есть 3 переменные: p1, p2, p3, и 2 строки: в первой строке пользователь задает условие((p1!=p2) and (p1>5)) во второй - действие (p3=p1*p2)}
AlexCooper
20.09.2013, 12:23
появился еще 1 вопрос: возможно ли использовать строку, как строку ввода логических условий?{есть 3 переменные: p1, p2, p3, и 2 строки: в первой строке пользователь задает условие((p1!=p2) and (p1>5)) во второй - действие (p3=p1*p2)}
можно но придется ручками написать парсер таких строк
Для ввода условий можно использовать булевы переменные и даже затолкать их в словарь
Akopalipsis
20.09.2013, 16:28
у меня почему-то не хочет установить связь между 2 предками одного родителя...
А у меня тоже вопрос появился - можно как то событие детьми ловить?
AlexCooper
20.09.2013, 16:45
На счёт событий (http://flashpress.ru/blog/event-part2/)
Добавлено через 1 минуту
скорей всего нужно самому посылать событие ребёнку, либо сделать метод для этого действия, либо подписывать родителя у ребёнка.
Добавлено через 5 минут
если это ДО
import flash.display.Sprite;
import flash.events.Event;
var papa:Sprite = new Sprite();
var child:Sprite = new Sprite();
papa.addChild(child);
papa.addEventListener('event', function(e:Event){ trace('papa')} );
child.addEventListener('event', function(e:Event){ trace('child')} );
child.parent.addEventListener('event', function(e:Event){ trace('papa child')} );
child.dispatchEvent(new Event('event')); // child
papa.dispatchEvent(new Event('event'));
// papa
// papa child
можно но придется ручками написать парсер таких строк
думал что есть что-то встроенное... значит снова будем писать парсер.
AlexCooper
20.09.2013, 19:23
Вот нечего было делать, наваял вам небольшой парсер, работает только с условием AND нет проверок на пробелы, вообще м как, примерно показал.
var fLib:Object = new Object();
fLib['=='] = ravno;
fLib['!='] = neravno;
fLib['>'] = bolshe;
fLib['<'] = menshe;
function bolshe(arg:Array):Boolean {
return arg[0]>arg[1];
}
function menshe(arg:Array):Boolean {
return arg[0]<arg[1];
}
function ravno(arg:Array):Boolean {
return arg[0]==arg[1];
}
function neravno(arg:Array):Boolean {
return arg[0]!=arg[1];
}
var variables:Object = new Object();
variables['p1'] = 1;
variables['p2'] = 2;
variables['p3'] = 2;
var commandLine = '(p1!=p2) AND (p2==p3) AND (p1<2)';
var resultCommand:Boolean = interpretator(commandLine);
trace(resultCommand); // true
function interpretator(line:String):Boolean {
var funcTemp:Array = new Array();
var funcDump:Array;
// разбиваем на логические И
var ifDump:Array = line.split('AND');
var resultDump:Array = new Array();
var result:Array = new Array();
// проходим по логическим составным
for each( var subcommand:String in ifDump) {
// ищем функции
for ( var func:String in fLib) {
// разбиваем на элементы
funcDump = subcommand.split(func);
// если два и более элемента значит нужно выполнить эту логическую функцию
if (funcDump.length>1) {
if (!resultDump[func]) resultDump[func] = new Array();
// парсим переменные
variableParser(funcDump);
// результаты в массив
resultDump[func].push(funcDump);
}
}
}
// выполняем функции
for ( func in resultDump) {
// пока есть элементы
while (resultDump[func].length) {
// выбираем по парам и выполняем соответсвующию функцию
result.push(fLib[func]( resultDump[func].shift() ) );
}
}
// только для условия И ( нужно доработать )
var resultBoolean:Boolean = true;
for each( var resB:Boolean in result ) {
if (resultBoolean) resultBoolean = resB;
}
return resultBoolean;
}
function variableParser(arr:Array):void {
// проходим все пары элементов
for ( var i:uint = 0; i <arr.length ; i++) {
var varIndex:String;
var ind:Number;
if (i%2) {
// если элемент после знака оператора то ищем дугу
ind = String(arr[i]).indexOf(')');
// режем текст до дуги
varIndex = String(arr[i]).substr(0,ind);
} else {
// если элемент перед оператором
ind = String(arr[i]).lastIndexOf('(');
// режем текст с начала строки до дуги
varIndex = String(arr[i]).substr(ind+1,String(arr[i]).length);
}
// находим переменную и переопределяем массив
arr[i] = (variables[varIndex]) ? variables[varIndex] : varIndex;
}
}
MikroAcse
20.09.2013, 21:10
fLib['=='] = ravno;
fLib['!='] = neravno;
fLib['>'] = bolshe;
fLib['<'] = menshe;
Мои глаза!!!
Akopalipsis
20.09.2013, 21:16
Мои глаза!!!
Что с ними?)
MikroAcse
20.09.2013, 22:42
Что с ними?)
Все плохо :)
AlexCooper
20.09.2013, 22:47
Мои глаза!!!
еще чёт наваять?)) сча я мигом)
AlexLucas
20.09.2013, 22:56
Лицо покраснело ?
AlexCooper
20.09.2013, 22:59
Кстати очень интересно посмотреть другие (ваши) реализации, интерпретаторов по данной задаче, весь полезная штука в принципе.
http://www.antlr.org/about.html
http://www.antlr.org/wiki/display/ANTLR3/Antlr3ActionScriptTarget
Akopalipsis
21.09.2013, 00:18
Смог..)
MikroAcse
21.09.2013, 19:50
Лицо покраснело ?
Цвета 0xFF0000
Вот, кстати, делал тут довольно быстрый парсер математических выражений:
https://github.com/MikroAcse/MikroAcse-Library/blob/master/sources/acse/simpleproject/math/MParser.as
Поддержки переменных нету, но есть поддержка функций из класса Math.
Работает с выражениями любой сложности:
12/12/2/2+0.75
12/2+3*2*4+(1+(1+5)/2)
(sin(asin(1))+sin(asin(1)))*2
Думаю, самому написать будет не сложно, нужно только заменить значения стека на значение переменной.
UPD:
Ах, да. Тут не просто математические выражения нужны, тут еще и логические операторы. Тогда MParser не совсем подходит.
mikhailk
22.09.2013, 02:18
Что-то я туплю, наверное, но зачем все эти пляски с бубнами?
Я еще понимаю, в туториале отслеживать, куда пользователь нажал, но в квестах-то зачем?
AlexCooper
22.09.2013, 14:54
Что-то я туплю, наверное, но зачем все эти пляски с бубнами?
Я еще понимаю, в туториале отслеживать, куда пользователь нажал, но в квестах-то зачем?
Дык где Вы увидели что клики отслеживаются? Я так понимаю эт для того что-бы создавать динамически квесты и не компилировать версию.
mikhailk
23.09.2013, 01:08
Из топика автора не совсем ясно, что там за приложение, но в нормальном клиент-серверном приложении квесты никто вроде и не компилирует. О прогрессе выполнения квеста и задач квеста клиента информирует сервер, а тот уже визуализирует информацию от сервера с применением данных модели и статической информации по квесту, которая грузится в ресурсном файле при загрузке приложения.
Интересно, кто-то делает иначе? :)
AlexCooper
23.09.2013, 12:59
Интересно, кто-то делает иначе? :)
Я раньше так делал) Сейчас квесты передаю только в виде брифа, все просчёты ведутся на сервере.
p.s. смотря конечно какие квесты
mikhailk
23.09.2013, 13:32
На самом деле, строго говоря, есть вариант клиент-серверного приложения с постобработкой на сервере (сейчас как раз в таком проекте участвую), в этом случае обработку квестов надо делать дважды - и на клиенте и на сервере.
ЗЫ. Под постобработкой я в данном случае понимаю, что клиент производит изменения на своей модели пользователя, а потом с некоторым интервалом (например, раз в минуту или по достижению определенного количества изменений) пакетом сбрасывает их на сервер, тот прогоняет изменения по своей модели и, если все сошлось, то акцептует их, если не сошлось - отправляет клиента на релоад. Но я, кстати, до сих пор не уверен, что эта архитектура дает какие-то дополнительные бонусы. Кроме снижения нагрузки на БД, естественно.
Тема очень интересная. Может знатоки приведут несколько ссылок для чтения? :)
Вот например, каким образом реализовать текстовое описание квеста? Сам квест, разумно хранить и передавать как id из таблицы всех квестов в игре. Эта таблица только на сервере. Цели и задачи тоже можно использовать как id'ы выполняемых действий, их можно описать на клиенте. Но вот как хранить и передавать текстовое описание, ведь его не передать в виде id, иначе придётся для каждого внесения/редактирования квеста обновлять весь клиент?
AlexCooper
23.09.2013, 19:33
Бриф? А что мешает хранить бриф в базе данных и получать текст в соответствии с Ид?
Tails,
Возможно, большая нагрузка на сервер? Хотя, если предусмотреть возможность разделения сервера на логический и контент хранилище..
Вообщем потому и говорю, что интересно было-бы почитать чего хорошего на эту тему, в ознакомительных целях.
AlexCooper
23.09.2013, 19:46
Дык нам нужна динамичность и гибкость. То-есть текст брифа может изменятся. Соответственно можно реализовать версии. То-есть хранить уже полученные данные ( бриф - хотя сколько там того текста ) локально и сверяться только с версией брифа конкретного квеста. Если версия изменилась, произвести апдейт локальной версии.
А вот это уже хорошая идея :)
mikhailk
23.09.2013, 21:26
Мне все-таки нравится отдавать условно статическую информацию файлом и не дергать базу по такому поводу. Ведем, конечно, в админке, и храним в базе, потом нажимает кнопку "Генерация applicationData" и генерим xml-файл. При загрузке клиента скармливаем ему ссылку на текущую версию applicationData.xml, клиент его прикрасно закачивает, а поскольку меняется applicationData.xml не каждый день, то в итоге он садится в кеш браузера и мы еще и на трафике экономим.
Что касается описания непосредственно квеста, то мы использовали примерно такой формат и было достаточно удобно (на идеальный вариант не претендую):
<quest ID="123" sequenceID="567" numInSequence="2">
<title>Собрать и продать яблоки<title>
<info>Тебе надо собрать 20 зеленых яблок и 10 красных яблок, 10 зеленых потом продать.</info>
<tasks>
<task num="1" type="collect" targetID="456" count="20">
<info>Собери 20 зеленых яблок.</info>
</task>
<task num="2" type="collect" targetID="765" count="10">
<info>Собери 10 красных яблок.</info>
</task>
<task num="3" type="sell" targetID="456" count="10">
<info>Продай 10 зеленых яблок.</info>
</task>
</tasks>
<bonus xp="100" gold="10" />
</quest>
Akopalipsis
23.09.2013, 21:56
то в итоге он садится в кеш браузера и мы еще и на трафике экономим.
Можно чуть-чуть поподробнее.. я некоторое время назад как раз на этом моменте остановился.
Сделал на сервере, чтобы при изменении нужных файлов создавался новый xml с датой изменения..
Тут нужно немного обьяснить - я прочел статью, где говорилось о том же о чем говорите Вы.
Файл с временем последнего изменения и что при загрузке флеш проверяет его и если что, то дакачивает, если время не поменялось, то берет из хеша.. И там говорилось, что этот файл в браузере оседает.
А что нужно сделать, чтобы он там осел? Не чего? Просто загрузить во флешь? Или как?)
MikroAcse
23.09.2013, 22:11
А что нужно сделать, чтобы он там осел?
Загрузить, минуя кэш:
urlLoader.load(new URLRequest("hello.png?" + (new Date()).getTime()));
Загрузить из кэша (только если до этого уже воспроизводилась загрузка файла):
urlLoader.load(new URLRequest("hello.png"));
mikhailk
23.09.2013, 22:39
Ну да. Это собственно не заслуга флеша. Это браузер кэширует. И браузер же проверяет, нужно закачивать файл или отдавать из кэша.
Тема очень интересная. Может знатоки приведут несколько ссылок для чтения? :)
Вот например, каким образом реализовать текстовое описание квеста? Сам квест, разумно хранить и передавать как id из таблицы всех квестов в игре. Эта таблица только на сервере. Цели и задачи тоже можно использовать как id'ы выполняемых действий, их можно описать на клиенте. Но вот как хранить и передавать текстовое описание, ведь его не передать в виде id, иначе придётся для каждого внесения/редактирования квеста обновлять весь клиент?
Храните таблицы (редкоизменяемые части БД) на клиенте. В снапшотах, понятных клиенту (например, amf). При перегенерации серверной таблицы создавайте новый снапшот. Сообщите клиенту, что снапшот изменился, чтобы он мог воспользоваться новым. Это если у вас хорошо спроектированная система. Либо подождите перезагрузки клиента, он сам загрузит новый снапшот базы квестов, если у вас полумеры.
AlexCooper
23.09.2013, 23:25
Мне все-таки нравится отдавать условно статическую информацию файлом и не дергать базу по такому поводу. Ведем, конечно, в админке, и храним в базе, потом нажимает кнопку "Генерация applicationData" и генерим xml-файл. При загрузке клиента скармливаем ему ссылку на текущую версию applicationData.xml, клиент его прикрасно закачивает, а поскольку меняется applicationData.xml не каждый день, то в итоге он садится в кеш браузера и мы еще и на трафике экономим.
Я не использую xml. Он выглядит мне слишком избыточным, использую для передачи данных AMF. А вообще работаю на связке AS3 -> AMF -> AMFPHP -> MongoDB, пихаю целыми объектами из базы в клиент и обратно практически не трансформируя. Плюс AMF работает и на FMS, для меня это как стандарт.
Akopalipsis
23.09.2013, 23:59
AlexCooper а MongoDB это БД которую как и обычную, можно ставить на любой сервер?
mikhailk
24.09.2013, 02:13
MongoDB это БД которую как и обычную, можно ставить на любой сервер?
Монго - чудесная вещь, но надо понимать, что все чудесно, пока она вся сидит в памяти. Как только возникает своп - чудеса заканчиваются. :)
А вообще работаю на связке AS3 -> AMF -> AMFPHP -> MongoDB, пихаю целыми объектами из базы в клиент и обратно практически не трансформируя.
Читеры не беспокоят? Или протокол AMF обеспечивает защиту от подмены данных?
Akopalipsis
24.09.2013, 02:20
mikhailk а что тогда лучше использовать?
mikhailk
24.09.2013, 11:25
Насколько я понимаю, надо идти все-таки от функционала приложения. MongoDB - штука модная и эффективная, но документо-ориентированная. Очень удобно вместо 30-50 таблиц иметь 3-5 коллекций, в которых все это лежит достаточно естественным образом, но некоторые операции становятся сложнее, чем в обычной SQL-базе (например, передача айтема от одного перса другому - тут это корректировка двух профилей персов, а в SQL-базе - изменение значения одного поля в одной строке таблицы, где лежат все айтемы всех персов). И она жрет память, а память - это деньги за хостинг.
Если проект оффлайновый и малобюджетный, то пока еще ничего лучше связки PHP+MySQL+Memcache+Ngnx, на мой взгляд, не придумали. Поднимаем все справочники и классификаторы в мемкеш и работаем с базой только по данным пользователей. Если добавить постобработку, то можем тащить на одном сервере БД совершенно неприличное количество пользователей.
Если проект онлайновый, то мне лично нравится связка Node.js+Mongoose+MongoBD (ну и Ngnx, естественно, если отдаем много контента). Но нужно следить за размером бд и его соответствием ресурсу сервера по оперативной памяти.
AlexCooper
24.09.2013, 13:17
Читеры не беспокоят? Или протокол AMF обеспечивает защиту от подмены данных?
Нет, пока не беспокоят, внесли цифровую подпись, в редких случаях SSL. Да и AMF спасает от "начинающих" хакеров, тот же FireBug при передачи данных будет показывать непонятные иероглифы, что при обычных POST/GET запросах показывает всё в чистом виде.
MongoDB - штука модная и эффективная, но документо-ориентированная Для меня это преимущество нежели недостаток. Структура очень гибкая, не нужно переписывать немереное количество SQL запросов при изменениях базы данных. Нет строгой типизации, два объекта в одной коллекции могут иметь различные типы свойств. На счёт nginx, дык это немного не по-теме)
МemCached активно использую, ему ведь всё равно что у Вас там за БД, SQL или NoSQL. Всё остальное дело "криворукости" разработчиков. Единственным недостатком ООБД это полнотекстовый поиск, да его там "подрихтовали" с выходом 2.4 версии, но всё же без машины индексации в хорошем проекте не обойтись ( к примеру ElasticSearch, проигрывает тому же Sphinx но хоть как-то спасает ситуацию). Если уже описать всю связку для hi-load проектов то у меня она следующая
AS3+SharedObject <-> AMF3 <-> AMFPHP <-> MongoDB ( динамические данные ) <-> MySQL ( статика + текста + логи ) <-> MemCached <-> Sphinx/ElasticSearch <-> Gearman ( async task ), когда еще в связку добавляю P2P с FMS. Ну и естественно без аппаратной части не обойтись, а это и SSD HDD и Nginx и правка всех конфигов сервера с репликацией и шардированием.
За Node.js слышал не раз, но как-то все обхожусь тем что знаю и умею. Но эт hi-load, а до таких проектов в основном рядовому разработчику далеко.
Потому моя рекомендация эт AS3 <-> AMF <-> MongoDB, MySQL использовать в крайне редких случаях. Лично в ней я храню первоначальные данные, кто когда зарегистрировался, текста и логи ( вся работа с MySQL выполняется асинхронно )
Добавлено через 9 минут
Что может быть проще, я даже представить себе не могу, писал в браузере на скорую руку, для демонстрации возможностей AMF c MongoDB
var sendOBJ:Object = new Object();
sendOBJ.number = 123;
sendOBJ.string = 'string';
sendOBJ.array = new Array();
sendOBJ.array.push(new Array());
sendOBJ.object = new Object();
sendOBJ.object.boolean = true;
sendOBJ.bitmap = new Bitmap();
AMF.call('Class/method', callbackFunc, sendOBJ);
class Class {
public function method($data) {
$m = new mongo();
$db = $m->selectCollection;
$db->insert($data);
return $data;
}
}
и всё, "сложный" объект на сервере в базе данных, который можно в любой момент таким же и получить обратно
Что-то я туплю, наверное, но зачем все эти пляски с бубнами?
Я еще понимаю, в туториале отслеживать, куда пользователь нажал, но в квестах-то зачем?
я делаю редактор текстовых квестов... далее квест сохраняется в XML... и для того чтобы сделать вывод переменных приятный для глаза, делаю парсер{решил Редактор вывести время(и например ограничить игру по нему). Чтобы не перекомпилировать полностью приложение, он, в строке формата вывода первой переменной пишет строчку: "Время: {p1 div 60} час. {p1 mod 60} мин."}
mikhailk
24.09.2013, 15:35
и всё, "сложный" объект на сервере в базе данных, который можно в любой момент таким же и получить обратно
Я про это и говорю.
Есть программы вот этого класса: http://vk.com/cheatengine
Они позволяют менять данные в мозгах клиента. Если клиент все, что хочет, пишет в базу, а сервер доверяет всему, что от него приходит, то что мне помешает накрутить себе голды и экспириенса?
За Node.js слышал не раз, но как-то все обхожусь тем что знаю и умею
Это чисто для онлайна. Как альтернатива эрлангу, джаве и прочему, на чем можно собрать сокет-сервер.
Чтобы не перекомпилировать полностью приложение
Чтобы не перекомпилировать полностью приложение, надо, чтобы данные по квестам подкачивались клиентом при загрузке, либо в составе общего ресурсного файла, либо отдельным файлом.
Akopalipsis
24.09.2013, 15:54
mikhailk если MongoDB не настолько надежна, то что используете Вы?
mikhailk
24.09.2013, 16:06
Дело не в MongoDB, а в том, где реализована логика приложения.
Если логика целиком реализована в клиенте, то возникают пляски с бубнами, как защититься от взлома. Если логика целиком реализована на сервере, то этих проблем нет. Ну нравится читеру дергать сервер не через клиент, а напрямую - флаг ему в руки. Куллдаун-то один на всех. Что через клиент, что так...
А непосредственно от самой MongoBD я, кстати, в восторге. :)
Вот только совместное использование мемкеша и монгодб у меня как-то слабо в мозгах стыкуется. Это примерно как использовать два мемкеша вместо одного. Впрочем, возможно, из PHP доступ к данным мемкеша быстрее, чем доступ к данным монгодб.
Akopalipsis
24.09.2013, 16:29
А непосредственно от самой MongoBD я, кстати, в восторге.
Спасибо! Теперь я её точно попробую.
Вот только совместное использование мемкеша и монгодб у меня как-то слабо в мозгах стыкуется.
А вот тут мне тяжело понять о чем Вы, но скорее всего пойму, когда вернусь к изучению php.
mikhailk
24.09.2013, 18:06
Мемкеш - это хранилище в оперативной памяти по приниципу ключ-значение. Практически мгновенная скорость доступа к данным без гарантии сохранности данных. Очень удобно для построения кэша приложения, при этом основным хранилищем данных остается SQL-база, MySQL, например.
МонгоДБ - тоже сидит в оперативной памяти, скорость доступа там тоже очень неплохая и поэтому ее можно использовать и как хранилище данных и как кэш приложения. Два в одном флаконе. Плюс там есть специализированные механизмы под хайлоад.
Akopalipsis
24.09.2013, 18:57
Мемкеш - это хранилище в оперативной памяти по приниципу ключ-значение.
mikhailk Спасибо! То есть, если я правильно понял, мемкеш сидит в браузере и когда пользователь конектится к серверу, то сервер проверяет запрошенную пользователем информацию в хеш-таблице. И если пользовательский запрос ( или какая то часть ) есть в этой таблице, то сервер не лезет в БД, а отдаёт её из хеша?
То есть, вот зашёл я в эту тему и в первые вижу Ваше сообщение, которое сервер отдал из БД. А вот аватарку Вашу, сервер проверил на наличии её в хеш таблицы и найдя её там, он не лезет за ней в БД а отдаёт из хеша браузера?
mikhailk
24.09.2013, 22:32
То есть, если я правильно понял
Нет, Memcache - это сервис на стороне сервера.
Вот про Memcahed (примерно то же самое):
http://ru.wikipedia.org/wiki/Memcached
Вот тут сравнение:
http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B-%D0%B4%D0%BB%D1%8F-php/
Я лично использую Memcache.
AlexCooper
27.09.2013, 16:52
Они позволяют менять данные в мозгах клиента. Если клиент все, что хочет, пишет в базу, а сервер доверяет всему, что от него приходит, то что мне помешает накрутить себе голды и экспириенса?
Нет, что Вы, в боевой версии реализовано уйма проверок, клиенту вообще никогда верить нельзя. Пример я показал самый простой чтобы ознакомить людей с тем на сколько просто работать с МонгоДБ, а точнее как просто передавать и сохранять в бд различного типа свойств. Я не агитирую всех переходить на Монго, у неё есть свои минуса и плюса, как в прочем и в любой другой технологии. Но для использования с Флеш она мне больше всего годится.
Вот только совместное использование мемкеша и монгодб у меня как-то слабо в мозгах стыкуется. Это примерно как использовать два мемкеша вместо одного. Впрочем, возможно, из PHP доступ к данным мемкеша быстрее, чем доступ к данным монгодб.
Совместное использование нужно только в тех случая когда есть сложная выборка данных. К примеру из БД, где 100 тысяч игроков, нужно выбрать топ-100 игроков за прошлую неделю по различным версиям, эта информация обновляется один раз соответственно, постоянно нагружать БД не имеет смысла, делает выборку из БД один раз и записываем в мемкеш, все последующие выборки топ-100 уже берутся с пулов в мемкеше.
Нет, Memcache - это сервис на стороне сервера.
Вот про Memcahed (примерно то же самое):
Важным нужно сказать то что сам сервис именуется как Memcahed, приставка D - означает Deamon, тоесть работа в фоновом режиме. А Memcache и Memcahed это всего лишь расширения к примеру php для работы с сервисом Memcahed. Причем первый имеет не все реализации из полных возможностей Memcahed.
Добавлено через 30 минут
Для сравнения список функций Memcached (http://php.net/manual/en/book.memcached.php) и Memcache (http://php.net/manual/en/book.memcache.php)
mikhailk
27.09.2013, 17:59
Совместное использование нужно только в тех случая когда есть сложная выборка данных. К примеру из БД, где 100 тысяч игроков, нужно выбрать топ-100 игроков за прошлую неделю по различным версиям, эта информация обновляется один раз соответственно, постоянно нагружать БД не имеет смысла, делает выборку из БД один раз и записываем в мемкеш, все последующие выборки топ-100 уже берутся с пулов в мемкеше.
Я об этом и говорю.
Вы сделали на мемкеше кэш приложения. Применительно к приложению на том же PHP/MySQL - это классическое решение. Пользовательские процессы живут доли секунды, мемкеш обеспечивает общую, доступную для всех область данных с практически моментальным доступом.
Но когда Вы юзаете монго, Вы УЖЕ имеете средство для построения кэша приложения. Иначе говоря, сформировав топ-100 из данных, Вы просто пишете это документом в коллекцию top100 и никакие мемкешы дополнительно не нужны. Вы ничего существенно не выигрываете. Ну, разве что имеет место совершенно нереальный хайлоад. Но если так, то все равно шардинг и все дела.
Нет, что Вы, в боевой версии реализовано уйма проверок, клиенту вообще никогда верить нельзя. Пример я показал самый простой чтобы ознакомить людей с тем на сколько просто работать с МонгоДБ, а точнее как просто передавать и сохранять в бд различного типа свойств.
Главное, чтобы люди, ознакомившись с такой простотой, не пошли клепать свои приложения один в один. :) Я тут как раз недавно чинил приложение, в котором вся логика приложения сидит в клиенте, клиент все считает сам и пишет профиль прямо в базу. Видимо, разработчики планировали сделать "проверки", но руки не дошли. В итоге через чарли вообще можно было писать в базу кому угодно и что угодно.
Не, не знаю. Логика приложения должна быть на стороне сервера. Впрочем, это совсем не для данной темы.
Akopalipsis
27.09.2013, 21:42
AlexCooper , mikhailk в скором времени я буду вынужден соприкоснуться с Вашими советами, но как уже сейчас понял - разбираться придётся очень долго.
Статьи если и есть, то они как всегда минимальные. По этому, остается только попросить, знаете ли Вы какие то ссылки, которые возможно не так просто найти, но они очень информативные? Очень интересно, как защитить БДМонго...
mikhailk
28.09.2013, 00:40
:)
От чего Вы собрались ее защищать? Монго тут вообще ни при чем.
Если логика приложения реализована на стороне сервера, то нужно защищаться от неверных данных в запросах, идущих со стороны клиента, чтобы сервер корректно отрабатывал и правильно писал в бд. А что там с клиентом происходит - не суть важно.
Если логика приложения реализована внутри клиента, то дополнительно к тому, что сказано выше, надо защищаться еще от взлома самого клиента (чтобы читеры не могли менять данные внутри клиента).
Логика приложения должна быть реализована на стороне сервера. Это необходимое и достаточное условие существование приложения, даже без клиентов.
AlexCooper
28.09.2013, 17:10
Логика 100% должна быть на сервере. Единственными исключениями являются не значимые данные и разделённая логика.
не значимые данные - к примеру тренировочный бой, изменения этих данных ни коем образом не даст изменений на сервере.
Разделённая логика ( как я её называю ) - это дублирование логического модуля на клиенте. Основной логически модуль лежит на сервере, на клиенте происходит предпоказ, в большинстве случаев это используется в риалтайм играх или же пошаговых стратегиях. Где клиентский логический модуль осуществляет операции до синхронизации с сервером, а во время синхронизации проверяется идентичность поведения и при их разбежности можно считать что клиент взломан.
Вы ничего существенно не выигрываете. Ну, разве что имеет место совершенно нереальный хайлоад. Но если так, то все равно шардинг и все дела.
Я использую технологии по их прямому назначению. MemCache - инструмент кеширования, соответственно MongoDB - это база данных. Разница как минимум в том, что при аварийном сбое первый утратит все свои данные, так как они хранятся только в оперативной памяти, MongoDB же хранит свою базу физически.
На счёт топ-100 это был пример, но и объясню свое мнение, почему всё же лучше использовать MemCache, нежели создавать отдельную коллекцию.
Во-первых нет переизбытка информации, я считаю, если одни и те же данные хранить в базе данных несколько раз, это является переизбытком, если в результатах хранить только ид пользователя, а при выборе данных топ-100 юзать основную коллекцию за полной информацией, как-то вовсе не хай-лоад.
Во-вторых не забываем что какая-б база данных не была крутой, лучше когда идет меньше обращений к ней, а в случае с хай-ло там и так достаточно операций записи/чтения и если мы максимально перенесём операции на другие не менее продуктивные технологии, от этого мы только выиграем. так же не забываем что у монго есть свое ядро которое тоже может словить оверлоад.
Ну а в третьих за чем мне еще создавать в кроне задачу или писать еще какой-нить логический блок для "затирания" результатов поза прошлой недели, если в Мемкеше я укажу срок хранения данных неделя и всё произойдет автоматически. Ведь пример с ТОР-100 был всего лишь примером, а если у нас более крупная система, где имеется различное количество вариантов выборок, и все результаты пихать в монго как отдельная коллекция, а потом же их затирать считаю не очень хорошим решением. Но это лишь моё мнение, на роль супер-героя по хайлоад системам я не претендую, но в моем уме не возникает коллапса когда разработчики используют базу данных для хранения данных, а сервис кеширования для хранения промежуточных результатов сложных выборок из баз данных.
mikhailk
28.09.2013, 20:02
Логика 100% должна быть на сервере. Единственными исключениями являются не значимые данные и разделённая логика.
Кто-то несколько выше предлагал писать игровые объекты из клиента напрямую в БД.
Во-первых нет переизбытка информации, я считаю, если одни и те же данные хранить в базе данных несколько раз, это является переизбытком,
Поправьте меня, если ошибаюсь - Вы храните в монговских коллекциях данные в третьей нормальной форме?
Ну а в третьих за чем мне еще создавать в кроне задачу или писать еще какой-нить логический блок для "затирания" результатов поза прошлой недели, если в Мемкеше я укажу срок хранения данных неделя и всё произойдет автоматически.
Я об этом и говорю. Вы используете MongoDB как MySQL. Подозреваю, если Вы замените MongoDB на ORM+MySQL, то ничего не потеряете в функциональности, зато приобретете в стабильности, компактности и еще какие-никакие бонусы по мелочам.
Не надо крона, читаем про т.н. ограниченные коллекции:
http://docs.mongodb.org/manual/core/capped-collections/
А что касается "укажу мемкешу хранить неделю" - то это уж мемкеш решит, сколько он будет хранить. :)
AlexCooper
28.09.2013, 20:43
Кто-то несколько выше предлагал писать игровые объекты из клиента напрямую в БД.
Я ничего не предлагал. Я показывал на сколько просто передавать объекты через AMF в объектно-ориентированную базу данных.
Поправьте меня, если ошибаюсь - Вы храните в монговских коллекциях данные в третьей нормальной форме?
В зависимости от ситуации. Но примерно так.
30031
Соответственно иногда данные всё же дублируются, но не все, а лишь те которые в зависимости от задачи нужно получать сразу же, во избежания выборок из других коллекций.
А что касается "укажу мемкешу хранить неделю" - то это уж мемкеш решит, сколько он будет хранить. :) эт верно, но мемкеш начинает удалять только при "перегрузке" и то с самых древних не используемых пулов и это логично.
Предлагаю закрыть дискуссию, так как она уже давно отошла от темы ТС.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.