ПРИМЕНЕНИЕ СОБЫТИЙНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ В СЕТЕВЫХ ПРИЛОЖЕНИЯХ - Студенческий научный форум

VII Международная студенческая научная конференция Студенческий научный форум - 2015

ПРИМЕНЕНИЕ СОБЫТИЙНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ В СЕТЕВЫХ ПРИЛОЖЕНИЯХ

Ерофеевский В.В. 1, Самсонова С.А. 1
1Филиал ФГАОУ ВПО «Северный (Арктический) федеральный университет имени М.В. Ломоносова» в г. Коряжме Архангельской области
 Комментарии
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

 

Быстрое расширение доступности Интернета в XXI веке привело повышенным требованиям, которые предъявляются к программным продуктам и системам, обслуживающим сетевые сервисы и пользователей этих сервисов. Самые главные требования − это скорость и безотказность работы. Одной из главнейших концепций, позволяющей создавать надежные и устойчивые к нагрузкам системы, является парадигма событийно-ориентированного программирования. Согласно данной парадигме программа рассматривается как набор объектов, реагирующий на события. Под событиями понимаются действия пользователей, внутренние вызовы самой программы, сигналы системы и других программ. Большое распространение парадигма событийно-ориентированного программирования приобрела в графических интерфейсах − например, Qt. Однако идеи, лежащие в ее основе, использовались значительно раньше. В частности ядро операционной системы Unix имеет событийную архитектуру.

Дальнейшее развитие концепция получила в создании серверных приложений. Многие современные лидирующие веб-серверы и прокси-серверы, такие как nginx, Node.js, Squid, используют событийную модель.

Наша дипломная работа посвящена событийно-ориентированной модели программирования. Цель работы − создание стабильного клиент-серверного приложения на основе событийной архитектуры.

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

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

Часть работы посвящена каркасу программной системы Twisted, который облегчает создание сетевых программ на событийно модели. Рассмотрены некоторые из его исходных кодов, показаны принципы его работы на низком уровне. На основе проведенных исследований разработана программа для учета расходных материалов принтеров. Данная программа упрощает документооборот в учебном заведении и позволяет вести учет расходных материалов, прогнозировать уровень потребностей.

Формулировка задачи.

В высшем учебном заведении приходится постоянно пользоваться принтерами для распечатки различных документов, работ и многого другого. Как правило, большинство принтеров являются лазерными. Довольно дорогим расходным материалом для принтера является картридж. В филиале САФУ в г. Коряжме за своевременную смену картриджей обычно отвечает системный администратор. Запрос на смену направляется в виде заявления директору. Необходимо автоматизировать данный процесс, чтобы системный администратор вовремя получал сообщения о необходимости в замене картриджей. Также дополнительной функцией программы будет формулирование текста заявления и возможность его распечатывания.

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

Серверная часть программы.

Вышеизложенная задача легко реализуется в рамках клиент-серверных приложений. Общая схема программы представлена на рисунке 1. Сервер в данном случае будет программой-посредником между базой данных и клиентом. Поскольку клиентов может быть одновременно несколько, в том числе администратор системы, то необходимо, чтобы сервер умел принимать несколько соединений. Мы это сделаем с помощью событийно-ориентированного программирования. Сервер будет работать асинхронно, для чего воспользуемся каркасом Twisted, который возьмет на себя работу на низком (сокетном) уровне.

Так как высоких нагрузок на базу данных не будет, то понадобится простая и не ресурсоёмкая реляционная база данных. Под эти требования полностью подходит база данных SQLite. SQLite − встраиваемая база данных. Всю информацию она хранит в одном файле, который располагается на том же компьютере, на котором работает программа. Обмен данными с программой осуществляется с помощью API функций SQLite. Тем не менее, у нее есть один существенный недостаток. SQLite, исполняя транзакции, блокирует файл, хранящий базу данных. В рамках асинхронной модели нас это не устраивает. Чтобы обойти данную проблему, воспользуемся нестандартными API для доступа к SQlite, которые реализованы в модуле sqlite3, a API функциями фреймворка Twisted. Модуль для работы с базами данных в асинхронном стиле в Twisted называется adbapi. Он является частью модуля twisted.enterprise. Таким образом, доступ к базе данных в коде сервера будет выглядеть следующим образом:

