<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Welab Developer&#039;s Blog</title>
	<atom:link href="http://blog.welab.ru/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.welab.ru</link>
	<description>Блог разработчиков студии Welab</description>
	<lastBuildDate>Tue, 23 Feb 2010 08:09:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Использование fork() и DBD::Pg</title>
		<link>http://blog.welab.ru/?p=124</link>
		<comments>http://blog.welab.ru/?p=124#comments</comments>
		<pubDate>Tue, 16 Feb 2010 07:20:27 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[Разработка]]></category>
		<category><![CDATA[DBI]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=124</guid>
		<description><![CDATA[Находил в интернете очень много статей о том, как пользоваться функцией fork() или интерфейсов DBI, но ни разу не встречал статей о том, с какими проблемами сталкиваешься при одновременном использовании этих вещей. Хочу написать о том, с чем столкнулся я при их использовании.Я, в частности, при разработке приложения на Perl, использующем fork() и DBD::Pg, столкнулся [...]]]></description>
			<content:encoded><![CDATA[<p>Находил в интернете очень много статей о том, как пользоваться функцией <em>fork()</em> или интерфейсов <em>DBI</em>, но ни разу не встречал статей о том, с какими проблемами сталкиваешься при одновременном использовании этих вещей. Хочу написать о том, с чем столкнулся я при их использовании.<span id="more-124"></span>Я, в частности, при разработке приложения на Perl, использующем<em> fork()</em> и <em>DBD::Pg</em>, столкнулся со следующими проблемами.</p>
<p><strong>Проблема 1: автоматически закрывается соединение с БД после уничтожения одного из дочерних процессов.</strong></p>
<p>Данная проблема возникает из-за того, что Perl автоматически уничтожает переменные, ссылок на которые больше нет. Решение данной проблемы можно найти в описании модуля <em>DBI</em> в <a href="http://search.cpan.org">архиве CPAN</a>. В частности, смотрите описание атрибута <em>InactiveDestroy</em>.</p>
<p>Итак, чтобы соединение не закрывалось автоматически, то необходимо присвоить этому атрибуту ложное значение &#8211; ноль, пустая строка или неопределенное значение. Но при этом необходимо не забывать, что будет хорошим тоном закрыть соединение в конце работы родительского процесса вручную или автоматически.</p>
<p>Можно использовать следующий алгоритм для автоматического закрытия соединения в родительском процессе.</p>
<pre><code>my $dbh = DBD::SomeDriver-&gt;new();
$dbh-&gt;{InactiveDestroy} = undef; # Разрешаем автоматическое закрытие соединения
. . .
my $child = fork();
unless ($child) {
  $dbh-&gt;{InactiveDestroy} = 1; # Запрещаем автоматическое закрытие соединения в дочернем процессе
  . . .
}
. . .</code></pre>
<p><strong>Проблема 2: возникают ошибки типа &#8216;<em>Statement is already prepared</em>&#8216; в дочерних процессах</strong></p>
<p>Данные ошибки возникают при использовании метода <em>prepare()</em> для подготовки SQL-запросов. Один из вариантов, которым я пользуюсь, является клонирование дескриптора БД.</p>
<p>Дополняя предыдущий пример, можно прийти к такому алгоритму.</p>
<pre><code>my $dbh = DBD::SomeDriver-&gt;new();
$dbh-&gt;{InactiveDestroy} = undef; # Разрешаем автоматическое закрытие соединения
. . .
my $child = fork();
unless ($child) {
  $dbh-&gt;clone(); # Создаем копию дескриптора БД
  $dbh-&gt;{InactiveDestroy} = 1; # Запрещаем автоматическое закрытие соединения в дочернем процессе
  . . .
}
. . .</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=124</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Использование scrnsave.lib при разработке хранителей экрана</title>
		<link>http://blog.welab.ru/?p=122</link>
		<comments>http://blog.welab.ru/?p=122#comments</comments>
		<pubDate>Fri, 05 Feb 2010 15:09:56 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[Разработка]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Screen Saver]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/2010/02/05/122/</guid>
		<description><![CDATA[Начитавшись в интернете статей о том, как легко создается хранитель экрана с помощью библиотеки  scrnsave.lib в Visual Studio, я решил попробовать ее на практике. Собрав простенький пример на базе этой статьи, я&#8230; хм&#8230; обломался. Хранитель экрана упорно ругался на то, что не найдена функция ChangeWindowMessageFilter в USER32.DLL.Погуглив я узнал, что такая функция появилась впервые в [...]]]></description>
			<content:encoded><![CDATA[<p>Начитавшись в интернете статей о том, как легко создается хранитель экрана с помощью библиотеки  scrnsave.lib в Visual Studio, я решил попробовать ее на практике. Собрав простенький пример на базе <a href="http://www.hostmake.ru/articles/c/252/">этой</a> статьи, я&#8230; хм&#8230; обломался. Хранитель экрана упорно ругался на то, что не найдена функция <em>ChangeWindowMessageFilter</em> в <em>USER32.DLL</em>.<span id="more-122"></span>Погуглив я узнал, что такая функция появилась впервые в Windows Vista, а в XP и более ранних ею даже не пахнет. Проект я создавал в VS2008 Express, в который входила библиотека<em> scrnsave.lib</em> с сылкой на эту функцию. Из доступных советов было только, скачать более раннюю версию <em>scrnsave.lib</em>, создать DLL с &laquo;заглушкой&raquo;, и написать на форуме Microsoft SDK и тихо ждать. Еще один вариант был, создание хранителя экрана с нуля &#8211; с самостоятельной обработкой всех событий и т.п. Не густо.</p>
<p>Помедитировав над проектом какое-то время, я нашел достаточно простое решение, которое прекрасно работает в моей XP.</p>
<p>Итак, все что необходимо сделать, это пометить USER32.DLL, как отложенно загружаемую. Если конкретнее, то открываем свойства проекта, переходим в <strong>Свойства конфигурации\Компоновщик\Ввод</strong> и в значение параметра <strong>Отложенно загружаемые DLL</strong> дописываем <strong>USER32.DLL</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=122</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web-расширения GpsGate Server</title>
		<link>http://blog.welab.ru/?p=109</link>
		<comments>http://blog.welab.ru/?p=109#comments</comments>
		<pubDate>Mon, 18 Jan 2010 05:18:27 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/2010/01/18/109/</guid>
		<description><![CDATA[GpsGate Server имеет одну хорошую особенность, он позволяет добавлять свои web-расширения (дополнительные окна), реализующие необходимую Вам бизнес логику. Реализуются данные расширения с помощью DisplayKit, построенного, в прочем, как и весь web-интерфейс, на базе MochaUI и MochiKit.Для начала полезные ссылки: DisplayKit можно найти здесь; Официальный сайт MochaUI; Официальный сайт MochiKit; Пример разработки расширения здесь. Рекомендую скачать [...]]]></description>
			<content:encoded><![CDATA[<p>GpsGate Server имеет одну хорошую особенность, он позволяет добавлять свои web-расширения (дополнительные окна), реализующие необходимую Вам бизнес логику. Реализуются данные расширения с помощью <i>DisplayKit</i>, построенного, в прочем, как и весь web-интерфейс, на базе <i>MochaUI</i> и <i>MochiKit</i>.<span id="more-109"></span>Для начала полезные ссылки:</p>
<ul>
<li>DisplayKit можно найти <a href="http://franson.com/gpsgateserver/DisplayKit.zip">здесь</a>;</li>
<li><a href="http://mochaui.com/">Официальный сайт</a> MochaUI;</li>
<li><a href="http://mochikit.com/">Официальный сайт</a> MochiKit;</li>
<li>Пример разработки расширения <a href="http://franson.com/forum/topic.asp?TOPIC_ID=10663">здесь</a>.</li>
</ul>
<p>Рекомендую скачать и рассмотреть пример разработки расширения, указанный выше, так как все дальнейшие разъяснения буду основываться на его исходниках.</p>
<p>Первое, главными и необходимыми файлами модуля расширения являются следующие:</p>
<ul>
<li><b>Dispatcher.xml</b> &#8211; здесь размещается описание расширения, а также страница (<i>ScriptPage</i>), на которой будет возможность открывать окно расширения, и файл JavaScript (<i>ScriptFile</i>), который создаст окно расширения.</li>
<li><b>DispatcherPackage.xml</b> используется для предоставления информации активатору/установщику расширений в SiteAdmin. В Description тект, который отобразиться в списке <i>Script Plugins</i> в <i> SiteAdmin</i>, в module имя файла с описанием модуля расширения.</li>
<li><b>DispatcherModule.xml</b> &#8211; здесь задается ссылка на модуль ASP.NET и его зависимости.</li>
<li><b>Dispatcher.js</b> является конструктором окон расширения, создаваемых на базе <i>MochaUI</i>.</li>
<li><b>DispatcherContent.aspx</b> &#8211; собственно страница, которая отображается в окне расширения и реализует необходимую логику.</li>
</ul>
<p>Обратите внимание, что имена файлов ваших расширения могут отличатся от указанных здесь. В частности, вместо Dispatcher можно использовать любое другое имя.</p>
<p>В <i>Dispatcher.js</i> должно быть реализовано, как минимум, следующее:</p>
<ul>
<li>Конструктор окна <i>Franson.DispatcherWindow</i>, который создает окно и задает все его необходимые параметры и атрибуты;</li>
<li>А также необходимо подписаться на получение сообщения инициализации пользовательского интерфейса с помощью вызова метода <i>Franson.Event.subscribe</i>.</li>
</ul>
<p>Сама логика расширения реализуется обычным для ASP.NET способом.</p>
<p>После того, как расширение готово для использования/тестирования, необходимо выполнить следующие лействия:</p>
<ul>
<li> Поместить файлы в папку <i>%HOME_DIR%\IIS\Resources\ScriptPlugins\%SITE%\%NAME%</i>, где <i>%HOME_DIR%</i> &#8211; папка, куда установлен GpsGate Server, <i>%SITE%</i> &#8211; название вашего сайта или фирмы или еще что-то (например, com.mysite), <i>%NAME%</i> &#8211; название вашего расширения.</li>
<li>Зайти в <i>SiteAdmin</i> и перейти на закладку <i>Script Plugins</i>.</li>
<li>Надавить кнопку <i>Refresh Script Plugins</i>.</li>
<li>Выбрать в списке рядом с кнопкой расширение.</li>
<li>Поставить галочку рядом с расширением ниже и надавить кнопку Save.</li>
</ul>
<p>Для того, чтобы воспользоваться расширением необходимо зайти (пример для <i>VehicleTracker</i>) в <i>VehicleTracker</i>, в меню должен появиться пункт <i>Windows</i>, если его не было ранее, и в выпадающем меню будет находится пункт для окрытия расширения.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=109</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Установка модуля DBD::Pg</title>
		<link>http://blog.welab.ru/?p=106</link>
		<comments>http://blog.welab.ru/?p=106#comments</comments>
		<pubDate>Mon, 14 Dec 2009 17:09:23 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[Разработка]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=106</guid>
		<description><![CDATA[При установке данного модуля столкнулся с такой проблемой. При запуске приложений, которые используют данный модуль, вылетала ошибка вроде такой &#171;&#8230;DBD::Pg: libpq.so.4: cannot open shared object file: No such file or directory&#8230;&#187;, хотя установка прошла нормально. На различных форумах было множество предположений &#8211; нехватка прав, переустановить, перезагрузить компьютер, &#8230; Положение спасло только курение readme файла.Проблема на [...]]]></description>
			<content:encoded><![CDATA[<p>При установке данного модуля столкнулся с такой проблемой. При запуске приложений, которые используют данный модуль, вылетала ошибка вроде такой &laquo;&#8230;DBD::Pg: libpq.so.4: cannot open shared object file: No such file or directory&#8230;&raquo;, хотя установка прошла нормально. На различных форумах было множество предположений &#8211; нехватка прав, переустановить, перезагрузить компьютер, &#8230; Положение спасло только курение readme файла.<span id="more-106"></span>Проблема на самом деле крылась в том, что не прописаны пути к библиотеке PostgreSQL и решалась эта проблема следующим образом.</p>
<ol>
<li>Прописать путь к директории содержащей библиотеку libpq.so в /etc/ld.so.conf</li>
<li>Запустить /sbin/ldconfig</li>
</ol>
<p>А вот выдержка из самого readme. Кстати, в последних версиях модуля в readme я уже не нашел данного текста.</p>
<blockquote>
<p style="text-align: left">DBD::Pg uses the libpq library that comes with Postgres. If the shared libpq<br />
library is not available, DBD::Pg will error with a message that<br />
usually mentions a file names libpq.so, like this:</p>
<p style="text-align: left">&nbsp;&nbsp;&nbsp;&nbsp;Can&#8217;t load &#8216;./blib/arch/auto/DBD/Pg/Pg.so&#8217; for module DBD::Pg: libpq.so.5: cannot open<br />
&nbsp;&nbsp;&nbsp;&nbsp;shared object file: No such file or directory at &#8230;/DynaLoader.pm line 230.</p>
<p style="text-align: left">This means that the libraries are not installed in a place where the system<br />
can find them when it tries to load the Pg.so file. On some systems, you<br />
can run /sbin/ldconfig -v to see a list of shared modules, or just search<br />
the system for the file with &laquo;locate libpq.so&raquo;. If it exists but is not being<br />
loaded, you may need to add the directory it is in to /etc/ld.so.conf file<br />
and run the ldconfig command. Otherwise, you may need to add the path to<br />
the environment variable LD_LIBRARY_PATH.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=106</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интеграция устройств в GpsGate Server: сохранение данных устройства</title>
		<link>http://blog.welab.ru/?p=103</link>
		<comments>http://blog.welab.ru/?p=103#comments</comments>
		<pubDate>Thu, 03 Dec 2009 14:31:55 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Native device integration]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=103</guid>
		<description><![CDATA[Добрался наконец-то до темы сохранения данных, поступающих от устройства, в GpsGate Server. Собственно писать-то много и не нужно, так все делается достаточно просто, если использовать стандартные таблицы сервера.Данные в GpsGate разделяются на 2 категории &#8211; навигационные и статусы. Навигационные данные отражают положение устройства, скорость движения, направление движения, время регистрации положения. Статусы же отражают состояние самого [...]]]></description>
			<content:encoded><![CDATA[<p>Добрался наконец-то до темы сохранения данных, поступающих от устройства, в GpsGate Server. Собственно писать-то много и не нужно, так все делается достаточно просто, если использовать стандартные таблицы сервера.<span id="more-103"></span>Данные в GpsGate разделяются на 2 категории &#8211; навигационные и статусы. Навигационные данные отражают положение устройства, скорость движения, направление движения, время регистрации положения. Статусы же отражают состояние самого устройства и дополнительные параметры &#8211; заряд батареи, кнопка &laquo;SOS&raquo;, уровень топлива и т.п.</p>
<p>Для сохранения всех этих данных достаточно вызвать один метод <em>ToGpsGate</em>, которая является членом класса <em>Protocol</em>. Для передачи значений используются два параметра типа <em>TrackPoint</em> и <em>Dictionary&lt;string, object&gt;</em> &#8211; навигационные данные и статусы соответственно. Стоит заметить, что есть перегруженные версии этого метода, но данный вариант наиболее удобен на мой взгляд.</p>
<p>Приведу пример добавления навигационных данных и статусов SOS, FuelLevel.</p>
<p><code>TrackPoint point = new TrackPoint(<br />
                        new Position(m_longitude, m_latitude, m_altitude),<br />
                        new Velocity(m_speed, m_headingCourse),<br />
                        m_timestamp);</p>
<p>Dictionary&lt;string, object&gt; statuses = new Dictionary&lt;string, object&gt;();<br />
statuses.Add("SOS", new Boolean(false));<br />
statuse.Add("FuelLevel", new Double(100));</p>
<p>ToGpsGate((point, statuses);</code></p>
<p>Ничего сложного. <img src='http://blog.welab.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=103</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интеграция устройств в GpsGate Server: подводные камни</title>
		<link>http://blog.welab.ru/?p=100</link>
		<comments>http://blog.welab.ru/?p=100#comments</comments>
		<pubDate>Fri, 27 Nov 2009 06:26:03 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Native device integration]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=100</guid>
		<description><![CDATA[При разработке плагина столкнулся с проблемой того, что в SiteAdmin плагин отображается, запускается и работает корректно, но при остановке плагина происходит ошибка. GpsGate Server сообщает (в логах), что не может найти протокол. Также в VehicleTracker не отображается Device mapper. Все условия, вроде бы, выполнены &#8211; свойства ProtocolID и StringID соответствующих классов возвращают одинаковые значения.После дня [...]]]></description>
			<content:encoded><![CDATA[<p>При разработке плагина столкнулся с проблемой того, что в SiteAdmin плагин отображается, запускается и работает корректно, но при остановке плагина происходит ошибка. GpsGate Server сообщает (в логах), что не может найти протокол. Также в VehicleTracker не отображается Device mapper. Все условия, вроде бы, выполнены &#8211; свойства <em>ProtocolID</em> и <em>StringID</em> соответствующих классов возвращают одинаковые значения.<span id="more-100"></span>После дня трехэтажного мата и кучи выдернутых волос простое решение нашлось в примере MyDevice. Все же сложно создавать плагины для чужих систем при недостаточной информационной базе.</p>
<p>Решение достаточно простое, необходимо регистрировать протокол каждый раз, когда вызывается метод <em>OnStart()</em> класс-наследника <em>NmeaListener</em>. Пример ниже.</p>
<p><code>protected override void OnStart()<br />
{<br />
    // Install the protocol<br />
    MyProtocol proto = new MyProtocol(null);<br />
    proto.InstallProtocol();<br />
    .  .  .<br />
}</code></p>
<p>Всего лишь эти две строчки решают кучу проблем. Не наступайте на чужие грабли, надеюсь кому-нибудь пригодится. <img src='http://blog.welab.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=100</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интеграция устройств в GpsGate Server: версия и установка плагина</title>
		<link>http://blog.welab.ru/?p=89</link>
		<comments>http://blog.welab.ru/?p=89#comments</comments>
		<pubDate>Wed, 25 Nov 2009 10:22:41 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[Native device integration]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=89</guid>
		<description><![CDATA[Установка плагина и его версия имеют некоторые особенности, о которых я хотел бы упомянуть. Установка Первая установка плагина в систему не вызывается, каких-либо затруднений, так как GpsGate Server еще не загрузил его и не заблокировал к нему доступ. Чтобы выполнить обновление плагина, необходимо выполнить следующие действия: Зайти в SiteAdmin; Остановить сервис Nmea Service &#8211; кнопка [...]]]></description>
			<content:encoded><![CDATA[<p>Установка плагина и его версия имеют некоторые особенности, о которых я хотел бы упомянуть.<span id="more-89"></span></p>
<h3>Установка</h3>
<p>Первая установка плагина в систему не вызывается, каких-либо затруднений, так как GpsGate Server еще не загрузил его и не заблокировал к нему доступ. Чтобы выполнить обновление плагина, необходимо выполнить следующие действия:</p>
<ol>
<li>Зайти в SiteAdmin;</li>
<li>Остановить сервис Nmea Service &#8211; кнопка &laquo;Stop&raquo; на вкладке &laquo;NMEA Service&raquo;;</li>
<li>Завершить работу с SiteAdmin;</li>
<li>Выполнить команду <strong>iisreset /stop</strong> в консоли (Win+R);</li>
<li>Скопировать плагин (dll) в папку <em>&laquo;%APP_ROOT%\Franson NMEA Service&raquo;</em>;</li>
<li>Скопировать плагин (dll) в папку <em>&laquo;%APP_ROOT%\IIS\bin&raquo;</em>;</li>
<li>Выполнить команду <strong>iisreset /start</strong> в консоли;</li>
<li>Зайти в SiteAdmin;</li>
<li>Запустить сервис Nmea Service &#8211; кнопка &laquo;Start&raquo; на вкладке &laquo;NMEA Service&raquo;;</li>
<li>Обновить страницу, чтобы получить список загруженных плагинов.</li>
</ol>
<p>В данном случае <em>%APP_ROOT%</em> обозначает папку, в которую был установлен сервер GpsGate Server. По умолчанию это папка <em>C:\Inetpub\wwwroot\GpsGateServer</em>.</p>
<h3>Версии</h3>
<p>Ребята из техподдержки рекомендуют вести версии плагинов, но с версиями связана следующая особенность &#8211; сервер обновит информацию о плагине в БД в том случае, если версия найденного плагина старше версии в БД. В частности, это касается набора полей и команд устройства.</p>
<p>Так, если у в плагине версии 1.0.0.0 было только одно поле &laquo;SOS&raquo;, а в последствии добавили еще одно поле &laquo;Battery Low&raquo;, то это поле добавится в БД и, соответственно, в приложения (например, VehicleTracker) только, если версия плагина сменится на более старшую (например, на 1.0.0.1).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=89</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интеграция устройств в GpsGate Server: структура плагина</title>
		<link>http://blog.welab.ru/?p=84</link>
		<comments>http://blog.welab.ru/?p=84#comments</comments>
		<pubDate>Mon, 23 Nov 2009 10:37:13 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Native device integration]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=84</guid>
		<description><![CDATA[Изучив несколько примеров проектов плагинов, выделил базовую структуру, которая должна быть во всех плагинах. Плагин основывается на классах-наследниках от следующих базовых классов: GpsGate.Online.Directory.DeviceDefinition, GpsGate.Online.Net.Protocol, GpsGate.Online.Net.NmeaListener или других *Listener (зависит от требований к проекту), GpsGate.Online.Net.NmeaConnection или других *Connection.Опишу поподробнее эти классы, чтобы было понятно, для чего они нужны. Класс-наследник GpsGate.Online.Directory.DeviceDefinition нужен для описания базовых свойств и [...]]]></description>
			<content:encoded><![CDATA[<p>Изучив несколько примеров проектов плагинов, выделил базовую структуру, которая должна быть во всех плагинах. Плагин основывается на классах-наследниках от следующих базовых классов: <em>GpsGate.Online.Directory.DeviceDefinition</em>, <em>GpsGate.Online.Net.Protocol</em>, <em>GpsGate.Online.Net.NmeaListener</em> или других <em>*Listener</em> (зависит от требований к проекту), <em>GpsGate.Online.Net.NmeaConnection</em> или других <em>*Connection</em>.<span id="more-84"></span>Опишу поподробнее эти классы, чтобы было понятно, для чего они нужны.</p>
<p>Класс-наследник <em>GpsGate.Online.Directory.DeviceDefinition</em> нужен для описания базовых свойств и характеристик устройства. Для этого переопределяются следующие методы и свойства:</p>
<ul>
<li>Свойство <em>Name </em>возвращает название устройства<em>.</em></li>
<li>Свойство <em>Description</em> возвращает полное описание устройства.</li>
<li>Свойство <em>NamespaceName</em> возвращает имя пространства имен, в котором размещены остальные классы плагина.</li>
<li>Метод <em>InstallMessageFields</em> должен вернуть список названий полей, которые поддерживает устройство.</li>
<li>Метод <em>InstallDefaultMapperEntryFor </em>позволяет задать привязку полей устройства к полям сервера. Например, если в устройстве есть поле <em>SOS</em>, то его можно связать с одноименным полем <em>SOS</em> на сервере.</li>
<li>Метод <em>RegisterCommad</em> возвращает набор команд, которые могут быть отправлены устройству. Да-да, именно <em>Commad</em>, видимо, разработчики допустили небольшую ошибочку но исправлять уже поздно.</li>
</ul>
<p>Класс-наследник <em>GpsGate.Online.Net.Protocol</em> реализует протокол устройства. В частности это реализуется парой методов <em>TranslateFromDevice</em>, которые получают данные, поступающие с устройства, и обрабатывают их. Также в данном классе необходимо переопределить свойство <em>StringID</em>, чтобы оно возвращало символьное название протокола.</p>
<p>Классы-наследники <em>GpsGate.Online.Net.*Listener</em> и <em>GpsGate.Online.Net.*Connection</em> предназначены для реализации связи с устройством. Например, если устройство общается с сервером по протоколу UDP, то создаются два класса наследника от <em>UdpNmeaListener</em> и <em>UdpNmeaConnection</em>.</p>
<p>Класс-наследник <em>*Listener</em> выступает в качестве слушателя порта и т.п., т.е. он устанавливает соединения с устройством. В данном классе необходимо переопределить по необходимости методы <em>OnStart</em>, <em>OnStop</em>, <em>Install</em> и метод <em>CreateUdpConnection</em>, который создаст соединение с использованием вашего класса-наследника от <em>UdpNmeaConnection</em>. Также в данном классе необходимо переопределить свойство <em>ProtocolID</em>, чтобы оно возвращало символьное название протокола.</p>
<p><em>Крайне важно, чтобы свойства <strong>StringID</strong> класса-наследника <strong>GpsGate.Online.Net.Protocol</strong> свойство <strong>ProtocolID</strong> класса-наследника </em><em><strong>GpsGate.Online.Net.*Listene</strong>r возвращали одинаковые значения, иначе Вы не увидите ваш плагин в VehicleTracker. Обратите на это внимание, потому что, я при разработке плагина потратил очень много времени, чтобы разобраться с этой проблемой. Решение было найдено при переписке со службой техподдержки и на данный момент об этом нигде в документации не сказано.</em></p>
<p>Класс-наследник <em>*Connection</em> реализует соединение с устройством и должен переопределить метод <em>CreateProtocol</em>, который должен создавать для обработки данных ваш класс-наследник <em>GpsGate.Online.Net.Protocol</em>.</p>
<p>В плагине может быть реализовано несколько различных соединений, например, по SMS и TCP/IP.</p>
<p>Также в плагине доступен глобальный объект NLog для логгирования. Его Вы можете получить с помощью такой конструкции:</p>
<p><code>private static Logger m_nlog = LogManager.GetCurrentClassLogger();</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=84</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интеграция устройств в GpsGate Server: подготовка</title>
		<link>http://blog.welab.ru/?p=80</link>
		<comments>http://blog.welab.ru/?p=80#comments</comments>
		<pubDate>Fri, 20 Nov 2009 10:00:05 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[GpsGate Server]]></category>
		<category><![CDATA[Native device integration]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=80</guid>
		<description><![CDATA[Данным постом хочу открыть тему по интеграции новых устройств в GpsGate Server, а также поделиться тем, что изначально удалось найти и узнать про интеграцию устройств.Первым делом, заглянув на форум в топик об интеграции, узнал, что существует три варианта интеграции устройств: Реализовать протокол GpsGate Protocol в самом устройстве. Данный вариант достаточно сложный и подразумевает реализацию протокола [...]]]></description>
			<content:encoded><![CDATA[<p>Данным постом хочу открыть тему по интеграции новых устройств в GpsGate Server, а также поделиться тем, что изначально удалось найти и узнать про интеграцию устройств.<span id="more-80"></span>Первым делом, заглянув на форум в <a href="http://franson.com/forum/topic.asp?TOPIC_ID=10172" target="_blank">топик об интеграции</a>, узнал, что существует три варианта интеграции устройств:</p>
<ul>
<li>Реализовать протокол GpsGate Protocol в самом устройстве. Данный вариант достаточно сложный и подразумевает реализацию протокола в самом устройстве. Также, данный вариант привязывает устройство к GpsGate Server, если только не реализовать в самом устройстве поддержку нескольких протоколов. В общем, не подходит.</li>
<li>Реализовать proxy-сервер, который будет получать данные от устройства и преобразовывать их в совместимые с протоколом GpsGate Server и наоброт &#8211; от сервера к устройству. Этот вариант, также слишком громоздкий и хорош в том случае, когда нет доступа к устройству.</li>
<li>Реализовать плагин для GpsGate Server, который будет отвечать за получени данных от устройства и передачу данных и команд устройству, т.е., по сути, плагин реализует протокол устройства. Этот вариант наиболее предпочтительный</li>
</ul>
<p>Почитав темы форума, натолкнулся на документацию по разработке и самому серверу <a href="http://franson.com/gpsgateserver/guide.asp">здесь</a>. Из документации ясно видно, что сервер разработан на .NET, и плагин, соответственно, тоже необходимо писать на .NET. К сожалению, документация не блещет примерами и многословием, так что придется мучить службу поддержки при возникновении вопросов.</p>
<p>Также на форуме можно найти ссылки на несколько примеров проектов плагинов на C#, например, <a href="http://franson.com/gpsgateserver/samples/MyDevice.zip">MyDevice</a> &#8211; базовый пример, <a href="http://franson.com/gpsgateserver/Samples/GpsGate.Axonn.File.Source.zip">Axxon</a>, <a href="http://franson.com/gpsgateserver/Samples/GpsGate.TrendTek.Source.zip">TrendTek</a>. Примеры, опять же к сожалению, тоже не блещут многословием и достаточной описательностью, но суть плагина понять можно.</p>
<p>Еще несколько полезных ссылок про разработку и отладку плагинов &#8211; <a href="http://franson.com/forum/topic.asp?TOPIC_ID=8536">Какие логи сервера и где читать</a>, <a href="http://franson.com/forum/topic.asp?TOPIC_ID=10740">Терминал</a>, <a href="http://franson.com/forum/topic.asp?TOPIC_ID=8105">Отладка плагина в Visual Studio</a>.</p>
<p>Думаю, этого для начало разработки достаточно.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=80</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поддержка сессий при выполнении Ajax-запросов к Tomcat</title>
		<link>http://blog.welab.ru/?p=75</link>
		<comments>http://blog.welab.ru/?p=75#comments</comments>
		<pubDate>Fri, 20 Nov 2009 06:39:18 +0000</pubDate>
		<dc:creator>Андрей Башкатов</dc:creator>
				<category><![CDATA[История одного проекта]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://blog.welab.ru/?p=75</guid>
		<description><![CDATA[В предыдущем посте было рассказано, как выполнять межсерверные запросы Ajax, в частности к Tomcat. Для этого использовался небольшой скриптик на PHP, который перенаправлял запрос на удаленный сервер, получал и возвращал ответ. Настало время его немного доработать в связи с тем, что он не поддерживает сессии, т.е. каждый Ajax-запрос Tomcat воспринимает как совершенно новое соединение.На самом [...]]]></description>
			<content:encoded><![CDATA[<p>В предыдущем посте было рассказано, как выполнять межсерверные запросы Ajax, в частности к Tomcat. Для этого использовался небольшой скриптик на PHP, который перенаправлял запрос на удаленный сервер, получал и возвращал ответ. Настало время его немного доработать в связи с тем, что он не поддерживает сессии, т.е. каждый Ajax-запрос Tomcat воспринимает как совершенно новое соединение.<span id="more-75"></span>На самом деле поддержка сессий реализуется достаточно просто. Все необходимое для поддержки сессий передается в заголовках HTTP-запросов/ответов.</p>
<p>Так, когда мы посылаем запрос Tomcat, он его обрабатывает и возвращает ответ, в котором присутствует заголовок типа <em>Set-Cookie: Path=/; JSESSIONID=xxx</em>, где <em>xxx</em><strong> </strong>- идентификатор сессии.</p>
<p>Чтобы все последующие запросы относились к данной сессии, необходимо передавать полученный идентификатор сессии в заголовке запроса. Сделать это можно с помощью заголовка Cookie. К запросу добавляется пара заголовков <em>Cookie: Path=/</em> и <em>Cookie: JSESSIONID=xxx</em>.</p>
<p>Т.е. алгоритм поддержки сессий следующий:</p>
<ul>
<li>При получении ответа от сервера, проверяем, есть ли там идентификатор сессии?</li>
<li>Сохраняем идентификатор сессии, например, в переменной <em>$_SESSION['SERVER_SESSION_ID']</em>.</li>
<li>При выполнении последующих запросов к этому серверу, добавляем заголовок с идентификатором сессии.</li>
</ul>
<p>Легко и просто. <img src='http://blog.welab.ru/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.welab.ru/?feed=rss2&amp;p=75</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
