Эта тема на forum.dklab.ru


RGoblin: Создание чата
Здравствуйте.
Необходим чат с минимальным количеством примочек, а именно: смайлы, приват, список юзверей. Больше ничего не нужно (необходимо максимальное быстродействие при работе с большим количеством пользователей). Причем все пространство должно делиться на "комнаты".

Что лучше использовать в данном случае: текстовые файлы или mysql - что быстрее? как сделать приват (хотябы общая идея без кода)?
Ближайшая аналогия необходимого чата - чат Бойцовского Клуба (если кто знает что это такое).


Может уже где-то валяется легкая болванка? как она называется , если существует?


Спасибо.
странник:
http://php.spb.ru/chat/
http://www.softlinks.ru/scripts/f682.php
странник:
разбери чат по последний ссылке, когда то dushik писал его как учебное пособие
RGoblin:
к сожалению последний чат уже гикнулся - не скачивается. "проект закрыт"

а первого у меня уже есть исходники, но еего минус, что он очень жирный - один архив только весит 1,21 мешка...
chin:
В принцыпе, тут сложновато вот так сесть и рассказать. Во всяком случае могу сказать, что лучше, естественно, MySQL + php + javascript. MySQL - понятно что делает, php - берет информацию из БД, обрабатывает, выдает javascript. Сам же javascript - выводит информацию пользователю, посылает запрос серверу с некоторой периодичностью для обновления фрейма или отправки сообщения пользователю. Сами понимаете, это только теория. Если она Вам чем-то поможет..

Хотите писать игру на подобии БК? Мой совет, как человека, съевшего на этом собаку: рулите Flash. Если напишите такое на Flash, спроса нынче будет больше. Там даже технология проще, если разобраться и не лениться.

RGoblin:
chin, к сожалению flash жрет много траффика. а для того чтобы этого не было - необходимо еще и клиент клепать. да и насмотрелся я на Time Zero и Destiny Sphere - они очень ограничены в плане сюжета, флеш не позволит нормально создать атмосферу ролевки, которую может позволить чистый текст.

еще возникли вопросы:
1) в каком виде хранить долгосрочные приваты? (если mysql, то понятно, что поле varchar или char, но сколько таких полей или как разделять одно поле? спецсимволами?)

2) где вообще хранить эти самые приваты?
обычный чат как я понимаю в отдельной таблице (ктати, что и сколько в ней должно быть?), а приваты куда пихать? в таблицу данных юзверя или лучше отдельную таблицу завести, например, user_privat с двумя полями на запись: user_id (повязанная с таблой данных пользователя) и приват этого юзера в данной комнате? или еще какой-то вариант есть получше?
chin:
Если Вам не сложно подождать, я завтра раскопаю свой чатик, который когда-то делал. Сегодня уже сил нет. А вот завтра все распишу как надо, что и куда. Сорс давать не буду - он прикреплен к сайту, выдерать его будет сложно.... да Вы и не поймете там ничего (:
А вот обьяснить что и куда я смогу. Завтра ^_^
RGoblin:
Спасибо огромное!! :)
ToxaP:
RGoblin

Ты скажи, что именно тебе нужно?
Тока теорию чата, или как розрулить все (комнаты, и т.д.)!
RGoblin:
как минимум теорию, а как максимум - разрулить как :)
но вроде общие черты догнал самостоятельно, теперь вот думаю как и где хранить в мускуле приваты...

да, и кто-нибудь знает как явой дописывать сообщения в окно чата, без скачивания всего содержимого (особенно, если там пара сотен строк)? Иначе сервак и линии удавятся...
Юрий Насретдинов:
RGoblin
см. JsHttpRequest
ToxaP:
RGoblin

По технологии БК есть 5 фреймов:

Первый фрейм (верхний) он независимый, и c делан для игрового процесса!
Второй фрейм (главное окно чата) в нём отображаются сообщения!
Третий фрейм (кто в онлайн) в нём кто в твоей комнате!
Четвёртый фрейм (отправка сообщений) там пишут само сообщение и настройка обновления и т.п.!
Пятый фрейм (рабочий) этот фрейм нигде не отображаются, и отвечает за отправку сообщений и приём!
Кажись с фреймами закончили :-)