from twisted.enterprise import adbapi

filename = "database.db"

dbpool = adbapi.ConnectionPool("sqlite3", filename)

Запросы передаются через метод runQuery.

dbpool.runQuery("SQL запрос");

Запрос к базе данных использует синтаксис SQL. Так, например, выглядит создание таблицы с именами пользователей.

sql = u"""

CREATE TABLE IF NOT EXISTS person(

id_person INTEGER PRIMARY KEY AUTOINCREMENT,

firstname,

surname,

patronymic

); """

Здесь поле id_person является целочисленным первичным ключом. Остальные поля соответственно отвечают за имя, фамилию и отчество.

Между клиентом и сервером должно быть организована передача данных. Чтобы «общение» происходило правильно, необходим протокол, средствами которого будем осуществляться вызов функций обратного вызова Twisted на сервере. В качестве такого протокола будем использовать XML-RPC. Этот протокол использует язык XML для кодирования сообщений через протокол передачи данных HTTP. Например, ответ сервера мог бы выглядеть так:

Некоторый текст

Чтобы сервер мог отвечать на XML-RPC запросы, создадим класс, который будет наследником стандартного класса Twisted twisted.web.xmlrpc.XMLRPC. Тогда функция в данном классе для получения списка всех картриджей будет выглядеть следующим образом:

from twisted.web import xmlrpc

class XmlRPCExample(xmlrpc.XMLRPC):

def xmlrpc_get_printers(self):

def get_prnt():

return dbpool.runQuery("SELECT %s FROM %s" % ("*","printer"))

return get_prnt()

Чтобы запустить сервер, который будет обрабатывать все функции из класса, остается запустить цикл реактор.

from twisted.web import server

from twisted.internet import reactor

port = 7788

r = XmlrpcHandler()

reactor.listenTCP(port, server.Site(r))

reactor.run()

В данном случае цикл будет прослушивать все соединения на порту 7788.

Клиентская часть программы

Главное видимое отличие клиентской программы от серверной − наличие графического интерфейса пользователя (GUI). Чтобы нарисовать графический интерфейс пользователя на экране, понадобятся специальные библиотеки. Среди множества продуктов остановимся на библиотеке Qt. Её основные достоинства: кроссплатформенность, бесплатность и подробная документация. Qt в исходном виде предназначена для работы с языком программирования C++. Поскольку мы используем Python, то воспользуемся фрейморком PyQt, который позволяет работать с Qt на Python. PyQt − это расширение Python. Например, чтобы работать с классами QtCore и QtGui нужно им импортировать.

from PyQt4 import QtCore, QtGui

Интерфейс можно создать как вручную, так и с помощью программы Qt Designer. В этой программе создается форма, которая будет основой графического интерфейса. Затем форма преобразуется в код языка Питон с помощью программы pyuic4 командой: pyuic4 form.ui -o pythoncode.py.

Так же как и в серверной части, в клиентской программе будет использоваться фреймворк Twisted для соединения с сервером. Qt основана на событийно-ориентированном программировании. Следовательно, Qt так же имеет цикл, подобный циклу reactor у Twisted. Чтобы оба цикла работали как один, существует специальный модуль qt4reactor. После его импортирования необходимо запустить функцию install.

import qt4reactor

qt4reactor.install()

Теперь в программе можно работать одновременно и с Twisted и с Qt.

Для создания функций обратного вызова, которые будут направлены на сервер, в Twisted есть класс Proxy. Так, чтобы получить список принтеров, нам надо вызвать функцию get_printers с сервера. Код ее вызова и отображения результата выглядит следующим образом.

from twisted.web.xmlrpc import Proxy

class XmlrpcClient():

def __init__(self):

pass

