Модераторы: javastic, W0LF, AntonSaburov
  

Поиск:

Добавить материал
 

Технология Push
W0LF
Репутация: 19
Всего: 20

Профиль
Быстрая цитата Цитата
Теги:
Цитата

Технология Push

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

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

"Push" является частью системы управления приложениями (application management system (AMS)), то есть программным обеспечением устройства, ответственным за жизненный цикл каждого из приложений (инсталляцию, активацию, запуск и удаление). Рush регистрация является компонентом AMS, который используется Push API и следит за Push регистрациями.

Push Регистрация (Push Registry)


PushRegistry API позволяет регистрировать push сигналы и соединения, а также получать информацию о push соединениях. Обычно push регистрация имеет доступ к списку регистраций соединений и сигналов как в памяти, так и на постоянном носителе.

PushRegistry API

Push регистрация является частью Generic Connection Framework (GCF) и содержится в одном классе, javax.microedition.io.PushRegistry, который содержит все необходимые методы. Они перечислены в следующей таблице.

user posted image

Набор методов может показаться весьма скромным, однако это все, что Вам потребуется для реализации push составляющей Вашего приложения.

Исключения

При использовании PushRegistry API Вы можете столкнутся с некоторыми исключениями, которые вам следует отлавливать. К примеру, Вы можете получить исключение в случае, если платформа не поддерживает определенный тип соединения или не имеет достаточного количества ресурсов. Следующая таблица содержит исключения, которые может бросать PushRegistry.

user posted image

Исключения, связанные с безопасностью - нововведение. MIDP 2.0 приложения должны запрашивать разрешения перед использованием привилегированных операций, таких как использование сетевых соединений или push регистрацию. Если Вы не запросите необходимых разрешений, то платформа может кинуть SecurityException.

Активация мидлета и его жизненный цикл

Появление push технологии не изменило жизненного цикла мидлетов, но открыло два новых способа их активации:

    * При помощи входящих сетевых соединений
    * При помощи сигнала таймера 

user posted image



Разделение ответсвенности за push процесс

В MIDP 2.0 ответсвенность за push разделяется между мидлетом и AMS. Как только мидлет зарегистрировал себя при помощи push регистрации, ответственность за обработку push событий разделяется следующим образом:

   1. Когда мидлет неактивен, AMS отслеживает зарегистрированные push события вместо мидлета. Когда происходит push событие, AMS активирует соответствующий мидлет для обработки этого события. Следующая схема иллюстрирует эту последовательность сетевой активации. 
user posted image

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


О внешних соединениях


Для поддержки сетевой акивации платформа должна поддерживать некоторые типы внешних соединений. В MIDP 1.0 единственным официально поддеживаемым типом был HttpConnection - клиентский тип сетевого соединения и, следовательно, не пригодный для push передачи посредством внешних соединений. В MIDP 2.0 поддерживаются новые типы соединений над HTTP, такие как TCP сокеты (потоковые) и UDP датаграмы (пакетные), которые могут быть использованы для внешних соединений и, в свою очередь, для push передачи. В добавок, Wireless Messaging API (WMA) делает возможной активацию, основанную на SMS. В спецификации MIDP 2.0 не определен тип внешнего соединения для push передачи, дает некоторую свободу разработчикам платформ. Тем не менее, обычно используются сокеты и датаграмы. Стоит помнить, что попытка использования неподдерживаемого соединения выльется в ConnectionNotFoundException исключение.

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

Для создания внешнего соединения, основанного на статичном адресе, надо вызвать метод Connector.open() с URL, описывающим протокол и локальный порт. Например:
Код


Connector.open("socket://:5000")
Connector.open("datagram://:5000")
Connector.open("sms://:5000")


Для создания же внешнего соединения, основанного на динамическом адресе, необходимо вызвать метод Connector.open() с URL, описывающим только протокол для того, чтобы показать, что система сама должна назначить адрес. Например:

Код

Connector.open("socket://")
Connector.open("datagram://")


При использовании адреса, назначенного системой, Вы должны опубликовать этот адрес, чтобы внешние системы могли подключиться к Вашему приложению. Если Вы используете ServerSocketConnection или UDPDatagramConnection, то Вы можете получить динамически назначенный адрес при помощи методов getLocalAddress() и getLocalPort(). Вы можете также получить имя хоста, назначенного Вашему устройству, вызовом System.getProperty("microedition.hostname"). Для публикации динмаческого адреса внешним системам Вы можете использовать HTTP.

Push Регистрация

Для того, чтобы стать push-активным, мидлет должен зарегистрироваться при помощи push регистрации, используя один из двух типов регистраций:

    * Статическая регистрация - Регистрация статических соединений происходит при установке пакета мидлетов. Вы можете указать их в MIDlet-Push атрибутах соответствующего JAD файла или JAR манифест файла. Установка провалится, если Вы попытаетесь зарегистрировать уже зарегистрированный адрес. При деинсталяции пакета мидлетов для всех связанных с ним соединений регистрация будет удалена.
    * Динамическая регистрация- Вы регистрируете динамические соединения и сигналы таймера при выполнении программы, используя PushRegistry API. 