Дальше работает JavaScript!
Технология такая, раз в 15 секунд (это время выбирает сам юзер, я, например, делал 15,30,45,60 секунд) рабочий фрейм идёт на скрипт и забирает сообщение!
Когда ты отписал сообщение опять же рабочий фрейм идёт на скрипт и отдаёт скрипту сообщение, и сразу же этот скрипт отдаёт ему новые сообщения плюс ту, что он написал!
Кажись с теорией тоже разобрались :-)


Поля в базе я делал такие:

1)message_id – уникальное id сообщения
2)time – время когда написали сообщение
3)message – само сообщение
4)status – три вида сообщения public, private, to

public – это простое сообщение написанное юзером
private – это сообщение написанное юзером юзеру
to – это обычное сообщение написанное юзером юзеру

Я также делал еще и admin_message, bot_message и т.д. на всю фантазию :-)

5)author – кто написал сообщение
6)sender – кому написали сообщение
7)room – в какой комнате будет отображаться сообщение
8)color – цвет которым будет отображаться сообщение

С базой тоже кажись покончено!

Кажись самое главное всё рассказал!
Если чёт не понятно спрашуй :- )
chin:
Блин, Тоха, ну ты и шустрый! (:
У меня вот инета не было два дня, вот и не смог написать...
RGoblin
Короче, мы вот с ToxaP как-то делали что-то подобное тому, что хотите сделать Вы. Технология вот такая, как он обьяснил. Если бы у меня не было напрягов, я бы написал примерно то же самое.
Вот только хотел подчеркнуть один нюанс: если хотите делать долгосрочные приваты, делайте на них отдельную таблицу в базе (Кто,Кому,Мессаг,Время, ...). А осуществляться он может примерно так: пользователь отправляет сообщение, если того кому он его отправляет нету, значит сообщение сохраняется в таблицу приватов и ждет своего получаемого. Когда каждый пользователь входит в систему, скрипт проверяет, нет ли для него там привата. Если есть - выводит в чат окно и удаляет из базы, как прочитанное.

Технология такова: в базе хранятся сообщения максимум последних 10 минут. Все сообщения, старее 10 минут удаляются. Все что надо висит уже у пользователя в фрейме - этих сообщений может уже и не быть в базе.
А вот когда пользователь только заходит в чат, ему в фрейм прогружаются сообщения за последние 10 минут.
RGoblin:
гы! пасиб! :)
хотя к этому моменту с чатом БК (клиентской частью) уже разобрался :)

и вот кстати, там полученная информация из БД приходит единым текстом. а потом уже форматируются явой и выпихиваются в поле чата.

может стоит не делать в мускуле поля message_id, status, author, sender, room? Не вижу особого смысла...
оставить только время юниксное и тело сообщения, в котором будет написан автор, статус (private или to), тот, кому написали сообщение. каждая комната чата вообще в отдельной таблице (чтобы меньше запрос был).
запросом выдираются все сообщения после запроса, сцепляются в единый текст и отправлятся броузеру...
Но встает вопрос безопасности: можно ли перехватить из полученного текста чужие приваты, пусть даже это рабочее окно имеет нулевой размер?

И выдержит ли такой чат нагрузку в 500 человек в разных комнатах? или придется переходитьвсе-таки на работу с серверным даемоном как у CHAT.PHP.SPB.RU?
RGoblin:
первый вопрос предыдущего поста отпал. второй остался в силе.

и возник еще вопрос:
есть MyISAM таблица в мускуле:
message_id int(11) auto_increment
login varchar(15)
unix_time int(11)
message tinytext