def con_lost(self, connector, reason):

print ("Failed connection to %s." % connector.getDestination())

connector.connect()

def con_start(self, connector):

print "started connecting"

def connect(self, host, port):

self.proxy = Proxy("%s:%d" % (host, port))

self.proxy.queryFactory.clientConnectionFailed = self.con_lost

self.proxy.queryFactory.startedConnecting = self.con_start

return self.proxy

def remote_call(self, method, *args):

return self.proxy.callRemote(method, *args)

if __name__ == '__main__':

def printValue(value):

print repr(value)

def printError(error):

print 'error', error

from twisted.internet import reactor

host = "http://localhost"

port = 7788

proxy = XmlrpcClient()

proxy = proxy.connect(host, port)

proxy.callRemote('get_printers').addCallbacks(printValue, printError)

reactor.run()

После запуска программы на экран будет выведена надпись started connecting, свидетельствующая о попытке соединения с сервером, и в случае если сервер запущен, будут выведен список из принтеров и их номеров, которые являются первичными ключами в базе данных.

Направив вывод на различные элементы интерфейса, получим функционирующий клиент, который умеет подключаться к базе данных. Снимок экрана с интерфейсом показан на рисунке 2.

Рисунок — Интерфейс программы

К сожалению, интерпретатор Питона установлен далеко не на всех персональных компьютерах. К тому же в программе используются множество различных модулей, которые также пришлось бы устанавливать на каждый компьютер. Чтобы программа запустилась на любой операционной системе семейства Windows, необходим исполняемый файл, который будет запускать интерпретатор Питона и все необходимые модули. Данную процедуру можно выполнить с помощью модуля cx_Freeze. Чтобы создать описанный выше исполняемый файл в папке с исходным кодом программы, создадим файл setup.py со следующим содержимым.

import sys

from cx_Freeze import setup, Executable

base = None

if sys.platform == "win32":

base = "Win32GUI"

setup(

name = "main",

version = "0.1",

description = "Sample cx_Freeze PyQt4 script",

executables = [Executable("programma.py", base = base)])

Запустим данный код. После его исполнения в папке build будет находиться программа в виде исполняемого файла exe со всеми необходимыми модулями. Таким образом, мы добились работы программы на любом компьютере с установленной операционной системой Windows.

Список литературы

  1. Прохоренок Н.А. Python 3 и PyQt. Разработка приложений — СПб.: БХВ—Петербург, 2012. − 704 с.: ил.

  2. Стивенс У.Р., Феннер Б., Рудофф Э.М. Unix: разработка сетевых приложений. 3-е изд. — СПБ.: Питер, 2007. − 1039 с.: ил.

  3. Хоп, Грегор, Вульф, Бобби. Шаблоны интеграции корпоративных приложений.: Пер. с англ. — М.: OOO “И.Д. Вильямс”, 2007. − 672 с.

  4. Jessica McKellar and Abe Fettig Twisted Network Programming Essentials, Second Edition.: O’Relly, 2013. − 193 c.

  5. Паттерн Singleton (Одиночка) [Электронный ресурс]; URL: http://rsdn.ru/article/patterns/singleton.xml (Дата обращения 15.03.14)

  6. Методы и технологии реинжиниринга ИС [Электронный ресурс]; URL: http://citforum.ru/SE/project/isr/ (Дата обращения 14.03.14)

  7. Психология автоматного программирования [Электронный ресурс]; URL: http://softcraft.ru/design/ap/ap01.shtml (Дата обращения 14.03.14)

  8. Event Collaboration [Электронный ресурс]; URL: http://citforum.ru/SE/project/isr/ (Дата обращения 17.03.14)

  9. Developer Guides [Электронный ресурс]; URL: http://twistedmatrix.com/documents/current/core/howto/index.html (Дата обращения 20.03.14)

  10. Using Qt Designer [Электронный ресурс]; URL: http://pyqt.sourceforge.net/Docs/PyQt4/designer.html (Дата обращения 21.03.14)

1

Просмотров работы: 1452