В некоторых случаях Вы, возможно, захотите зарегистрировать статическое соединение в зависимости от какого-то условия или удостовериться, что push исключения не помешают установке мидлета. В таких случаях Вы можете использовать PushRegistry API для регистрации статического соединения и отлова любых IOExceptions или SecurityExceptions исключений. Хотя чаще всего Вы будете регистрировать статическое соединение, используя JAD файл и позволяя системе удалить регистрацию этого соединения, когда мидлет будет удаляться.

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

Статическая регистрация (с использованием MIDlet-Push атрибута)

Статические регистрации определяются атрибутом (возможно, несколькими атрибутами) MIDlet-Push в JAD или JAR манифест файлах. AMS осуществляет статическую регистрацию сразу после установки мидлета. Аналогично, когда пакет мидлетов удаляется, AMS автоматически отменяет регистрацию всех связанных с ним push соединений.

Формат MIDlet-Push атрибута следующий:
Код


MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>


где

    * MIDlet-Push-<n> является именем свойства, которое определяет push регистрацию, где <n> - номер, начиная с 1. К примеру, MIDlet-Push-1. Заметьте, что можно делать более одной записи для push.
    * <ConnectionURL> - это строка URL соединения, которая определяет внешнюю точку для регистрации. Записывается в том же формате, что испольуется для вызова Connector.open(). Напрмер, socket://:5000 закрепляет для внешнего сервера сокетное соединение с портом 5000.
    * <MIDletClassName> полностью указанное имя класса мидлета, которые должен быть запущен в случае обнаружения сетевой активности в<ConnectionURL>. Например, j2medeveloper.basicpush.PushMIDlet.
    * <Allowed-Sender> - фильтр, используемый для used to ограничения круга серверов, которые могут активировать <MIDletClassName>. Можно использовать шаблоны. * означает один или более символов, а ? один символ. Например, 192.168.1.190 или 192.168.1.* или 192.168.19?.1 или просто * . 


Далее показан JAD файл для статической регистрации внешнего сокетного соединения с портом 5000 (без фильтрации адресов), которое активирует мидлет j2medeveloper.basicpush.PushMIDlet.


Код

MIDlet-1: PushMIDlet,,j2medeveloper.basicpush.PushMIDlet
MIDlet-2: WMAMIDlet,,j2medeveloper.wma.WMAMIDlet
MIDlet-Name: MyMIDletSuite
MIDlet-Vendor: Sun Microsystems, Inc.
MIDlet-Version: 1.0
MIDlet-Jar-Size: 4735
MIDlet-Jar-URL: basicpush.jar
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-Push-1: socket://:5000, j2medeveloper.basicpush.PushMIDlet, *
MIDlet-Permissions: javax.microedition.io.PushRegistry, javax.microedition.io.Connector.serversocket


Листинг JAD файла с атрибутом MIDlet-Push


Если запрошенный адрес <ConnectionURL> уже используется, то инсталляция провалится. То, как факт провала подается пользователю, зависит от поставщика и реализации

Динамическая регистрация


Вам необходимо использовать PushRegistry API для реализации динамической регистрации как внешних соединений, так и сигналов таймера в процессе исполнения.

Регистрация сигнала таймера

Вашему мидлету, возможно, надо будет выполнять некоторую периодическую обработку информации через определенные промежутки времени. Например, ему надо будет синхронизироваться с сервером каждые 30 минут. В этом случае Ваш мидлет может использовать TimerTask для того, чтобы запланировать переиодическую обработку, как показано в следущем листинге:

Код

...

long REFRESH_TIME = 1000*60*5; // каждые 5 минут
Timer aTimer = new Timer();
MyTask myTask = new MyTask();
aTimer.schedule(myTask, 0, REFRESH_TIME);

...

class MyTask extends TimerTask {
    public MyTask() {
    }
    
    ...
    
    public void run() {
        ... // Ваше тело задачи
    }
}

...

Листинг. Использование TimerTask


В этом примере осуществляется планировка запуска класса MyTask через каждые REFRESH_TIME миллисекунд. Для периодического запуска Вам надо вписать логику Вашей задачи в run() методе.

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

В следующем примере вспомогателный метод использует метод registerAlarm() для планирования запуска мидлета:

// @param deltatime количество времени в миллисекундах до истечения времени таймера.
Код

private void scheduleMIDlet(long deltatime)
    throws ClassNotFoundException, 
           ConnectionNotFoundException, 
           SecurityException {

    String cn = this.getClass().getName();
    Date alarm = new Date();
    long t = PushRegistry.registerAlarm(cn, 
        alarm.getTime()+deltatime);
}


Листинг. Использование метода registerAlarm().


Если вызов registerAlarm() перезапишет предыдущий таймер, то он вернет старое время таймера. В противном случае он вернет 0.