при отправке в нее запроса типа:
INSERT INTO chat SET login='rgoblin', unix_time=1117501282, message=12345678901234567890
получаем в поле message вот что: -6101065172474983726
почему текстовое поле воспринимает запрос как число?? и как этого избежать?
функция sql_placeholder ( (с) Дмитрий Котеров ) не помогает (да и не должна)...
chin:
INSERT INTO `chat` (`login`,`unix_time`,`message`) VALUES ('rgoblin',1117501282,'12345678901234567890')
message в кавычки взять слабо?
RGoblin:
ээээээээ.... ой... :)

спасиб :)
ToxaP:
А также, поле с unix_time должно быть 10 значним, а не 11 значным! Поле с message я думаю не должно быть больше 255 символов!
Тобиш, должно быть так :

unix_time int(10)
message varchar(255)
RGoblin:
мммм...
ну поля unix_time - это простой int без заморочек.
да и tinytext ограничен 255 буквами.
chin:
RGoblin
А разницу знаете между tinytext и varchar?
RGoblin:
если не ошибаюсь: из varchar вырезаются концевые пробелы, а из tinytext - нет. Результатом этого идет: меньший объем данных и более низкая скорость обработки данных у varchar, в отличие от tinytext.
C учетом того, что чат самоочищается - размер не имеет значения.
ToxaP:
RGoblin
Ты прав на все 100%!

chin
А я тебе пытался доказать что размер не имеет значения!
chin:
ToxaP
Ну в этом случае мы же не спорили на ряжанку! (:
В принцыпе, да. Я считаю, что тут разницы большой нету. Учитавая вот это:
что чат самоочищается - размер не имеет значения.
ToxaP:
chin

Хе! Зря, что не поспорили!

Ну, а если уже по делу, то понятно, что должен работать скриптик очистки на кроне!
RGoblin:
очистка бд чата работает через пользователей отправляющих сообщения. в среднем каждое 100 сообщение должно очищать бд.

а вот на кроне надо сделать отслеживание онлайна пользователей. если не было действий в течение минуты (типа автообновления чата или списка пользователей) выгонять из списка актива.
Дамир Хуснатдинов:
если не ошибаюсь: из varchar вырезаются концевые пробелы, а из tinytext - нет. Результатом этого идет: меньший объем данных и более низкая скорость обработки данных у varchar, в отличие от tinytext.
C учетом того, что чат самоочищается - размер не имеет значения.

Ой ли? Насколько я помню концевыми пробелами дополняются только CHAR'ы. А VARCHAR от TINYTEXT'а отличается тем что можно максимальную длину указать.
Юрий Насретдинов:
Дамир Хуснатдинов
Концевые пробелы вырезаются как из CHAR так и из VARCHAR, читайте документацию
RGoblin:
Вот Вам выдержка из книги "MYSQL. Учебное пособие. - Люк Веллинг, Лара Томпсон.":

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

Может Вы это и имели ввиду, но речь здесь идет скорее о хранении данных в БД, а не в том, что извлекается из нее.

итого:
VARCHAR - длина задается, концевые пробелы не хранятся.
CHAR - длина задается, концевые пробелы хранятся.
TINYTEXT - длина не задается, концевые пробелы хранятся.
ToxaP:
очистка бд чата работает через пользователей отправляющих сообщения. в среднем каждое 100 сообщение должно очищать бд.

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

Как я делал, я думаю, делал я правильно, на кроне вешал один скрипт. Который делал всю грязную роботу:
1) Проверка кто в онлайн
2) Очистка в базе от лишнего мусора (чат, регистрация и т.к.)

А кто в онлайне я б посоветовал бы делать раз в 3 минуты! И сделать таймер на JavaScript
Который будет проверять последнюю передачу данных на сервер, и если её уже нету в течение 2 минут и 30 секунд чтобы сам автоматом перегружал игровой фрейм!
Юрий Насретдинов:
концевые пробелы хранятся
Они конечно хранятся, но при этом при получении результата они убираются.
RGoblin:
ToxaP
Да, у меня нечто похожее.
az:

А кто в онлайне я б посоветовал бы делать раз в 3 минуты! И сделать таймер на JavaScript
Который будет проверять последнюю передачу данных на сервер, и если её уже нету в течение 2 минут и 30 секунд чтобы сам автоматом перегружал игровой фрейм!

Лучше не перезагружать игровой фрейм, а в какое-нибудь служебное окно загружать скрипт наподобие "update_status.php". Во-первых - в случае, если данные не изменились мы не получаем лишний трафик, а во-вторых и серверу так проще :)
RGoblin:
Конечно, так и сделано с использованием служебного окна. :)
Обновление через Ява-скрипт делается... все как надо, для снижения траффика.
netghost:
RGoblin
Здравствуйте! Можно пару вопросов по вашему чату? :
1.) Какими правами обладают участники чата как пользователи базы данных MySQL? Я сначала хотел создавать отдельного пользователя для каждого участника
GRANT INSERT(`mes_txt`) ON `chat` . `mes_table` TO '.$login.'"@"%"IDENTIFIED BY "'.$pass.'"
где
mes_txt - поле сообщений, куда данному пользователю разрешён доступ
mes_table - соответственно таблица, где содержится полу mes_txt
chat- база данных, где расположена таблица mes_table
$login и $pass - логин и пароль введенный участником при регситрации
Но потом решил создать одного пользователя, через которого будет осуществлен доступ к базе. Правильно ли это? И вообще насколько безопасным это будет для базы?
2.) Хотя это к PHP не относится, вы не могли бы подсказать, как оформить скрипт для ДОБАВЛЕНИЯ сообщения в фрейм, а не для его обновления. Я знаю, что там используется "нулевой" фрейм. Что это такое? В поиске четкой информации не нашёл. И как Вы организовали это добавление или обновление в своём чате?
Заранее благодарен :)
RGoblin:
1) эээ... батенька, да вы похоже не в ту степь полезли... никаких прав никуда не нужно. достаточно одного пользователя БД для коннекта (можно даже root под пароль загнать и не париться). ну и к нему логин с паролем. А в самой бд уже делать таблицу с никами общающихся, их паролями и правами доступа в самом чате.
2) попробуйте разобраться в Java-script коде Бойцовского клуба (www.combats.ru - не реклама). Там это активно используется.
netghost:
RGoblin
Спасибо за разъяснения :) (+1) Просто в первое время меня терзали смутные сомнения по поводу безопасности входа из-под root'a . А можно ещё один вопросик: я вот тут посидел - подумал и пришёл к мысли, что под нулевым фреймом подразумевается некая область (возможно скрытый фрейм или иная конструкция), которая и обновляется. Причём она содержит лишь новые сообщения, а старые к ней не поступают. Потом из этой невидимой области все новые сообщения с помощью JS переносятся в основной, видимый пользоваелю фрейм, фактически создавая иллюзию ДОБАВЛЕНИЯ сообщения, а не какого-то обновления. Получается что этот скрытый фрейм является буфером между базой сообщений и рабочим фреймом пользователя. Как вы думаете, я правильно мыслю, или опять куда-то в дебри?.. :)
RGoblin:
1) в идеале root, конечно не стоит использовать.
2) в общем правильно - один из фреймов имеет нулевую высоту и параметр noresize.
при обновлении сервер присылает в этот фрейм новые сообщения, а тот уже добавляет к существующим сообщениям новые с помощью JS (через свойство innerHTML).
netghost:
RGoblin
всё супер :) Чат почти доделан... Но у меня остался ещё один небольшой вопрос : где нужно хранить список людей в on-line ? Я для авторизации использую мехнизм сессий, поэтому и хотел бы ограничиться одними сессиями. Однако столкнулся с проблемой - как можно просмотреть переменную
$_SESSION['last_tm']

