mvn clean install
« Мультимедиа-программирование вместе с Red 5 server. Часть 3 | Мультимедиа-программирование вместе с Red 5 server. Часть 5 » |
Мультимедиа-программирование вместе с Red 5 server. Часть 4
Рассказ о том, как создать веб-приложение, работающее в среде red5, медленно, но неуклонно близится к своему завершению. Так, прошлая статья была посвящена созданию серверной части примера: я перечислял файлы и каталоги, составляющие тот архив war, который можно развернуть на red5 сервере. Сегодняшний же материал расскажет о том, как создать клиентскую часть приложения, как установить соединение с сервером и вызывать на нем какой-нибудь метод из flash.В прошлый раз мы остановились на описании конфигурационных файлов, составляющих java часть проекта. Напомню, что любое веб-приложение в мире java должно содержать, как минимум, один конфигурационный файл: web.xml в подкаталоге WEB-INF. Пример файла, который я привел в конце прошлой статьи, был пуст и не содержал ни одной директивы. Если вы посмотрите на содержимое подкаталога conf, расположенного в корне того каталога, куда вы установили red5, то там вы увидите множество xml и properties-файлов. Все эти файлы содержат настройки как списка служб, запускаемых при старте сервера tomcat, так и настройки по-умолчанию для тех веб-приложений, что будут исполняться в среде red5. Большой необходимости в том, чтобы изменять эти файлы у вас не должно возникнуть, разве что можете обратить внимание на файлы red5.properties и red5-core.xml. В первом из них находится список главных конфигурационных переменных, влияющих на работу поддерживаемых red5 служб. Помните, я говорил в первой статье серии, что существует несколько протоколов, по которым flash-приложение может общаться с сервером, например, RTMP, RTMPT, RTMPTS. Так вот, в файле red5.properties содержатся номера портов, которые сервер red5 будет “слушать”, ожидая входящих подключений по этим протоколам (также можно изменить и номер порта, по которому будет “отдаваться” обычный http-трафик). Что касается файла red5-core.xml, то этот файл является конфигурационным файлом в стиле spring и содержит перечень служб, которые запускаются tomcat-ом при своем запуске. К примеру, протоколы RTMPT, RTMPTS изначально отключены и чтобы их включить, вам нужно убрать лишние комментарии внутри red5-core.xml. Сразу скажу, что сервер red5 был написан с использованием популярной java-технологии spring (http://springframework.org). Если вы никогда ранее не сталкивались с spring, то spring - это средство описания в виде xml-файлов списка компонент составляющих приложение и их настроек. Сейчас spring стал стандартом де-факто для создания “серьезных” java-приложений. Также стала часто встречаться практика, когда приложения (особенно opensource) не содержат отдельных конфигурационных файлов, управляющих их работой, а предлагают пользователям изменять поведение приложения посредством правок spring-конфигураций.
Возвращаясь назад к нашему примеру веб-приложения, давайте рассмотрим остальные файлы, составляющие содержимое модуля warmodule. Итак, в каталоге WEB-INF, помимо файла web.xml, еще находятся файлы red5-web.xml и red5-web.properties. Что касается имен этих файлов, то по умолчанию red5 ищет в каталоге WEB-INF веб-приложения xml-файлы, начинающиеся с “red5-”, а затем загружает эти файлы и интерпретирует их как инструкции по конфигурированию приложения. Имя же второго файла red5.properties не имеет какого-либо особого значения, но чтобы понять то, зачем он нужен, давайте рассмотрим содержимое файла red5-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/red5-web.properties"/>
</bean>
<bean id="web.context" class="org.red5.server.Context" autowire="byType"/>
<bean id="web.scope" class="org.red5.server.WebScope"
init-method="register">
<property name="server" ref="red5.server"/>
<property name="parent" ref="global.scope"/>
<property name="context" ref="web.context"/>
<property name="handler" ref="web.handler"/>
<property name="contextPath" value="${webapp.contextPath}"/>
<property name="virtualHosts" value="${webapp.virtualHosts}"/>
</bean>
<bean id="web.handler" class="blz.red5demo.HelloApplication" singleton="true"/>
</beans>
var nc : RemoteNetConnection = new RemoteNetConnection();
nc.connect('rtmp://localhost/logic’);
webapp.contextPath=/warmodule
webapp.virtualHosts=localhost, 127.0.0.1
Теперь я приведу пример класса HelloApplication. По правилам red5 любой класс, который обрабатывает серверные вызовы внутри red5, должен быть наследован от класса org.red5.server.adapter.ApplicationAdapter:
package blz.red5demo;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
public class HelloApplication extends ApplicationAdapter {
@Override
public boolean appConnect(final IConnection iConnection, Object[] params) {
return super.appConnect(iConnection, params);
}
@Override
public void appDisconnect(IConnection conn) {
super.appDisconnect(conn);
}
}
Разобравшись с серверной частью примера, пора перейти к рассмотрению кода flash-клиента. Не мудрствуя лукаво, я решил создать простенький интерфейс в виде формы с одной единственной кнопкой. По нажатию на эту кнопку я буду посылать на сервер запрос с просьбой подключения к red5 серверу. При отправке запроса на подключение я могу сразу же передать на сервер какую-либо информацию, влияющую на процесс установления сессии. Например, передать имя и пароль для входа в приложение. Серверная часть проверит представленные данные и или разрешит, или отклонит запрос на подключение. Сейчас я не буду усложнять пример и создавать диалоговое окно для запроса имени и пароля. Так что обойдемся передачей фиксированного имени пользователя “DemoUser” и такого же пароля “DemoPassword”. Весь последующий код я поместил внутрь файла Main.mxml расположенного внутри подкаталога “flashmodule/src/main/flex”:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script><![CDATA[
import flash.events.MouseEvent;
import flash.net.NetConnection
private var nc: NetConnection;
private function doConnect(event:MouseEvent):void {
var context : String = application.parent.loaderInfo.parameters['contextName'];
nc = new NetConnection ();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
nc.connect('rtmp://localhost/' + context, “DemoUser”, “DemoPassword”);
}
private function netStatus(event:NetStatusEvent):void {
log.text += event.info.code + "\n";
}
]]>
</mx:Script>
<mx:VBox paddingTop="10" paddingLeft="10">
<mx:Button click="doConnect(event)" label="connect to Red5"/>
<mx:TextArea id="log" width="400" height="400" />
</mx:VBox>
</mx:Application>
Теперь нужно вернуться назад к серверному скрипту и подправить функцию appConnect, так чтобы она проверяла, переданные ей как параметры, имя и пароль:
public boolean appConnect(final IConnection iConnection, Object[] params) {
if (params.length ==2 && "DemoUser".equals(params[0]) && "DemoPassword".equals(params[1]))
return super.appConnect(iConnection, params);
return false;
}
Теперь, после того как мы установили соединение с сервером, можно попробовать и вызывать на нем (точнее в scope или приложении) какие-нибудь методы. В самом начале этой серии статей я поставил целью создать хотя бы простое приложение, посылающее на сервер строку с именем пользователя и получающее в ответ строку вида “Hello, %username%”. Для этого я в состав класса HelloApplication добавил новый метод sayHello.
public String sayHello (String userName){
return “Hello, ”+ userName;
}
<mx:Button click="sayHello(event)" label="Say Hello"/>
private function sayHello (event:MouseEvent):void {
var r : Responder = new Responder(onSayHello, netStatus);
nc.call("sayHello", r, “My User Name”);
}
private function onSayHello(r: Object):void {
trace(r);
}
Показанному мною примеру еще есть куда развиваться. Во-первых, остался открытым вопрос о передаче на сервер и обратно более сложных структур данных, кроме чисел или строк (например, собственный класс User , состоящий из таких полей, как ФИО, дата рождения и т.д.). Но обо всем этом в следующий раз. Также в следующий раз я расскажу о том, как можно из java-кода сделать обратный вызов к какой-либо функции расположенной на стороне flash-клиента. Например, создавая чат, мы, получив от одного из зарегистрированных пользователей сообщение, должны выполнить его рассылку всем остальным пользователям.
« Мультимедиа-программирование вместе с Red 5 server. Часть 3 | Мультимедиа-программирование вместе с Red 5 server. Часть 5 » |