PushRegistry API не дает инструментов для обнаружения факта запуска мидлета при помощи таймера. Если Вам необходимо будет это обнаружить, то Вам нужно будет реализовать свой собственный метод для этого. К примеру, можно сохранять информацию о времени предыдущего запуска в постоянной памяти и затем сравнить сохраненное время с тем, когда мидлет был запущен в последний раз.

Мидлет, которому нужны push сигналы, должен запланировать их перед выходом. Следущий фрагмент кода использует метод scheduleMIDlet() для планирования запуска мидлета перeд выходом:

Код

public void destroyApp(boolean uc) throws 
    MIDletStateChangeException {
    // Освободить ресурсы
    ...
    //  Устанавливаем таймер и завершаем выполнение мидлета
    scheduleMIDlet(defaultDeltaTime);
    display = null;
}


Листинг. Планирование активации по таймеру перед выходом


Регистрация внешнего соединения

Разберем несколько примеров регистрации внешних соединений. Начнем с примера, в котором используется определенный пользователем локальный порт. Мидлет вызывает registerConnection() для регистрации только что созданного внешнего сокетного соединения:
Код

...

String midletClassName = this.getClass().getName();
String url = "socket://:5000"; 
String filter = "*";

try {
    // Open the connection.
    ServerSocketConnection ssc = (ServerSocketConnection)Connector.open(url);
    // Регистрируем соединение так, чтобы когда мидлет существует (разрушается),
    // AMS может его активировать в случае обнаружения сетевой активности.
    // AMS будет помнить зарегистрированный URL, даже если мидлет будет неактивен
    PushRegistry.registerConnection(url, midletClassName, filter);
    // Теперь ждем внешней сетевой активности.
    SocketConnection sc = (SocketConnection)ssc.acceptAndOpen();
    // Читаем данные из внешнего соединения.
    InputStream is = sc.openInputStream();
    //  ..... читаем входной поток.

    // Здесь обрабатываем полученные данные.
    //  .....
}
catch(SecurityException e) {
    System.out.println("SecurityException, insufficient permissions");
    e.printStackTrace();
}
catch(ClassNotFoundException e) {
    System.out.println("ClassNotFoundException, MIDlet name not found");
    e.printStackTrace();
}
catch(IOException e) {
    System.out.println("IOException, possibly port already in use.");
    e.printStackTrace();
}

...


Листинг. Регистрация сокетного соединения определенного пользователем


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

Код

...

String midletClassName  = this.getClass().getName();
String url = "socket://";
String filter = "*";

try {
    // Открываем соединение.
    ServerSocketConnection ssc = (ServerSocketConnection)Connector.open(url);
    // Находим порт, назначенный системой.
    url = "socket://:" + ssc.getLocalPort();
    // Регистрируем соединение.
    PushRegistry.registerConnection(url, midletClassName, filter);
    // Публикуем URL для push. Можно использовать HTTP POST или сокеты или датаграмы для этого.
    String purl;
    purl = "socket://"+ssc.getLocalAddress()+":"+ssc.getLocalPort();
    publishInboundConnection(purl, midletClassName);
}
catch(SecurityException e) {
    System.out.println("SecurityException, insufficient permissions");
    e.printStackTrace();
}
catch(ClassNotFoundException e) {
    System.out.println("ClassNotFoundException, MIDlet name not found");
    e.printStackTrace();
}
catch(IOException e) {
    System.out.println("IOException, possibly port already in use.");
    e.printStackTrace();
}

...


Листинг. Регистрация и публикация сокетного соединения назначенного системой


Отмена регистрации внешнего соединения

Так как AMS поддерживает регистрацию даже после завершения работы мидлета, последнему надо отменить регистрацию соединения, когда она уже не требуется. Для того, чтобы это сделать, используйте метод unregisterConnection():

.
Код

..

try {
    boolean status;
    // unregisterConnection возвращает false в случае неудачи и true в противном случае.
    status = PushRegistry.unregisterConnection(url);
}
catch(SecurityException e) {
    System.out.println("SecurityException, insufficient permissions");
    e.printStackTrace();
}

...


Листинг. Отмена регистрации соединения


Метод кинет SecurityException, если указанный мидлет был зарегистрирован другим пакетом мидлетов. 

Источник - "Нововведения в MIDP 2.0 (отчет Михаила Грачева)"

Это сообщение отредактировал(а) W0LF - 19.3.2008, 23:20


Комментарии посетителей:


Дата 20.3.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата
Antropoid **   Репутация: 13  Всего: 16 
Почините картикни плиз - теряется суть написанного
PM MAIL   Вверх

Дата 20.3.2009, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата
W0LF ***   Репутация: 19  Всего: 20 
Сори, это наверно при переносе случилось, раньше все было нормал. искал ток че статью в нете - не нашел, наверно прибили уже, у меня где-то есть на внешнем винте она, но винт появится не раньше вторника, поэтому, еще раз сорри, но ни чем пока помочь с картинками не могу..
PM MAIL WWW   Вверх

  
 

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.0863 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.