(содержащую время последнего обновления) всех юзверей? Допустим, человек зашел в чат, авторизировался - создалась сессия - и для того, чтобы создатать у него в броузере список юзверей в он-лайн, ему, этому человеку, необходимо просмотреть переменные
$_SESSION['last_tm']
всех сессий (т.е. всех пользователей чата), дабы исключить людей в off-line путем сравнения этого времени, содержащегося в last_tm с текущим временем. Так вот, что-то я не нашёл способа просмотра всех сессий - это и есть основная загвоздка :) Можно было бы конечно создать отдельную таблицу в БД чата только для on-line юзверей, тогда конечно, каждый зашедший в чат сразу имеет доступ ко всем записям этой таблицы. Точнее, я бы конечно и сессии мог бы просмотреть "в лоб" путём их открытия как файлов с именем "ses_".SID , но мне этого делать не хочется. Я прошу у Вас совета.
chin:
Как правило, все именно так и делают: отдельную таблицу.
RGoblin:
netghost
создай отдельную колонку в списке пользователей - online и пиши туда единичку, если пользователь "онлайн", т.е. обращался к чату за последние 5 минут.
и выводи в список пользователей всех тех у кого online=1.
все.
для очистки от "ушедших" проверяй насколько давно было обращение - если недавно, то оставляй единичку, иначе ставь 0.
netghost:
chin
Да, я тоже так сделал. :) Спасибо за ответ.
RGoblin
Спасибо за ответ. Можно было бы сделать и так, но я уже создал отдельную таблицу. В принципе, идея хорошая :)
Saber:
Господа, у меня такой вопрос возник:

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

На РНР пишу пол года - с ним проблем не возникает, впринципе.
С базами MySql тоже все окей.
А вот с JavaScript - проблема.
Поэтому буду благодарен, если кто-нибудь более подробнее опишет:

Дальше работает JavaScript!
Технология такая, раз в 15 секунд (это время выбирает сам юзер, я, например, делал 15,30,45,60 секунд) рабочий фрейм идёт на скрипт и забирает сообщение!
Когда ты отписал сообщение опять же рабочий фрейм идёт на скрипт и отдаёт скрипту сообщение, и сразу же этот скрипт отдаёт ему новые сообщения плюс ту, что он написал!
Кажись с теорией тоже разобрались :-)

Немогу понять с чего начать. Может быть есть какой-нибудь опен-сорц пример работы яваскрипта? Дело в том что я действительно в яваскрипте - ноль. Максимум - это поставить счетчик мейл.ру (стеб :) )
ПОмогите, пожалуйста, объясните как это должно работать, конкретнее.
Буду ОЧЕНЬ и очень Вам благодарен.
Saber:
например в скрытом фрейме раз в 20 секунд скрипт идет на страницу - http://www.chat.com/get_msg.php?SID=ro458tg943hv43igf9
и получает сообщения... только в каком виде ему их скармливать?вообщем я очень запутался :( очень надеюсь что Вы мне поможете
Saberыфваыв:
Люди, уже сделал яваскриптоую часть для чата (ну очень правда, но и то хорошо)
появился вопрос:
как мне вычислить, пшиет ли пользователь приват другому? помогите, с регекспами, пожалуйста!
unlamed:

Люди, уже сделал яваскриптоую часть для чата (ну очень правда, но и то хорошо)
появился вопрос:
как мне вычислить, пшиет ли пользователь приват другому? помогите, с регекспами, пожалуйста!

Может и не актуально, но посмотрев на замечательную библиотеку JSHttpRequest, сразу решил ее использовать. Получился замечательный чат, который я встроил в свой проект http://unlamed.com. Ознакомиться с его работоспособностью можно там.

По поводу реализации: построено на MySQL+PHP+JS. В связи с тем, что основной сайт был реализован на perl (так повелось исторически), немного perl.
Если что непонятно, пишите на nobody (a) unlamed.com.

C уважением,
Nobody
Alex12543:
Хочу чат создать, как бы мне его пооригинальнее сделать? Может какие-нибудь возможности добавить или что-то в этом роде? Если у кого какие идеи есть, напишите, буду премного благодарен!
chin:
unlamed
Это что за фид?

Дядьки, спам (:

Эта тема на forum.dklab.ru