По существу,
стандартизация дает возможность
взаимодействовать между собой разнородным
предметам – фонарику и батарейкам,
Macromedia Flash и серверу
многопользовательской игры, и так далее.
Также и во Всемирной сети, где каждую
секунду перемещаются огромные объемы данных,
чрезвычайно важно стандартизировать способы
обмена данными между системами. Мощный и
простой в использовании XML очень быстро
становится таким общепринятым стандартом.
В этом уроке
мы познакомим вас с основами формата XML, а
также покажем, как можно использовать во
Flash объекты XML и XMLSocket. К концу урока
вы научитесь организовывать "общение" Flash
с ASP-страницами для регистрации входа
пользователей; также мы с вами создадим
простой чат, работающий в реальном времени с
использованием сокет-сервера.
Внимание! Для работы с этим уроком
необходимы учебные файлы, которые Вы
можете загрузить
здесь.
Несложное чат-приложение, которое мы
запрограммируем в этом уроке, будет
использовать соединение типа XML socket.
Основы xml
Хотя само
название XML, или eXtensible Markup
Language, звучит несколько таинственно,
понять и освоить этот язык совсем несложно.
В сущности, XML есть способ форматирования и
структурирования информации, которую
приложения-получатели могут интерпретировать
и использовать. На самом деле все мы, быть
может, сами о том не подозревая, имеем
большой опыт структурирования и организации
информации. Возьмем такой пример.
Когда вы
хотите написать другу письмо, вы должны
структурировать свои мысли (информацию) в
таком формате, который ваш друг сможет
распознать. Итак, вы начинаете писать слова
на листе бумаги, начиная с левого верхнего
угла и разделяя свои мысли на абзацы,
предложения и слова. Конечно, вы могли бы
писать не слева направо, а как-нибудь по
кругу, или вообще попытаться передать свои
мысли картинками, однако такой способ,
скорее всего, лишь приведет вашего друга в
недоумение. А написав письмо в таком формате,
который вашему другу привычен, вы сможете
быть уверены в том, что ваше послание будет
понято – то есть передача ваших мыслей (данных,
информации) получателю письма совершится
успешно.
Для того же
предназначен и XML – это формат для передачи
информации. Если, к примеру, нужно переслать
данные из Flash на веб-сервер для обработки,
следует сначала представить эти данные в
формате XML. Тогда сервер сможет надлежащим
образом интерпретировать эти данные и
использовать их. Без этого сервер, получив
несколько порций данных, не знал бы, что ему
делать с первой порцией, что со второй, и
какое вообще отношение имеет первая порция
ко второй. Благодаря XML эти разрозненные
части данных наполняются смыслом, и сервер
может понять, как с ними работать.
В синтаксисе
XML, подобно HTML, используются теги,
атрибуты и значения – но на этом сходство и
заканчивается. Тогда как в HTML используются
заранее определенные теги (например,
body, head или
html), в XML
пользователь создает свои собственные, а не
выбирает готовые имена из библиотеки.
Давайте для начала рассмотрим вот этот
простой документ XML:
<MyFriend>
<Name Gender="female">Kelly Makar</Name>
<Name Gender="male">Mike Grundvig</Name>
<Name Gender="male">Free Makar</Name>
</MyFriend>
Каждый тег
XML называется узлом (node),
набор данных в формате XML называется
документом XML. В нашем документе-примере
имеется корневой узел
MyFriends и три дочерних узла. Каждый
XML-документ может содержать только один
корневой узел. Первый из дочерних узлов
имеет имя узла Name
и значение узла Kelly
Makar. Слово
Gender в каждом из дочерних узлов –
атрибут. Атрибуты необязательны; каждый узел
может иметь неограниченное число атрибутов.
Обычно атрибуты используются для размещения
небольших порций информации, которые
необязательно отображать на экране (например,
идентификационный номер пользователя).
Как вы видите
в этом примере, теги (которые мы сами же
создали и описали) придают смысл порциям
информации (Kelly Makar, Mike Grundvig и
Free Makar).
Следующий
XML-документ являет более сложный пример
структурирования.
<AddressBook>
<Person>
<Name>Kelly Makar</Name>
<Street>121 Baker Street</Street>
<City>Some City</City>
<State>North Carolina</State>
</Person>
<Person>
<Name>Tripp Carter</Name>
<Street>777 Another Street</Street>
<City>Elizabeth City</City>
<State>North Carolina</State>
</Person>
</AddressBook>
В этом
примере показано, как могут выглядеть данные
адресной книги в формате XML. Если бы в
нашей адресной книге числилось 600 человек,
то узел Person повторялся бы 600 раз при той
же самой структуре.
Каким же
образом следует создавать свои узлы, свою
структуру? Как объект-получатель (ASP-страница,
сокет и т.п.) распознает форматирование
документа? Ответ прост – средства для этого
должны быть встроены в объект-получатель.
Например, если мы создали адресную книгу во
Flash и хотим поместить содержащуюся в ней
информацию в базу данных, нам следует
послать версию нашей книги в формате XML на
ASP-страницу (или другую страницу сценария),
которая сможет проанализировать информацию и
разместить данные в соответствующих полях
базы данных. Вы должны понимать, что этот
скрипт ASP-страницы должен быть заранее
разработан так, чтобы обработать данные
должным образом. XML больше приспособлен для
передачи информации, чем для хранения;
поэтому данные нашей адресной книги удобнее
хранить в записях базы данных, чем в виде
XML-документа. Когда понадобится, информацию
можно будет извлечь из базы данных, с
помощью специального скрипта перевести в
формат XML и переслать во Flash или другое
приложение.
Иногда также
используют текстовые файлы, содержащие
информацию в формате XML – например,
статичный XML-файл, хранящий информацию о
том, какую ASP-страницу следует вызвать или
какой порт и IP-адрес использовать для
соединения с сокет-сервером.
Итак, с
основами структуры XML вы ознакомились;
теперь мы перечислим некоторые правила,
которым необходимо следовать при составлении
XML-документов.
- Не
следует начинать имена узлов буквами
XML; многие XML-анализаторы прерывают
разбор документа, встретив такое
сочетание символов.
-
Каждый узел должен быть правильно
завершен – например, для закрытия узла
<Name>
служит </Name>.
- Все
служебные символы должны кодироваться в
стандарте URL (во Flash это можно
сделать с помощью функции
escape()).
Многие анализаторы интерпретируют
некоторые не кодированные служебные
символы как начало нового узла – а потом
не обнаруживают его завершения. Документ
с незавершенными узлами не сможет пройти
через XML-анализатор полностью. С
атрибутами нужно быть еще внимательнее –
здесь ошибку анализа могут вызвать даже
такие символы, как перевод строки или
амперсанд (&).
Правильно кодируя текст по стандарту
URL, вы избежите подобных проблем.
-
Большинство XML-анализаторов учитывают
регистр клавиатуры (различают прописные
и строчные буквы). Это означает, что все
соответствующие друг другу теги должны
иметь одинаковое написание. Если узел
был начат с
<Name>, а завершился
</name>,
это приведет к ошибке.
-
Корневой узел должен быть единственным.
Прежде чем
приступить к работе, стоит, пожалуй,
упомянуть еще об одном. Все это правильное и
красивое оформление структуры XML-документа
(каждый узел с новой строки, отступы для
дочерних узлов и т.п.) совершенно
необязательно. Все это просто облегчает
чтение документа для нас. А для XML-анализаторов
это просто пустое место; им все равно, есть
эти отступы или нет их.
Использование объекта xml
Что ж, пришла
пора применить XML! Во Flash практически все,
что касается XML, происходит при участии
объекта XML; при этом все происходящее
относится к одной из следующих категорий:
форматирование XML, анализ XML (извлечение
информации), загрузка XML и посылка XML.
Посредством объекта XML можно загрузить XML-данные
из внешнего источника. Документ может
храниться в статичном файле или может быть
создан серверным скриптом. После того, как
XML-документ загружен, доступ к содержащейся
в нем информации можно получить при помощи
методов и свойств объекта XML. Другие методы
и свойства этого объекта помогут создать
собственный XML-документ. Созданный документ
можно использовать во Flash-фильме или
послать скрипту на сервере. О том, как все
это делается, вы узнаете из этого раздела.
Форматирование XML
Объект XML
имеет набор методов, предназначенных для
создания и форматирования XML-документов.
Правда, они весьма не просты в использовании
– однако существует и более простой способ
форматирования XML-объектов: нужно создать
строку и затем преобразовать ее в объект
XML.
Во Flash
объект XML создается при помощи конструктора.
Вот пример создания пустого объекта XML:
myXML =
new XML();
Чтобы
заполнить этот объект данными в формате XML,
необходимо передать конструктору (указать в
скобках) имя переменной, содержащей строку
формата XML или другой объект XML.
Предположим,
что мы хотим создать во Flash такой XML-документ:
<MyFriends>
<Name Gender="female">Kelly Makar</Name>
<Name Gender="male">Free Makar</Name>
</MyFriends>
Для этого мы
должны сделать две вещи:
-
Создать документ в виде текстовой строки.
-
Преобразовать эту строку в объект XML
при помощи конструктора объекта XML –
new XML().
Например, так:
myString
= "<MyFriends><Name
Gender=\"female"\>Kelly Makar</Name><Name
Gender=\"male"\>Free Makar</Name></MyFriends>";
myXML = new XML(myString);
Как видите, в
этом скрипте текст XML-документа создается в
виде строки, которая затем преобразовывается
в настоящий объект XML под названием
myXML. Затем
этот объект можно послать для обработки на
сервер, воспользовавшись одним из
предназначенных для этого методов (которые
мы опишем далее в этом разделе).
Анализ XML
Слово анализ
в данном случае означает разбор на составные,
структурные части. Так, когда говорят о
написании скрипта, анализирующего XML-документ,
имеют в виду извлечение информации из этого
документа. Во Flash объект XML имеет
множество свойств, помогающих это сделать.
Для иллюстрации применения некоторых из них
мы воспользуемся XML-объектом из предыдущего
примера – myXML.
firstChild:
Это свойство указывает на первый узел внутри
структуры. Например:
myXML.firstChild.firstChild возвратит
значение <Name
Gender="female">Kelly Makar</Name>.
Первый дочерний узел XML-документа есть
корневой узел (MyFriends),
а первый дочерний узел корневого узла –
Name.
childNodes:
Это свойство возвращает массив дочерних
узлов данной точки структуры. Например:
myArray =
myXML.firstChild.childNodes. Массив
myArray будет
содержать два элемента, значения которых
будут равны значениям двух узлов Name.
nextSibling:
Это свойство указывает на следующий узел
того же уровня в структуре. Например,
myXML.firstChild.firstChild.nextSibling
возвратит <Name
Gender="male">Free Makar</Name>.
attributes:
Это свойство возвращает ассоциативный массив
имен атрибутов. Например:
myXML.firstChild.firstChild.nextSibling.attributes.Gender
возвратит значение "male".
Мы рассказали
здесь лишь о наиболее употребительных
свойствах объекта XML; прочие свойства
работают похожим образом, указывая на
различные части структуры документа.
Загрузка
XML
Обычно работа
с XML во Flash заключается в загрузке
документа из внешнего источника или отсылке
куда-либо. Чтобы загрузить XML из внешнего
источника, необходимо сделать следующее:
-
Создать объект XML.
- C
помощью метода
load() объекта XML загрузить
данные в XML-формате из внешнего
источника.
Например:
myXML =
new XML();
myXML.load("http://somedomain.com/info.xml");
В данном
случает документ загружается из статичного
XML-файла, однако это не единственный путь.
Можно указать ASP-страницу (или другую
страницу сценария), результатом выполнения
скрипта которой станет XML-документ.
Как узнать,
что загрузка XML из источника в объект XML
завершилась? Очень просто – с помощью
события onLoad
объекта XML. Можно использовать обработчик
этого события для вызова функции, которую
необходимо выполнить по окончании загрузки.
Возьмем такой пример:
function
init () {
//здесь могут быть действия, анализирующие документ
}
myXML = new XML();
myXML.onLoad = init;
myXML.load("http://somedomain.com/info.xml");
Как указывает
вторая снизу строка, по завершении загрузки
документа XML должна быть вызвана функция
init.
Посылка
XML
Объект XML
дает возможность отослать XML-данные по
указанному адресу. Также имеется
возможность, послав XML, сразу же загрузить
результаты его обработки.
Для отсылки
XML нужно воспользоваться методом
send(), указав
необходимый URL. Например:
myXML =
new
XML("<Message><Text>Hi!</Text><Message>");
myXML.send("http://somedomain.com/somedestination.asp");
Чтобы послать
XML и сразу получить ответ, следует
применить метод
sendAndLoad() объекта XML. При этом
необходимо указать XML-объект, содержимое
которого нужно отослать, URL-адрес места
назначения, а также объект XML, в который
должно быть загружено ответное послание. Как
и в случае с методом
load(), здесь событие
onLoad поможет
узнать, что ответ уже загружен. Вот пример:
URL =
"http://www.electrotank.com/projects/tfts/using_xml/UserLogin.asp";
function init () {
trace(objToReceive);
}
xmlToSend =
"<Login><UserName>Jobem</UserName><Password>hayes</Password></Login>";
objToSend = new XML(xmlToSend);
objToReceive = new XML();
objToReceive.onLoad = init;
objToSend.sendAndLoad(URL,
objToReceive);
Данный скрипт
создает объект XML (objToSend),
содержащий информацию для входа на сайт, и
затем отсылает его на URL, ожидая получить
ответ. Как только этот ответ будет полностью
загружен в принимающий XML-объект (objToReceive),
вызывается функция
init.
Итак, вы
кое-что узнали о формате XML, а также об
объектах XML, их методах и свойствах. Пора
применить знания на практике! В этом разделе
урока мы с вами создадим несколько простых
XML-документов, выполним несложный анализ и
применим метод
sendAndLoad() – все это в рамках
Flash-приложения, которое будет служить
экраном регистрации пользователей.
Flash-файл,
над которым мы будем работать в этом
разделе, взаимодействует с ASP-страницами.
Чтобы полностью построить и протестировать
этот файл, вам понадобится доступ к серверу,
который сможет выполнить ASP-скрипты (как
правило, это серверы под управлением
Windows). Для тестирования файлов этого
упражнения вам нужно выложить на
Windows-сервер, в один каталог, два
ASP-файла (AddUser.asp и UserLogin.asp) и
файл базы данных MS Access (XMLExample.mdb).
Эти файлы вы найдете в папке
Lesson12/Assets.
Страница
AddUser.asp воспринимает XML-документы,
имеющие следующую структуру:
<Register>
<UserName>jobem</UserName>
<Email>jobe@electrotank.com</Email>
<Password>secret</Password>
</Register>
В случае
правильной регистрации пользователя страница
AddUser.asp возвращает следующий результат:
<Register>
<Message>User Inserted</Message>
</Register>
Если же
пользователь с таким именем уже существует,
будет возвращен такой результат:
<Register>
<Message>User Exists</Message>
</Register>
Страница
UserLogin.asp воспринимает XML-документы,
имеющие следующую структуру:
<Login>
<UserName>jobem</UserName>
<Password>secretword</Password>
</Login>
Если
информация верна, то страница возвращает
следующий результат:
<Login>
<Message>Login Correct</Message>
</Login>
Если
информация неверна, будет возвращен такой
результат:
<Login>
<Message>Login Incorrect</Message>
</Login>
-
Откройте файл LoginRegister1.fla из
папки Lesson12/Assets.
Все
необходимые кадры, текстовые поля и кнопки в
этом файле уже созданы. Файл имеет четыре
слоя: в слое Actions мы будем размещать все
наши скрипты, слой Labels содержит метки
кадров, в слое Assets находятся текстовые
поля и кнопки, а слой Background содержит
общее графическое оформление.
-
Откройте панель Действия, выделите кадр
1 введите действие stop().
Этим мы
предотвращаем автоматическое воспроизведение
фильма.
-
При курсоре монтажного стола,
установленном на кадр 1, выделите кнопку
Login и введите в панели Действия такой
скрипт:
on
(release) {
_root.gotoAndStop("login");
}
Если
пользователь нажмет эту кнопку, на экран
будет выведен кадр, предлагающий заполнить
форму входа на сайт.
-
При курсоре монтажного стола,
установленном на кадр 1, выделите кнопку
Register и введите в панели Действия
такой скрипт:
on
(release) {
_root.gotoAndStop("register");
}
При нажатии
пользователем этой кнопки на экран будет
выводиться кадр, предлагающий заполнить
форму регистрации пользователя для создания
новой учетной записи.
-
Переместите курсор монтажного стола к
кадру с меткой Login. Здесь на сцене
имеется два текстовых поля – userName и
Password, а также кнопка. Выделите
соответствующий этой метке кадр слоя
Actions и введите в панели Действия
следующую строку скрипта:
loginURL="http://вашдомен.com/projects/tfts/using_xml/UserLogin.asp";
Это будет
адрес ASP-страницы, принимающей XML-документ
с данными для входа на сайт. Скрипт на этой
странице проанализирует посланный ему
документ и вернет ответ – верна ли введенная
пользователем информация. Не ошибитесь,
здесь вы должны правильно указать адрес к
файлу, который вы выложили на сервер.
- В
этот же кадр добавьте описание функции:
function
loginSubmit () {
xmlToSend =
"<Login><UserName>"+userName.text+"</UserName><Password>"+password.text+"</Password></Login>";
objToSend = new XML(xmlToSend);
objToReceive = new XML();
objToReceive.onLoad = loginResponse;
objToSend.sendAndLoad(loginURL,objToReceive);
_root.gotoAndStop("waiting");
}
Эта функция
будет вызываться при нажатии кнопки Submit
(мы потом присоединим к ней соответствующий
скрипт). В первой строке функции
используются значения, введенные в текстовые
поля userName
и password.
Они вставляются в текстовую строку данных
XML-формата; эта строка становится значением
переменной xmlToSend.
Затем мы создаем новый объект XML с именем
objToSend и
передаем ему только что созданную строку
текста в XML-формате. Мы должны это сделать,
поскольку метод
sendAndLoad() работает только с
XML-объектами – мы не можем применить его
непосредственно к строке. Далее мы создаем
новый объект под именем
objToReceive.
В этот XML-объект будет загружаться ответ
ASP-страницы. Далее мы, используя событие
onLoad,
указываем, что по завершении загрузки данных
в объект objToReceive
должна быть вызвана функция
loginResponce()
(эту функцию мы создадим на следующем шаге).
Следующим
действием вызывается метод
sendAndLoad()
с указанием передающего объекта, URL
назначения и объекта, в который должен быть
загружен ответ. Наконец, последнее действие
перемещает монтажный стол к кадру с меткой
waiting,
информируя пользователя о том, что данные
переданы и ожидается ответ сервера.
- В
конец текущего скрипта добавьте описание
еще одной функции:
function
loginResponse () {
var response = objToReceive.firstChild.firstChild.firstChild.nodeValue;
if (response == "Login Correct") {
_root.gotoAndStop("login success");
} else if (response == "Login Incorrect") {
_root.gotoAndStop("login failed")
}
}
Эта функция
будет вызвана, как только последний байт XML
будет загружен в XML-объект
objToReceive.
Функция анализирует ответ, полученный с
сервера.
Первая строка
данной функции создает переменную
response и
присваивает ей значение, извлеченное из
XML-документа, возвращенного сервером. Если
помните, ответ страницы UserLogin.asp имеет
такой формат:
<Login>
<Message>Login Correct|Login Incorrect</Message>
</Login>
Таким
образом, переменная response получит
значение "Login Correct" либо "Login
Incorrect". Затем в действие вступает
оператор if,
который, в зависимости от значения
response,
отправляет фильм к кадру с меткой
login success
либо login failed.
Тем самым фильм покинет кадр
waiting, на
котором, как вы помните, он был остановлен в
ожидании ответа сервера.
-
Выделите кнопку Submit и присоедините
скрипт, вызывающий функцию:
on
(release, keyPress "<Enter>") {
loginSubmit();
}
При нажатии
этой кнопки будет вызвана и выполнена
функция loginSubmit().
Тем самым будет активирован процесс входа на
сайт, описанный на предыдущих шагах.
Подведем
итоги. При вызове функции
loginSubmit()
XML-данные отсылаются на сервер, а фильм
перемещается к кадру с меткой
waiting. По
получении ответа с сервера автоматически
вызывается функция
loginResponse(), и фильм переходит к
кадру с меткой login
success либо
login failed.
Теперь мы
запрограммируем обработку проектом процесса
регистрации.
-
Переместите курсор воспроизведения к
кадру с меткой register. В этом кадре на
сцене расположены три текстовых поля
(userName, email и password), а также
кнопка. Выделите Выделите
соответствующий этой метке кадр слоя
Actions и введите в панели Действия
следующую строку скрипта:
registrationURL =
"http://вашдомен.com/projects/tfts/using_xml/AddUser.asp";
Это адрес
ASP-страницы, которая будет принимать для
обработки XML-документ с регистрационной
информацией. После обработки информации
будет возвращен результат. Будьте
внимательны и укажите правильный путь к
файлу, выложенному вами на сервер.
- В
тот же кадр добавьте описание функции:
function
registrationSubmit () {
XMLtoSend= "<Register><UserName>" + userName.text + "</UserName><Email>
" + email.text + "</Email><Password>" + password.text +
"</Password></Register>";
objToSend = new XML(XMLtoSend);
objToReceive = new XML();
objToReceive.onLoad = registrationResponse;
objToSend.sendAndLoad(registrationURL,objToReceive);
_root.gotoAndStop("waiting");
}
Эта функция
очень похожа на функцию
loginSubmit(),
описанную нами на шаге 6 – различия
заключаются лишь в структуре данных XML и
некоторых именах. Обратите внимание, что
XML-документ содержит здесь три элемента
данных, введенных пользователем – это
userName.text,
email.text и
password.text. Эти данные должны быть
введены пользователем в соответствующие
текстовые поля. Скрипт-получатель
проанализирует документ и извлечет эти
данные.
- В
конец текущего скрипта добавьте описание
еще одной функции:
function
registrationResponse () {
var response = objToReceive.firstChild.firstChild.firstChild.nodeValue;
if (response == "User Inserted") {
_root.gotoAndStop("registration success");
} else if (response == "User Exists") {
_root.gotoAndStop("registration failed")
}
}
Эта функция
будет вызвана, как только последний байт XML
будет загружен в XML-объект
objToReceive.
Функция очень похожа на функцию
loginResponse(),
описанную нами на шаге 7. Если помните,
страница AddUser.asp дает ответ в таком
формате:
<Register>
<Message>User Inserted|User Exists</Message>
</ Register >
Таким
образом, переменная response получит
значение либо "User Inserted", либо "User
Exists". Затем оператор
if, используя
это значение, отправляет фильм к кадру с
меткой registration
success либо
registration failed.
-
Выделите кнопку Submit и присоедините
скрипт, вызывающий функцию:
on
(release, keyPress "<Enter>") {
registrationSubmit();
}
При нажатии
этой кнопки либо клавиши Enter будет вызвана
функция
registrationSubmit(). Тем самым будет
активирован процесс регистрации
пользователя, описанный на предыдущих шагах.
Таким образом, при вызове функции
registrationSubmit()
XML-данные отсылаются на сервер, а фильм
перемещается к кадру с меткой
waiting. По
получении ответа с сервера автоматически
вызывается функция
registrationResponse(), и фильм
переходит к кадру с меткой
login success
либо login failed.
-
Командой Управление > Проверить фильм
(Control > Test Movie) запустите тест
проекта. Нажмите кнопку Register, затем
введите информацию и подтвердите ее
нажатием кнопки Submit. Закройте фильм,
запустите вновь и попробуйте войти на
сайт.
Мы с вами
только что создали несложное приложение,
иллюстрирующее применение объекта XML.
Протестируйте фильм еще несколько раз;
убедитесь, что вы поняли, как это
запрограммировано и как работает.
-
Закройте тестовый фильм и сохраните свою
работу под именем loginRegister2.fla.
Теперь вы
готовы приступить к созданию более
продвинутых приложений, управляемых данными!
Сокет-серверы: основные сведенья
Сокет-сервер
– это приложение, способное поддерживать
соединение типа "сокет" (socket) –
двунаправленный канал связи между
компьютерами сети. Такое соединение является
постоянным, то есть пользователь все время
находится в контакте с сервером, а не только
на время загрузки или передачи информации.
Сокет-сервер, в отличие от страниц
сценариев, работает непрерывно. Он может
одновременно поддерживать множество
соединений и обеспечивать обмен информацией
между присоединенными пользователями. Таким
образом, пользователь, будучи соединен с
сокет-сервером, может в любое время передать
или получить информацию. Именно при помощи
сокет-соединений, обеспечивающих непрерывный
обмен данными, создаются во Flash чаты и
многопользовательские игры.
Ключевая
мысль: при использовании сокет-соединения во
Flash нет нужды специально запрашивать
информацию, чтобы получить ее. Например, в
чат-приложение сообщение просто
"впихивается" без всяких запросов со стороны
Flash.
Учтите,
однако, что сокет-сервер нельзя просто так
прицепить" к графическому интерфейсу вашего
сайта или поместить в нормальный
веб-каталог. Сокет-серверы пишутся обычно на
Java, C, C++ или Visual Basic и для работы
им нужен доступ корневого уровня к
веб-серверу – а это значит, что вам
понадобился бы свой собственный сервер, на
котором вы можете инсталлировать и запускать
все, что хотите, в том числе и сокет-сервер.
Впрочем, никто не мешает вам разместить
сокет-сервер просто на своем персональном
компьютере.
В следующем
упражнении мы покажем вам, как подготовить и
запустить сокет-сервер на локальной машине
(вашей), так что вы сможете создать
несложное чат-приложение, использующее
соединение с сокет-сервером. Чтобы
протестировать это приложение, вам
необходима операционная система Windows 98,
Windows 2000, Windows XP или Mac OS X.
На
прилагаемом к книге CD-ROM вы найдете
простой сокет-сервер на основе Java – он
называется AquaServer (автор – Брэнден Халл
из Figleaf Software). Для запуска этого
сокет-сервера и тестирования чат-программы
на вашей машине должно быть установлено
программное обеспечение Java 2 Runtime
Environment (JRE) версии 1.3.1 или выше.
Если вы используете Mac OS X, то все в
порядке – нужная версия JRE входит в
комплект поставки.
-
Чтобы загрузить и установить JRE (для
пользователей Windows), войдите на сайт
http://www.sun.com. Перейдите в
Downloads > Java Technology > Java 2
Runtime Environment v 1.3.1 (или выше).
Скачайте и установите, следуя
инструкциям.
Далее мы
расскажем вам, как запустить сервер для
определенного порта. Вот что следует сделать
для запуска сервера в Windows:
-
Скопируйте все файлы этого урока с
CD-ROM в папку на своем жестком диске.
Выполните команду Сеанс MS-DOS (MS-DOS
prompt) либо Командная строка (Command
Prompt) (в зависимости от версии
Windows) – Старт > Программы >
Стандартные > Командная строка (или
Сеанс MS-DOS) [Start > Programs >
Accessories > Command Prompt (или
MS-DOS)].
-
Перейдите в тот каталог, куда вы
скопировали файлы урока – для этого
введите команду cd и полный путь к
каталогу (например: cd C:\Documents and
Settings\Jobe Makar\Desktop\FlashFiles).
После этого нажмите клавишу Enter.
Буквы
cd – это
команда смены каталога (change
directory).
- В
окне командной строки введите: java
AquaServer 9999 и нажмите клавишу Enter.
Это
предложение следует вводить в точности так,
как написано, соблюдая заглавные и строчные
буквы. В окне командной строки должна
отобразиться информация о том, что сервер
запущен и прослушивает порт 9999.
Если вы
правильно установили JRE, все должно
заработать без проблем, так что вам нужно
просто оставить окно командной строки
открытым, пока сервер вам нужен. Если вы
закроете это окно, работа сервера будет
завершена.
AquaServer –
один из немногих бесплатных сокет-серверов,
созданных специально для работы с Flash.
Использовать бесплатные сокет-серверы в
коммерческих целях нельзя, однако существуют
чрезвычайно быстрые и надежные коммерческие
сокет-серверы, разработанные для Flash, к
примеру:
-
ElectroServer:
www.electrotank.com/ElectroServer
-
Unity: www.moock.org/unity/
Применение
объекта xmlsocket
Чтобы Flash
смог соединиться с сокет-сервером,
необходимо для начала создать новый объект
XMLSocket. После этого можно будет
использовать методы этого объекта для
установления соединения с сервером и обмена
информацией. В этом уроке мы покажем на
примерах, как создать и использовать объект
XMLSocket; также мы будем использовать
методы и свойства объекта XML, с которым вы
познакомились ранее в этом уроке.
Для создания
нового объекта XMLSocket следует
использовать соответствующий конструктор.
Например:
server =
new XMLSocket();
Приведенная
строка ActionScript создает новый объект
XMLSocket с
именем server.
Для установления соединения
XMLSocket с
сервером следует применить метод
connect(),
используя следующий синтаксис:
server.connect(hostName,port);
Параметр
hostName – это
IPадрес, по которому находится
сокет-сервер; обычно это последовательность
чисел (например, 65.134.12.2). Поскольку в
этом упражнении вы будете соединяться со
своей собственной машиной, вы можете указать
либо последовательность "127.0.0.1", либо
"localhost" – и то, и другое будет указанием
на ваш компьютер. Если ввести
http://localhost в адресной строке
веб-браузера, тот будет соединяться с вашей
собственной машиной, как если бы это был
веб-сайт. Параметр
port указывает на порт, который
прослушивается сервером. Flash может
присоединяться только к портам, код которых
больше 1024. Пример:
server =
new XMLSocket();
server.connect("localhost",9999);
Закрыть
соединение с сервером можно с помощью метода
close() – это
выглядит так:
server.close();
Для передачи
информации через сокет-соединение
используется метод
send() с указанием объекта, который
нужно передать. Например:
sever.send("<Text>Hi</Text>");
XMLSocket
способен обрабатывать следующие виды
событий:
-
onConnect – это событие означает
установление соединения либо отказ в
соединении.
-
onXML – событие возникает каждый
раз, когда через сокет-соединение
поступает информация.
-
onClose – данное событие возникает
при разрыве соединения с сокетом.
Мы можем
назначить обработчики этих событий для
созданного нами объекта
XMLSocket (так
же, как мы делали с событием
onLoad объекта
XML).
Например:
function
serverConnected (success) {
trace(success);
}
server.onConnect = serverConnected;
Здесь, как
видите, функция
serverConnected() вызывается при
возникновении события
onConnect. Параметр
success,
использованный в описании функции, имеет
значение true,
если соединение установлено успешно, и
false – если
соединение не удалось установить.
Событие
onXML
используется следующим образом:
function
xmlReceived (data) {
trace(data);
}
server.onXML = xmlReceived;
Функция
xmlReceived()
будет вызываться каждый раз, когда через
сокет поступает новая информация. Параметр
data содержит
XML-документ, переданный во Flash.
Событие
onXML можно
использовать так:
function
socketClosed () {
//уведомление для пользователя
}
server.onClose = socketClosed;
Обработчик
этого события обычно используют, чтобы
уведомить пользователя о том, что соединение
разорвано.
В этом
упражнении мы с вами построим несложное
чат-приложение, соединяющееся с AquaServer
(бесплатный сокет-сервер, имеющийся на
CD-ROM). Сервер, получив сообщение,
автоматически транслирует его всем
присоединенным пользователям. Нельзя
сказать, что это подходящее решение для
реального, долгосрочного чат-проекта, однако
для учебных целей вполне сгодится. Более
продвинутые серверы позволяют создавать
"компании" или присоединяться к
существующим, дают возможность отправить
сообщение только одному определенному
пользователю, или компании, или всем, кто
находится в чате.
-
Откройте файл chat1.fla из папки
Lesson12/Assets.
Этот файл
содержит четыре слоя: в слой Actions мы
будем помещать наши скрипты, слой Labels
содержит метки кадров фильма, в слое Assets
находятся текстовые поля и кнопки, а в слое
Background – общее графическое оформление.
Мы начнем с
того, что запрограммируем базовые
функциональные возможности нашего
чат-приложения. Позднее мы присоединим
соответствующие действия к различным
кнопкам.
-
Откройте панель Действия, выделите кадр
1 и введите такой скрипт:
stop();
function setChatText (msg) {
chatText += msg;
chatBox.htmlText = chatText;
scrollbar.setScrollPosition(chatBox.maxscroll);
}
Первая строка
содержит действие
stop() – это останавливает
воспроизведение фильма на первом кадре до
дальнейших указаний. Со следующей строки
начинается описание функции. Функция будет
обновлять текст, отображаемый в окне чата
(текст в поле chatBox
с включенной опцией HTML). Окно чата
находится в кадре с меткой
chat. Функция
при вызове принимает один параметр, под
именем msg,
который является текстовой строкой в формате
HTML – с соответствующими тегами: разрыв
строки (<BR>)
и т.п. Первая строка в теле функции
выполняет конкатенацию этой строки со
значением переменной
chatText, в которой хранится полная
"стенограмма" чата. В общем-то, эта
переменная содержит необработанное
HTML-представление сеанса чата. В следующей
стоке функции переменная
chatText
используется для обновления окна чата
(текстовое поле
chatBox). Поскольку для этого поля
включена опция HTML, сырой HTML из
переменной chatText
будет обработан и отображен как
нормальный текст с соответствующим
форматированием.
Если вы
посмотрите на кадр с меткой
chat, то
увидите, что к текстовому полю
chatBox
присоединен Flash-компонент "полоса
прокрутки" (scroll bar). Метод этого
компонента
setScrollPosition() используется для
прокрутки текста в поле, к которому
присоединен компонент. Таким образом,
последняя строка функции прокручивает текст
в поле chatBox
в самый конец.
Эта функция
будет интенсивно использоваться в нашем
приложении, особенно при обработке события
onXML.
- В
тот же кадр, после описания функции,
добавьте описание еще одной функции:
function
initializeChat (itWorked) {
if(itWorked) {
_root.gotoAndStop("login");
} else {
_root.gotoAndStop("failed");
}
}
Эта функция
будет вызываться обработчиком события
onConnect (мы
создадим его на шаге 8). Этот обработчик
будет автоматически передавать функции
значение true
или false
(параметр itWorked),
в зависимости от того, удалось ли установить
соединение. Оператор
if проанализирует значение параметра
и выполнит соответствующее действие. Если
соединение успешно установлено (то есть
itWorked имеет
значение true),
монтажный стол фильма будет перемещен к
кадру с меткой login.
Если установить соединение не удалось,
произойдет переход к кадру с меткой
failed. Таким
образом, эта функция не допустит перехода
пользователя к экрану входа на сайт, если он
не соединен с сервером.
- В
тот же кадр добавьте описание еще одной
функции:
function
received (info) {
info.ignoreWhite = true;
var from = info.firstChild.firstChild.attributes.from;
var message = info.firstChild.firstChild.firstChild.nodeValue;
setChatText("<BR><B><FONT FACE=\"arial\" SIZE=\"15\" COLOR=\"#333333\">
"+from +"</B></FONT>: <FONT FACE=\"arial\" SIZE=\"15\"
COLOR=\"#999999\">
"+message+"</FONT>");
}
Эту функцию
мы назначим для обработки события
onXML (на шаге
8), то есть она будет вызываться при
получении информации с сервера. Параметр
info
представляет собой полученные XML-данные.
Эти полученные данные (сообщение чата)
идентичны данным, которые послал сервер. Они
форматированы так:
<doc>
<message from="jobe">Hello world</message>
</doc>
В двух первых
строках функции используются свойства
объекта XML – для присвоения значений
локальным переменным
from и message.
Согласно структуре XML-документа значением
переменной from
станет имя пославшего сообщение, а
переменная message
будет содержать сам текст сообщения. После
этого эти переменные используются при
создании строки HTML-кода, которая
добавляется в окно чата при помощи функции
setChatText()
(описанной на шаге 2).
Примечание
Информацию об использовании текста в HTML-формате
вы найдете в Уроке 13 – Проверка и
форматирование данных.
-
Добавьте в тот же кадр описание функции,
которая будет сообщать пользователю о
разрыве соединения:
function
connectionClosed () {
setChatText("<BR><B><FONT FACE=\"arial\" SIZE=\"15\" COLOR=\"#666666\">
The connection has been terminated.</B></FONT>");
}
Вскоре мы
назначим эту функцию для обработки события
onClose (на
шаге 8). Функция будет вызываться при
закрытии или потере соединения с сервером.
Собственно, все действие этой функции
заключается в вызове другой функции –
setCharText(),
которая, как вы помните, обновляет текст в
окне чата. Таким образом, при завершении
соединения в окне чата появляется сообщение
"The connection has been terminated".
-
Добавьте описание функции для "ручного"
закрытия соединения:
function
closeConnection () {
server.close();
}
Вызов этой
функции приведет к принудительному разрыву
сокет-соединения. Это приведет к
возникновению события
onClose. Вызов этой функции мы вскоре
присоединим к одной из кнопок.
- В
тот же кадр добавьте описание еще одной
функции:
function
send (messageToSend) {
server.send("<doc><message from=\""+screenName+"\">"+messageToSend+"</message></doc>");
}
Эта функция
посылает сообщение на сервер при помощи
метода send()
– само сообщение передается функции как
параметр (messageToSend);
его значение – это любой текст, введенный
пользователем. Этот текст форматируется в
XML-документ, структура которого выглядит
так:
<doc>
<message from="jobe">Hello</message>
</doc>
Этот документ
отсылается на сервер, и тот рассылает его
всем прочим пользователям; вызывается
функция received()
(мы описали ее на шаге 4) и выводит новое
полученное сообщение во всех открытых окнах
чата.
-
После скрипта, добавленного на
предыдущем шаге, поместите следующие
строки:
XML.prototype.ignoreWhite = true;
server = new XMLSocket();
server.onConnect = initializeChat;
server.onXML = received
server.onClose = connectionClosed;
server.connect("localhost",9999);
Первая строка
здесь устанавливает свойство
ignoreWhite
всех XML-объектов в значение
true.
Благодаря этому все "пустые" пробелы (то
есть, отступы и переводы строки между
узлами) будут игнорироваться – хороший
обычай, учитывая то, что это весьма упростит
и ускорит анализ кода. Помните, мы говорили,
что Flash воспринимает отступы и переводы
строки как узлы, поэтому, если не присвоить
ignoreWhite
значение true,
вы можете получить дополнительные ненужные
"узлы". Не беспокойтесь об отступах и
переводах строки внутри узлов – с ними
ничего не случится. Свойство
ignoreWhite
действует только между узлами.
Остальные
строки этого скрипта создают новый объект
XMLSocket с
именем server и назначают функции для
обработки всех его событий. Последняя строка
открывает соединение с сервером. Напомним:
все это у нас запрограммировано в кадре 1, а
значит, будет выполнено (либо определено)
сразу после начала воспроизведения фильма.
-
Переместите курсор монтажного стола к
кадру с меткой failed. Выделите кнопку
Try Again и введите в панели Действия
такой скрипт:
on
(release) {
_root.gotoAndStop(1);
}
При неудачной
попытке установления соединения фильм
перемещается к кадру с меткой
failed. Этой
кнопкой мы даем пользователю возможность
повторить попытку установить соединение,
перемещая фильм опять к кадру 1, где
содержатся запрограммированные нами действия
для установления соединения.
-
Переместите курсор монтажного стола к
кадру с меткой login – здесь имеется
текстовое поле (с именем nameField) и
кнопка. Выделите соответствующий этой
метке кадр в слое Actions и введите в
панели Действия следующую строку
скрипта:
selection.setFocus("nameField");
Когда фильм
перейдет к этому кадру, данная строка
установит курсор в текстовое поле
nameField.
Таким образом, пользователь сможет сразу
начать вводить свое имя – ему не придется
щелкать мышкой в этом текстовом поле. Для
нас запрограммировать это совсем не сложно,
а для пользователей будет большое удобство.
-
По-прежнему находясь в кадре login,
выделите кнопку Submit и присоедините к
ней такой скрипт:
on (release, keyPress "<Enter>") {
if (nameField.text != "") {
screenName = nameField.text;
_root.gotoAndStop("chat");
}
}
Этот скрипт
будет устанавливать "экранное имя"
пользователя, которое будет использоваться
при передаче сообщений (см. шаг 7). Когда
пользователь нажмет кнопку Submit, оператор
if сначала
проверит, введено ли хоть что-нибудь в
текстовое поле
nameField. Текст из этого поля станет
значением переменной
screenName – именно она и будет
содержать "экранное имя" пользователя.
Последнее действие перемещает монтажный стол
фильма к кадру с меткой
chat, где
пользователь уже сможет отправлять и
получать сообщения.
-
Переместите курсор монтажного стола к
кадру с меткой chat – здесь имеется два
текстовых поля (chatBox и chatMessage) и
две кнопки. Выделите соответствующий
этой метке кадр в слое Actions и введите
в панели Действия следующие строки
скрипта:
setChatText("<FONT FACE=\"arial\"
SIZE=\"20\" COLOR=\"#666666\">
<b>You have just joined the
chat!</b></FACE>");
selection.setFocus("chatMessage");
Эти действия
будут выполнены, как только фильм перейдет к
кадру с меткой chat.
Первая строка вызывает функцию
setChatText()
(описанную на шаге 2), которая отобразит в
окне чата сообщение для пользователя о том,
что он только что присоединился к чату.
Следующая
строка устанавливает курсор в текстовое поле
chatMessage,
где пользователь может вводить свои
сообщения для передачи. Это сделано для
удобства – как и скрипт на шаге 10.
-
Выделите кнопку Send и введите в панели
Действия следующий скрипт:
on
(release,keyPress "<enter>") {
if (chatMessage.text != "") {
send(chatMessage.text);
chatMessage.text = "";
}
}
Этот скрипт
будет отсылать введенное пользователем
сообщение при нажатии кнопки Send. Оператор
if проверяет,
введено ли хоть что-нибудь в поле
chatMessage.
Если в нем имеется какой-либо текст, он
передается в качестве параметра функции
send(),
описанной нами на шаге 7.
Последнее
действие в этом скрипте опустошает текстовое
поле chatMessage,
так что пользователь сможет сразу начать
вводить следующее сообщение.
-
Выделите кнопку Close Connection и
введите в панели Действия следующий
скрипт:
on
(release) {
closeConnection();
}
Этот скрипт
вызывает функцию
closeConnection(), описанную на шаге
6. Когда пользователь нажмет эту кнопку,
сокет-соединение будет принудительно
разорвано.
-
Запустите AquaServer на порте 9999.
Инструкции,
как это сделать, вы найдете в предыдущем
разделе.
-
Выполните команду Управление > Проверить
фильм (Control > Test Movie), чтобы
проверить, что у нас получилось: войдите
в чат и пошлите несколько сообщений.
В окне чата у
вас должны появиться HTML-форматированные
сообщения. Вы можете открыть несколько
экземпляров этого SWF-файла и попробовать
вести чат сразу за нескольких пользователей.
Нажав кнопку Close connection, вы увидите
сообщение о том, что вы отключены от чата.
-
Сохраните свою работу как chat2.fla.
Мы, наконец,
закончили! Как вы убедились, чтобы создать
даже самое простое чат-приложение, требуется
выполнить немалую работу. Зато теперь вы
освоились с XML, а также приобрели опыт
построения довольно больших и сложных
приложений.
|