Перейти к содержимому

Как называется отправка сообщений в программировании

  • автор:

Действия обмена сообщениями

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

Шаблоны обмена сообщениями

Существует три основных шаблона обмена сообщениями.

  • Датаграмма — при использовании mep датаграммы клиент отправляет сообщение службе, но служба не отвечает. Такой метод иногда называют «отправить и забыть». В этом случае требуется внешнее подтверждение успешной доставки. Сообщение может быть потеряно при передаче и может не достичь службы. Если клиент успешно отправил сообщение, это не гарантирует, что удаленная служба получила его. Датаграмма — это фундаментальный элемент обмена сообщениями, на основе которого можно строить собственные шаблоны обмена сообщениями.
  • Запрос-ответ . При использовании запроса-ответа meP клиент отправляет сообщение службе, служба выполняет необходимую обработку, а затем отправляет ответ обратно клиенту. Шаблон состоит из пар «запрос-ответ». Примерами вызовов «запрос-ответ» являются удаленные вызовы процедур (RPC) и запросы GET браузера. Этот шаблон также называют полудуплексным.
  • Дуплексный . При использовании дуплексного meP клиент и служба могут отправлять сообщения друг другу в любом порядке. Применение дуплексного шаблона похоже на разговор по телефону, когда каждое произносимое слово является сообщением.

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

Действия обмена сообщениями

В платформа .NET Framework 4.6.1 определяются следующие действия обмена сообщениями:

  • Send — следует использовать Send для отправки сообщения.
  • SendReply — следует использовать действие SendReplyдля отправки ответа на полученное сообщение. Это действие используется службами рабочего процесса при реализации шаблона обмена сообщениями «запрос-ответ».
  • Receive — следует использовать действие Receive для получения сообщения.
  • ReceiveReply — следует использовать действие ReceiveReply для получения ответного сообщения. Это действие используется клиентами службы рабочего процесса при реализации шаблона обмена сообщениями «запрос-ответ».

Действия обмена сообщениями и шаблоны обмена сообщениями

В шаблоне обмена сообщениями «датаграмма» участвуют клиент, отправляющий сообщение, и служба, получающая его. Если клиент — это рабочий процесс, то следует использовать действие Send для отправки сообщения. Для получения этого сообщения в рабочем процессе следует использовать действие Receive. Действия Send и Receive имеют свойство с именем Content . Это свойство содержит отправляемые или получаемые данные. При реализации шаблона обмена сообщениями «запрос-ответ» клиент и службы используют пары действий. Клиент использует действие Send для отправки сообщения и действие ReceiveReply для получения ответа от службы. Эти два действия связаны друг с другом свойством Request. Значение этого свойства — действие Send, отправившее исходное сообщение. Служба также использует пару связанных действий: Receive и SendReply. Эти два действия связаны свойством Request. Значение этого свойства — действие Receive, получившее исходное сообщение. Действия ReceiveReply и SendReply, как и действия Send и Receive, позволяют отправить экземпляр Message или тип контракта сообщения.

Поскольку рабочие процессы выполняются в течении долгого времени, очень важно, чтобы шаблон обмена сообщениями «дуплекс» также поддерживал долговременные диалоги. Для поддержки долговременных диалогов клиенты, инициирующие диалоги, должны предоставлять службу с возможностью ее повторного вызова позднее, когда данные станут доступны. Например, заказ на покупку подается на одобрение менеджера, но он может быть обработан спустя день, неделю или даже год; рабочий процесс, управляющий заказом на покупку должен иметь возможность продолжить работу с ним после получения одобрения. Шаблон обмена сообщениями «дуплекс» поддерживается в рабочих процессах, использующих корреляцию. Для реализации шаблона «дуплекс» следует использовать действия Send и Receive. В действии инициализируйте Receive корреляцию с помощью CorrelationHandle. В действии Send задайте дескриптор взаимосвязи как значение свойства CorrelatesWith. Дополнительные сведения см. в разделе Устойчивый дуплекс.

Реализация дуплексного формата рабочего процесса с использованием корреляции обратного вызова («Устойчивый дуплекс») предназначена для длительных бесед. Это не то же самое, что «дуплекс» WCF с контрактами обратного вызова, в которых диалоги являются кратковременными (на время существования канала).

Действия по форматированию сообщений и обмену сообщениями

Действия Receive и ReceiveReply имеют свойство с именем Content . Это свойство имеет тип ReceiveContent и представляет данные, получаемые действием Receive или ReceiveReply. В платформе .NET Framework определены два связанных класса с именами ReceiveMessageContent и ReceiveParametersContent, которые являются производными от ReceiveContent. Задайте для свойства Receive действия ReceiveReply или Content значение экземпляра одного из этих типов для получения данных в службе рабочего процесса. Используемые типы зависят от типа данных, получаемых действием. Если действие получает объект Message или тип контракта сообщения, следует использовать ReceiveMessageContent. Если действие получает контракт набора данных или типы XML, которые могут быть сериализованы, используйте ReceiveParametersContent. ReceiveParametersContent позволяет отправлять несколько параметров, ReceiveMessageContent позволяет отправлять только один объект — сообщение (или тип контракта сообщения).

ReceiveMessageContent также можно использовать с одним контрактом данных или типом XML, который может быть сериализован. Разница между использованием класса ReceiveParametersContent с одним параметром и передачей объекта напрямую классу ReceiveMessageContent заключается в формате сообщений. Содержимое параметра упаковывается в элемент XML, соответствующий имени операции, а сериализуемый объект упаковывается в элемент XML с использованием имени параметра (например, Hello, World ). Содержимое сообщения не упаковывается в имя операции. Вместо этого сериализуемый объект размещается в элементе XML с использованием полного имени типа XML (например, Hello, World ).

Действия Send и SendReply также имеют свойство с именем Content . Это свойство имеет тип SendContent и представляет данные, отправляемые действием Send или SendReply. В платформе .NET Framework определены два связанных типа с именами SendMessageContent и SendParametersContent, которые являются производными от SendContent. Задайте для свойства Send действия SendReply или Content значение экземпляра одного из этих типов для отправки данных из службы рабочего процесса. Используемые типы зависят от типа данных, отправляемых действием. Если действие отправляет объект Message или тип контракта сообщения, следует использовать SendMessageContent. Если действие отправляет тип контракта, используйте SendParametersContent. SendParametersContent позволяет отправлять несколько параметров, SendMessageContent позволяет отправлять только один объект — сообщение (или тип контракта сообщения).

При императивном программировании действий обмена сообщениями следует использовать универсальные аргументы InArgument и OutArgument для упаковки объектов, назначенных для сообщения или свойств параметров для действий Send, SendReply, Receive и ReceiveReply. Используйте InArgument для Send действий и SendReply и OutArgument для Receive действий и ReceiveReply . С действиями по передаче сообщений используются аргументы In , поскольку в действия передаются данные. С действиями по получению сообщений используются аргументы Out , поскольку данные принимаются от действий, как показано в следующем примере.

Receive reserveSeat = new Receive < . Content = new ReceiveParametersContent < Parameters = < < "ReservationInfo", new OutArgument(reservationInfo) > > > >; SendReply reserveSeat = new SendReply < . Request = reserveSeat, Content = new SendParametersContent < Parameters = < < "ReservationId", new InArgument(reservationId) > > >, >; 

При реализации службы рабочего процесса, определяющей операцию «запрос-ответ», возвращающую пустое значение, необходимо создать экземпляр действия SendReply и задать для свойства Content значение пустого экземпляра одного из типов содержимого (SendMessageContent или SendParametersContent), как это показано в следующем примере.

Receive rcv = new Receive() < ServiceContractName = "IService", OperationName = "NullReturningContract", Content = new ReceiveParametersContent( new Dictionary() < < "message", new OutArgument() > > ) >; SendReply sr = new SendReply() < Request = rcv Content = new SendParametersContent(); >; 

Добавление ссылки на службу

При вызове службы рабочих процессов из приложения рабочего процесса Visual Studio 2012 создает пользовательские действия обмена сообщениями, которые инкапсулируют обычные Send действия и ReceiveReply , используемые в запросе и ответе MEP. Чтобы использовать эту функцию, щелкните правой кнопкой мыши проект клиента в Visual Studio и выберите Добавить>ссылку на службу. Введите базовый адрес службы в поле адреса и щелкните «Перейти». Доступные службы отображаются в поле Службы: . Разверните узел службы для отображения поддерживаемых контрактов. Выберите контракт, который требуется вызвать, и в поле Операции отобразится список доступных операций . Затем можно указать пространство имен для созданного действия и нажать кнопку ОК. Появится диалоговое окно с сообщением, что операция была завершена успешно, а созданные пользовательские действия появятся в области элементов после повторного построения проекта. Для каждой операции, определенной в контракте службы, существует одно действие. После повторного построения проекта пользователь сможет перетаскивать пользовательские действия в рабочий процесс и задавать любые необходимые свойства в окне свойств.

Шаблоны действий обмена сообщениями

Чтобы упростить настройку запроса и ответа mep в клиенте и службе, Visual Studio 2012 предоставляет два шаблона действий обмена сообщениями. System.ServiceModel.Activities.Design.ReceiveAndSendReply используется в службе, а System.ServiceModel.Activities.Design.SendAndReceiveReply используется на клиенте. В обоих случаях шаблоны добавят соответствующие действия обмена сообщениями в рабочий процесс. Для службы шаблон System.ServiceModel.Activities.Design.ReceiveAndSendReply добавит действие Receive, за которым следует действие SendReply. Свойство Request автоматически задается для действия Receive. Для клиента шаблон System.ServiceModel.Activities.Design.SendAndReceiveReply добавит действие Send, за которым следует действие ReceiveReply. Свойство Request автоматически задается для действия Send. Чтобы использовать эти шаблоны, перетащите соответствующий шаблон в рабочий процесс.

Действия и транзакции обмена сообщениями

При вызове службы рабочего процесса может быть полезно выделить для операции службы транзакцию. Чтобы сделать это, поместите действие Receive в действие TransactedReceiveScope. Действие TransactedReceiveScope содержит действие Receive и текст. Транзакция, выделяемая службе, остается внешней в течение выполнения текста TransactedReceiveScope. Транзакция завершает работу, когда заканчивается выполнение основной части. Дополнительные сведения о рабочих процессах и транзакциях см. в разделе Транзакции рабочих процессов.

См. также раздел

  • Отправка и получение ошибок в службах рабочих процессов
  • Создание службы долго выполняющегося рабочего процесса

Упаковка и отправка сообщений

Гейст Бигулин (Geist Beguelin) и его колле г и так описывают модель сооб щ ений PVM-среды:

PVM-демоны и задачи могут формировать и отправлять произвольной длины сообщения, содержащие типизированные данные. Если содержащиеся в сообщениях данные имеют несовместимые форматы, то при передаче между компьютерами их можно преобразовать, используя стандарт XDR1. Сообщения помечаются во время отправки с помощью определенного пользователем целочисленного кода и мотуг быть отобраны для приема посредством адреса источника, или тега. Отправитель сообщения не ожидает от получателя подтверждения приема (квитирования), а продолжает работу сразу после отправки сообщения в сеть. Затем буфер сообщений может быть очищен или вновь использован по назначению. Сообщения буфери-зируются до тех пор, пока не будут приняты получателем. PVM-система надежно доставляет сообщения адресатам, если таковые существуют. При оправке сообщений от каждого отправителя каждому получателю их порядок сохраняется. Это означает, что если отправителем было послано несколько сообщений, они будут получены адресатом в том же порядке, в котором были отправлены.

Библиотека PVM содержит семейство функций, используемых для упаковки данных различных типов в буфер оправки. В это семейство входят функции упаковки, предназначе нн ые для символьных массивов, значений типа double, float, int, long, byte и т.д. Список рллт_рк-функций представлен в табл. 6.3.

Таблица 6.3. Фу н кции упаковки

int pvm_pkbyte(char *cp, int count, int std) ;

Комплексные числа (комплексные числа типа double):

int pvm_pkcplx(float *xp, int count, int std) ; int pvm_pkdcplx(double *zp, int count, int std) ;

Значения типа double:

int pvm_pkdouble(double *dp, int count, int std) ;

‘ XDR (eXternal Data Representation) — стандарт для аппаратно-независимых структур данных, pM’ работанный фирмой Sun Microsystems.

6.3. Базовые механизмы PVM 237

Окончание табл. 6.3

Значения типа f 1 о а t :

int pvm_pkfloat(float *fp, int count, int std); Значения типа int:

int pvm_pkint(int *np, int count, int std) ; Значения типа long.

int pvm_pklong(long *np, int count, int std) ; Значения типа short:

int pvm_pkshort(short *np, int count, int std) ; Строки:

int pvm_pkstr(char *cp) ;

Все функции упаковки, перечисленные в табл. 6.3, используются для сохранения массиваданных в буфере отправки. Обратите вни м ание на то, что каждая PVM-задача (см. рис.6.6) должна и м еть по крайней м ере один буфер отправки и один буфер приема. Каждал функция упаковки прини м ает указатель на м ассив соответствую щ его типаданных. Все функции упаковки, за исключением функции pvm_pkstr (), принимают общее количество элементов, подлежащих сохранению в массиве (а не количество байтов!). Для функции pvm_pkstr() предполагается, что символьный массив, с которым она работает, завершается значение м NULL. Каждал функция упаковки, за исключением функции pvm_pkstr(), в качестве последнего пара м етра прини м ает значение, которое представляет способ обхода элементов исходного массива при их упаковке в буфер отправки. Этот параметр часто называют шагом по индексу (stride). Например, если этот шаг равен четырем, то в буфер упаковки будет помещен каждый четвертый элемент исходного массива. Важно отметить, что до отправки каждого сообщения необходимо использовать функцию pvm_initsend (), которая очищает буфер и готовит его к пересылке следующего сообщения. Функция pvm_initsend() готовит буфер к пересылке сообщения в одном из трех форматов: XDR, Raw или In Place.

Формат XDR (External Z>ata .Representation) — это стандарт, используемый для описания и шифрования данных. Слелует иметь в виду, что компьютеры, включенные всрелу PVM, могут быть совершенно разными, т.е. среда PVM, например, может состоять из Sun-, Macintosh-, Crays- и AMD-компьютеров. Эти компьютеры могут отличаться размерами машинных слов и по-разному сохранять различные типы данных. В некоторых случалх компьютеры могут различаться и битовой организацией. Стандарт XDR позволяет компьютерам обмениваться данными вне зависимости от типа их архитектуры. Формат Raw используется для отправки данных в собственно м фор м ате компьютера-отправителя. При это м никакое специальное кодирование не при м еняется. Формат In Place в действительности не требует упаковки данных в буфере отправки, и адресату отправляются лишь указатели на данные и раз м ер данных. В это м случае задача-получатель напря м ую копирует данные. В библиотеке PVM эти три типа кодирования данных представляются соответствующи м и тре м я константа м и:

PvmDataDefault XDR

PvmDataRaw Без специального кодирования

PvmDataInPlace В буфер отправки копируются лишь указатели и раз м ер данных

Вот пример: int BufferId;

BufferId = pvm_initsend(PvmDataRaw); //.. .

Здесь константа PvmDataRaw, переданнал функции pvm_initsend() в качестве параметра, означает, что данные упаковываются в буфер как есть, т.е. без специально г о кодирования. При успешном выполнении функция возвра щ ает номер буфера отправки (в данном случае он будет записан в переменную BufferId). Важно помнить, что хотя в каждый момент времени активным может быть только один буфер отправки, Любая PVM-задача может иметь несколько таких буферов, и с каждым из них связывается некоторый идентификационный номер.

В библиотеке PVM прелусмотрено несколько функций, имею щ их отношение к процелуре отправки.

Синопсис

# include « pvm3 .h»

int pvm_send(int taskid, int messageid); int pvm_psend(int taskid, int messageid,

char *buffer,int len, int datatype); int pvm_mcast(int *taskid,int ntask,int messageid);

В каждой из этих функций параметр taskid представл я ет собой идентификатор PVM-задачи, которая принимает сооб щ ение. При вызове функции pvm_mcast () параметр taskid означает коллекцию задач, представл я емых идентификаторами, которые передаютс я в массиве *taskid. Параметр messageid указывает идентификатор посылаемо г о сооб щ ени я. Идентификаторы сооб щ ений представл я ют собой целочисленные значени я, определенные пользователем. Они используются отправителем и получателем дл я идентификации сооб щ ени я, например:

case 1 : // Некоторые действия, break;

case 2 : // Другие действия, break

В данном случае функци я pvm_bufinfo() используетс я дл я получени я информации о последнем сооб щ ении, прин я том в буфер приема N. Мы можем получить количество байтов, идентификатор сооб щ ени я (messageid) и узнать, кто его отправил. Знал значение messageid, мы можем выполнить соответствую щ ие логические действи я. Функци я pvm_send () посылает заданной задаче команду псевдоблокировани я, после приема которой задача блокируетс я до тех пор, пока отправитель не убедится в том, что сообщение было послано правиль н о. Задача-отправитель не ожидает реального получени я сооб щ ения. Функция pvm_psend () отправляет сооб щ ение непосредственно указанной задаче. Обратите внимание на то, что функция pvmj?send () имеет параметр buffer, используемый в качестве буфера для хранения посылаемого сообщения. Функция pvm_mcast () используется для отправки сообщения нескольким задачам одновременно. Аргументы, передавае м ые функции pvm _mcast (), включают массив идентификаторов задач-получателей сообщения (taskid), количество задач — участников «широковещания» (ntask) и идентификатор сообщения (messageid) для идентификации отправляемого сооб щ ения. На рис. 6.6 показано, что у каждой PVM-задачи есть собственный буфер отправки, который существует в течение про м ежутка вре м ени, длительности которого было бы достаточно, чтобы сообщение гарантированно дошло до адресата.

За исключение м управляющих сообщений, значение сообщений, которы м и обмениваются любые две PVM-задачи, заранее определено логикой конкретного приложения, т.е. назначение каждого сообщения должно быть заранее известно для задачи-отправителя и задачи-получателя. Эти сообщения передаются асинхронно, могут иметь любой тип данных и произвольную длину. Тем са м ы м д ля приложения обеспечивается максимальнал гибкость. Аналога м и отправляе м ых РУМкюоб щ ений являются принимаемые PVM-сооб щ ения. Так, за прие м сооб щ ений «отвечают» пять основных функций.

Синопсис

# inc lude » pvm3 . h»

int pvm_recv(int taskid, int messageid) ;

int pvm_nrecv(int taskid, int messageid) ;

int pvm_precv(int taskid, int messageid, char *buffer,

int size, int type, int sender,

int messagetag, int messagelength); int pvm_trecv(int taskid,int messageid,

struct timeval *timeout); int pvm_probe(int taskid , int messageid);

Функция pvm_recv () используется о д ни м и PVM-за д ача м и для получения сооб щ ений от других. Эта функция создает новый активный буфер, предназначенный для хранения полученного сооб щ ения. Пара м етр taskid определяет идентификатор задачи-отправителя. Пара м етр messageid идентифицирует сооб щ ение, которое послано отправителе м. Следует и м еть в виду, что задача м ожет отправить несколько сообщений, и м ею щ их различные или одинаковые идентификаторы (messageid). Если taskid = -1, то функция pvm_recv () при м ет сооб щ е н ие от любой задачи. Ec-лиmessageid = -1, то функция при м ет любое сооб щ ение. При успешном выполнении функция pvm_recv () возвра щ ает идентификатор нового активного буфера, в противном случае — отрицательное значение. После вызова функции pvm_recv () задача будет заблокирована и станет ожидать до тех пор, пока сооб щ ение не будет получено. После получения сооб щ ение считывается из активного буфера с помо щ ью одной из функций распаковки, напри м ер:

float Value[10] ; pvm _recv (400002,2) ; pvn_unpkfloat(400002, Value,l) ; cout « Value..

Здесь фу н кция pvm_recv() обеспечивае т ожидание сооб щ ения от задачи, идентификатор которой равен 400002. Идентификатор сооб щ ения (messageid), полученно г о от задачи c номером 400002, должен быть равен значению 2. Затем используется функция распаковки для считывания массива чисел с плаваю щ ей точкой типа float. То г да как функция pvm_recv () вынуждает задачу ожидать до тех пор, пока она не получит сооб щ ение, функция pvm_nrecv () обеспечивает прием сообщений без блокирования. Если соответствующее сообщение не посгупает адресагу, функция pvm_nrecv () немедленно завершается. По прибытии сооб щ ения по месту назначени я функци я pvm_nrecv () сразу же завершаетс я, а активный буфер будет содержать полученное сооб щ ение. Если произойдет сбой, функция pvm_nrecv() возвратит отрицательное значение. Если сооб щ ение не поступит адресату, функция возвратит число 0. Если сооб щ ение бла г ополучно прибудет по месту назначения, функция возвратит номер ново г о активно г о буфера. Параметр taskid содержит идентификатор задачи-отправителя. Параметр messageid содержит идентификатор сооб щ ения, определенный пользователем. Если taskid = -1, функция pvm_nrecv() примет сооб щ ение от любой задачи. Если messageid = -1, эта функция примет любое сооб щ ение. При прие м е сооб щ ений с помощью функций pvm_recv () или pvm_nrecv () создается новый активный буфер, а теку щ ий буфер приема очищается.

Тогда как функции pvm_recv (), pvm_nrecv () и pvm_trecv () принимают сооб щ ения в новый активный буфер, функция pvm_precv () принимает сооб щ ение непосредственно в буфер, определенный пользователем. Параметр taskid содержит идентификатор задачи-отправителя. Параметр messageid идентифицирует получаемые сооб щ ения. Параметр buffer должен содержать реально принятое сооб щ ение. Поэтому вместо получения сооб щ ения из активного буфера с по м о щ ью одной из функций распаковки, сооб щ ение считывается напрямую из пара м етра buffer. Параметр size содержитдлину сооб щ ения в байтах. Параметр type определяет тип данных, содержа щ ихся в сооб щ ении. Параметр type может иметь следую щ ие значения:

PVM_STR PVM_BYTE

PVM_SHORT PVM_INT

PVM_FLOAT PVM_DOUBLE

PVM_LONG PVM_USHORT

PVM_CPLX PVM_DCPLX

PVM_UINT PVM_ULONG

Функция pvm_trecv() позволяет программисту организовать процедуру получения сооб щ ений с ограничением по времени. Эта функция заставляет вызываю щ ую задачу перейти в заблокированное состояние и ожидать прихода сооб щ ения, но лишь в течение промежутка времени, заданного параметром timeout. Этот параметр представляет собой струкгуру типа timeval, определенную в заголовке time.h, например:

struct timeval TimeOut; TimeOut.tv_sec = 1000; int TaskId; int MessageId;

TaskId = pvm_parent(); MessageId = 2;

pvro_trecv(TaskId,MessageId, &TimeOut) ; //.

Здесь переменная TimeOut содержит член tv_sec, установленный равным ЮОО с. Структуру timeval можно использовать для установки временных значений в секундах и микросекундах. Структура timeval имеет следую щ ий вид:

struct timeval

long tv_sec; // секунды

long tv_usec; // микросекунды

Этот пример означает, что функция pvm_trecv () заблокирует вызываю щ ую задачу максимум на 1000c. Если сооб щ ение будет получено до истечения заданных ЮОО с, функция сразу завершится. Функцию pvm_trecv () можно использовать для предотвращения бесконечных задержек и взаимоблокировок. При успешном выполнении функция pvm_trecv( ) возвра щ ает номер нового активного буфера, в противном случае (при возникновении ошибки) — отрицательное значение. Если taskid = -1, функция примет сооб щ ение от любого отправителя. Если messageid = -1, функция примет любое сооб щ ение.

Функция pvm_probe () определяет, поступило ли сооб щ ение, заданное параметром messageid, от отправителя, заданного параметром taskid. Если функция pvm_probe () «видит» указанное сооб щ ение, она возвра щ ает номер нового активного буфера. Если заданное сооб щ ение не прибыло, функция возвра щ ает число О. При возникновении сбоя функция возвра щ ает отрицательное значение.

Синопсис

#include «pvm3 .h»

int pvm_getsbuf (void) ;

int pvm_getrbuf (void) ;

int pvm_setsbuf(int bufferid);

int pvm_setrbuf(int bufferid);

int pvm_mkbuf(int Code);

int pvm_freebuf(int bufferid);

В библиотеке PVM предусмотрено шесть полезных функций управления буферами, которые можно использовать для установки, идентификации и динамического создания буферов отправки и приема. Функция pvm_getsbuf () используется для получения номера активного буфера отправки. Если теку щ его буфера отправки не существует, функция возвра щ ает число 0. Функция pvm_getrbuf () используется для получения идентификационного номера активного буфера приема. Следует иметь в виду, что при каждом получении сооб щ ения создается новый активный буфер, а теку щ ий буфер очи щ ается. Если теку щ его буфера приема не су щ ествует, функция возвра щ ает число 0. Функция pvm_setsbuf () устанавливает параметр bufferid равным номеру активного буфера отправки. Обычно PVM-задача имеет только один буфер отправки. Но иногда возникает необходимость в нескольких таких буферах. Хотя в любой момент времени активным может быть только один буфер отправки, PVM-задача может создавать дополнительные буфера отправки с по м о щ ью функции pvm_mkbuf (). Функцию pvm_setsbuf () можно использовать для установки в качестве активного буфера одного из буферов отправки, которые были созданы во время работы приложения. Эта функция возвра щ ает идентификатор предыду щ его активного буфера отправки. Функция pvm_setrbuf () устанавливает активный буфер прие м а равны м значению bufferid. По м ните, что PVM-функции распаковки работают с активны м буферо м прие м а. Если су щ ествует несколько буферов, функция pvm_setrbuf () позволит при м енить теку щ ий буфер д л я использования функция м и распаковки. При успешно м выполнении функция pvm_setrbuf () возвра щ ает идентификатор предыду щ его активного буфера. Если идентификатора буфера, переданного функции pmv_setrbuf (), не су щ ествует или он оказался недействительны м, функция возвратит одно из следую щ их сооб щ ений об ошибке: PvmBadParam или PvmNoSuchbuf. Функция pvm_mkbuf () используется для создания нового буфера сооб щ ений. Пара м етр Code определяет фор м ат данных, которые будут содержаться в это м буфере: XDR, собственный фор м ат компьютера или формат, использую щ ий указатели и размеры. Поэтому пара м етр Code мо-жет содержать одно из трех значений:

PvmDataDefault XDR

PvmDataRaw В зависи м ости от м арки ко м пьютера (без кодирования)

PvmDataInPlace Используются только указатели на данные и их размер

При успешном выполнении функция pvm_mkbuf () возвра щ ает идентификатор нового активного буфера, в противном случае — отрицательное значение. Для каждого обра щ ения к функции pvm_mkbuf () , если буфер отправки больше не будет нужен, необходи м о вызвать функцию pvm_freebuf () , которая освободит память, выделенную функцией pvm_mkbuf (). Функцию pvm_freebuf () с л едует испо л ьзовать то л ько в случае, когда сооб щ ение уже отправлено и в буфере нет никакой необходимости.

Что такое SMS‑сообщение?

Аббревиатура SMS расшифровывается как Short Message Service (сервис коротких сообщений). Это служба текстовых сообщений, которая позволяет обмениваться короткими текстовыми сообщениями между мобильными устройствами. SMS-сообщения обычно имеют максимальную длину 160 символов и могут быть отправлены и получены в различных мобильных сетях. SMS широко используются для личного и делового общения, обеспечивая быстрый и удобный способ отправки кратких сообщений отдельным лицам или группам людей. Она стала неотъемлемой частью мобильной связи и поддерживается практически всеми мобильными устройствами.

Что означает SMS?

Аббревиатура SMS расшифровывается как Short Message Service (сервис коротких сообщений). Это служба текстовых сообщений, которая позволяет обмениваться короткими текстовыми сообщениями между мобильными устройствами.

Как работает SMS?

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

  1. Отправитель инициирует сообщение: отправитель создает текстовое сообщение на своем мобильном устройстве и вводит номер телефона получателя.
  2. Сообщение, отправленное в SMSC: мобильное устройство отправителя отправляет сообщение в Центр обслуживания коротких сообщений (SMSC), который является централизованным сервером, отвечающим за обработку SMS-сообщений.
  3. Маршрутизация сообщений SMSC: SMSC проверяет телефонный номер получателя и определяет подходящую сеть для доставки сообщения.
  4. Доставка сообщения: затем SMSC отправляет сообщение в мобильную сеть получателя с помощью серии сигнальных сообщений.
  5. Сообщение, сохраненное в SMSC получателя: SMSC получателя принимает сообщение и временно сохраняет его до тех пор, пока устройство получателя не станет доступно для его получения.
  6. Уведомление на устройство получателя: как только устройство получателя будет доступно, SMSC получателя отправляет уведомление о доступности нового SMS.
  7. Получение сообщения: мобильное устройство получателя подключается к SMSC получателя для получения сообщения.
  8. Отображаемое сообщение: мобильное устройство получателя получает сообщение и отображает его.
  9. Дополнительное подтверждение доставки: мобильное устройство получателя может отправить подтверждение доставки обратно в SMSC отправителя, указывая, что сообщение было успешно получено.

Важно отметить, что SMS-сообщения обычно передаются по каналам управления и не используют те же голосовые каналы или каналы передачи данных, которые используются в других мобильных сервисах. Это позволяет SMS быть надежной и широко поддерживаемой формой связи даже в районах с ограниченным покрытием сети или во время перегрузки сети.

Как работает SMS-маркетинг?

SMS-маркетинг часто использует API SMS для автоматизации и оптимизации процесса. Вот обзор того, как работает SMS-маркетинг с помощью API SMS:

  1. Интеграция с API SMS: для реализации SMS-маркетинга компании интегрируют свои системы или приложения с API SMS. API служит интерфейсом, позволяющим программному обеспечению компании отправлять и получать SMS-сообщения программно.
  2. Составление списка подписчиков: компании собирают информацию о подписке от лиц, желающих получать маркетинговые SMS-сообщения. Эти данные можно собирать с помощью различных каналов, таких как веб-формы, мобильные приложения или регистрация в магазине. API позволяет легко интегрировать эти данные в список подписчиков.
  3. Создание и персонализация сообщений. Используя API SMS, компании создают персонализированные и целевые SMS-сообщения для взаимодействия со своими подписчиками. API позволяет динамически вставлять контент, позволяя настраивать сообщения на основе информации о подписчиках, такой как имена, история покупок или предпочтения.
  4. Запуск автоматических сообщений: API SMS позволяют автоматизировать отправку SMS-сообщений на основе заранее определенных триггеров или событий. Например, компании могут настроить автоматические приветственные сообщения для новых подписчиков или транзакционные сообщения для подтверждения заказов или обновлений касательно доставки.
  5. Отправка массовых SMS-кампаний: с помощью API SMS компании могут отправлять массовые SMS-кампании своему списку подписчиков. Они могут сегментировать свою аудиторию на основе демографических данных, предпочтений или поведения и отправлять целевые сообщения определенным сегментам, максимально повышая эффективность своих маркетинговых кампаний.
  6. Доставка и отслеживание сообщений: когда SMS отправляется через API SMS, сообщение передается на мобильные устройства абонентов через мобильную сеть. API управляет процессом доставки и предоставляет отчеты о доставке или обновления статуса, что позволяет компаниям отслеживать успех своих SMS-кампаний.
  7. Взаимодействие с абонентами и двусторонняя связь: API SMS позволяют компаниям упрощать двустороннюю связь со своими подписчиками. Подписчики могут отвечать на SMS-сообщения, что позволяет компаниям общаться в режиме реального времени, оказывать поддержку или собирать отзывы.
  8. Соответствие требованиям и нормативные требования. При использовании API SMS для SMS-маркетинга крайне важно соблюдать применимые правила, такие как получение надлежащего согласия и предоставление механизмов отказа от рассылки. API SMS часто включают функции, отвечающие требованиям соответствия, такие как управление отписками и обработка запросов на отказ от подписки.

Что такое API SMS?

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

Как работает API SMS?

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

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

Каковы преимущества использования API SMS?

Использование API SMS дает несколько преимуществ.

Автоматизация: API SMS позволяет автоматически отправлять и получать SMS-сообщения, что позволяет сэкономить время и силы по сравнению с ручными процессами.

Интеграция: API упрощают интеграцию функций SMS в существующие программные системы, позволяя компаниям включать SMS в свою коммуникационную стратегию.

Масштабируемость: с помощью API SMS компании могут легко масштабировать свои возможности SMS в соответствии с растущими коммуникационными потребностями, будь то отправка сообщений большой клиентской базе или обработка увеличенного объема сообщений.

Персонализация: API позволяют настраивать и персонализировать SMS-сообщения, интегрируя в них динамический контент, такой как имена клиентов или сведения о заказе.

Общение в реальном времени. Используя API SMS, компании могут общаться со своими клиентами в режиме реального времени, мгновенно доставляя важные уведомления, оповещения или рекламные сообщения.

Где найти поставщиков SMS-маркетинга?

API SMS доступны у различных поставщиков услуг SMS. Вы можете найти и изучить различные API SMS на торговых площадках или в каталогах API, посвященных демонстрации и предложению широкого спектра API. Некоторые популярные поставщики услуг SMS включают Amazon Pinpoint, Amazon SNS, Twilio и Sinch.

Не забудьте выбрать API SMS, соответствующие вашим конкретным потребностям, учитывая такие факторы, как цена, надежность, функции и качество документации.

Как использовать API SMS?

Чтобы использовать API SMS, выполните указанные ниже действия.

  1. Получите учетные данные API: зарегистрируйтесь у поставщика услуг SMS, который предлагает API SMS, и получите необходимые учетные данные API, такие как ключ API или токен доступа.
  2. Интегрируйте API: в зависимости от используемого языка программирования или платформы интегрируйте API SMS в код приложения. Обычно это связано с отправкой HTTP-запросов на адреса API, предоставленные поставщиком услуг SMS.
  3. Отправка SMS-сообщений: используйте методы или адреса API для отправки SMS-сообщений. Укажите необходимые параметры, такие как номер телефона получателя и содержимое сообщения, в запросе API.
  4. Обработка ответов: после отправки API SMS предоставит ответ с указанием статуса доставки сообщения. Обработайте эти ответы в своем приложении, чтобы обеспечить успешную доставку сообщений и устранить возможные ошибки.
  5. Получение SMS-сообщений (опционально): если ваш вариант использования связан с получением SMS-сообщений, API SMS может предоставить адреса или веб-хуки для получения входящих сообщений. Настройте приложение для прослушивания входящих сообщений и соответствующей их обработки.

Как AWS может удовлетворить ваши потребности в SMS?

Amazon Pinpoint – это многоканальный сервис связи и привлечения клиентов, предлагаемый AWS. Он предоставляет компаниям инструменты для эффективного привлечения клиентов по различным каналам, включая SMS, push-уведомления и голосовые сообщения. С помощью Amazon Pinpoint компании могут создавать целевые и персонализированные кампании, отслеживать взаимодействие с пользователями и анализировать эффективность кампаний для оптимизации стратегий привлечения клиентов. Amazon Pinpoint в первую очередь помогает компаниям отправлять SMS, push-уведомления или голосовые сообщения людям или конечным клиентам, что часто называют обменом сообщениями от приложения к пользователю (A2P). Amazon Pinpoint также позволяет компаниям создавать индивидуальные маршруты, чтобы клиенты получали нужное сообщение в нужное время.

Amazon Simple Notification Service (SNS) – это гибкий и масштабируемый сервис обмена сообщениями, предоставляемый AWS. Это позволяет разработчикам отправлять сообщения или уведомления большому количеству подписчиков или адресов, таких как мобильные устройства, адреса электронной почты или распределенные системы. Amazon SNS в первую очередь помогает компаниям отправлять сообщения A2A или из приложения в приложение с помощью автоматических уведомлений. Это позволяет приложениям взаимодействовать и обмениваться информацией друг с другом, обеспечивая беспрепятственную связь и интеграцию между различными программными компонентами.

Начните работу с SaaS на AWS, создав бесплатный аккаунт уже сегодня.

Сведения о сообщениях и очередях сообщений

В отличие от приложений на основе MS-DOS, приложения на основе Windows управляются событиями. Они не выполняют явные вызовы функций (например, вызовы библиотеки времени выполнения C) для получения входных данных. Вместо этого они ждут, пока система передаст им входные данные.

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

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

В этом разделе рассматриваются следующие темы:

  • Сообщения Windows
  • Типы сообщений
    • Системные сообщения
    • Сообщения, определяемые приложением
    • Сообщения в очереди
    • Сообщения, не хочуемые в очереди
    • Цикл сообщений
    • Процедура window
    • Публикация сообщений
    • Отправка сообщений

    Сообщения Windows

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

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

    Идентификатор сообщения — это именованной константой, которая определяет назначение сообщения. Когда процедура окна получает сообщение, она использует идентификатор сообщения для определения способа обработки сообщения. Например, идентификатор сообщения WM_PAINT сообщает процедуре окна, что клиентская область окна изменилась и должна быть перерисовывается.

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

    Типы сообщений

    В этом разделе описываются два типа сообщений:

    • Системные сообщения
    • Сообщения, определяемые приложением

    Сообщения System-Defined

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

    Каждое системное сообщение имеет уникальный идентификатор сообщения и соответствующую символьную константу (определенную в файлах заголовков пакета sdk), которая указывает назначение сообщения. Например, WM_PAINT константы запрашивают, чтобы окно закрашивать его содержимое.

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

    Prefix Категория сообщения Документация
    ABM и ABN Панель инструментов рабочего стола приложения Сообщения и уведомления оболочки
    ACM и ACN Элемент управления «Анимация» Сообщения элемента управления анимацией и уведомления элемента управления анимацией
    BCM, BCN, BM и BN Button — элемент управления Сообщения элемента управления кнопками и уведомления элемента управления кнопками
    CB и CBN ComboBox — элемент управления Сообщения элемента управления ComboBox и уведомления элемента управления ComboBox
    CBEM и CBEN Элемент управления ComboBoxEx Сообщения ComboBoxEx и уведомления ComboBoxEx
    СКК Общий элемент управления Управляющие сообщения
    CDM Общее диалоговое окно Распространенные сообщения диалогового окна
    DFM Контекстное меню по умолчанию Сообщения и уведомления оболочки
    DL Перетащите список Перетаскивание уведомлений со списком
    DM Элемент управления «Кнопка» по умолчанию Сообщения диалогового окна
    DTM и DTN Элемент управления «Выбор даты и времени» Сообщения средства выбора даты и времени и уведомления о выборе даты и времени
    EM и EN Элемент управления «Поле ввода» Изменение сообщений элемента управления, изменение уведомлений элемента управления, сообщения с расширенными возможностями и уведомления о расширенном редактировании
    HDM и HDN Элемент управления «Заголовок» Сообщения элемента управления заголовком и уведомления элемента управления заголовком
    HKM Элемент управления «Горячая клавиша» Сообщения элемента управления «Горячий ключ»
    IPM и IPN контроль IP-адресов Сообщения IP-адресов и уведомления об IP-адресах
    LB и LBN Элемент управления «Список» Сообщения со списком и уведомления со списком
    LM Элемент управления SysLink Сообщения элемента управления SysLink
    LVM и LVN Элемент управления «Представление списка» Сообщения представления списка и уведомления представления списка
    MCM и MCN Элемент управления «Календарь на месяц» Сообщения в календаре за месяц и уведомления календаря за месяц
    Управление на основе политик (PBM) Индикатор выполнения Сообщения индикатора выполнения
    PGM и PGN Элемент управления «Пейджер» Сообщения элемента управления Pager и уведомления элемента управления Pager
    PSM и PSN Страница свойств. Сообщения на странице свойств и уведомления на листе свойств
    RB и RBN Элемент управления «Перекладка» Сообщения элемента управления иуведомления элемента управления rebar
    SB и SBN Окно строки состояния Сообщения в строке состояния и уведомления в строке состояния
    SBM Элемент управления «Полоса прокрутки» Сообщения полосы прокрутки
    SMC Меню оболочки Сообщения и уведомления оболочки
    STM и STN Статический элемент управления Статические сообщения элемента управления и уведомления статического элемента управления
    ТБ и TBN Панель инструментов Сообщения элемента управления панелью инструментов и уведомления элемента управления панели инструментов
    TBM и TRBN Элемент управления trackbar Сообщения элемента управления Trackbar и уведомления элемента управления Trackbar
    TCM и TCN Элемент управления табуляции Сообщения элемента управления вкладками и уведомления элемента управления вкладками
    TDM и TDN Диалоговое окно задачи Сообщения диалогового окна задачи и уведомления о диалоговых окнах задач
    TTM и TTN Элемент управления «Подсказка» Сообщения элемента управления подсказками и уведомления элемента управления подсказками
    TVM и TVN Элемент управления «Древовидное представление» Сообщения в виде дерева и уведомления в виде дерева
    UDM и UDN Элемент управления «Вверх-вниз» Сообщения вверх-вниз и уведомления вверх-вниз
    WM Общие сведения Сообщения буфера обмена Уведомления буфера обмена Распространенные уведомления диалогового окна Уведомления курсора Сообщение о копировании данных Сообщения диспетчера окон рабочего стола Сообщения Управление устройствами Уведомления диалогового окна Динамические сообщения обмена данными Уведомления о динамическом обмене данными Уведомления перехватчика Сообщения ускорителя клавиатуры Уведомления ускорителя клавиатуры Ввод сообщений с клавиатуры Уведомления о вводе с клавиатуры Уведомления меню Уведомления о вводе с помощью мыши Сообщения из нескольких интерфейсов документов Необработанные входные уведомления Уведомления полосы прокрутки Уведомления таймера Сообщения окна Уведомления о окне

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

    Сообщения Application-Defined

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

    Значения идентификатора сообщения используются следующим образом:

    • Система резервирует значения идентификаторов сообщений в диапазоне 0x0000 до 0x03FF (значение WM_USER –1) для системных сообщений. Приложения не могут использовать эти значения для личных сообщений.
    • Значения в диапазоне 0x0400 (значение WM_USER) по 0x7FFF доступны для идентификаторов сообщений для частных классов окон.
    • Если приложение помечено версией 4.0, можно использовать значения идентификатора сообщения в диапазоне 0x8000 (WM_APP) через 0xBFFF для личных сообщений.
    • Система возвращает идентификатор сообщения в диапазоне 0xC000 по 0xFFFF, когда приложение вызывает функцию RegisterWindowMessage для регистрации сообщения. Идентификатор сообщения, возвращаемый этой функцией, гарантированно будет уникальным в системе. Использование этой функции предотвращает конфликты, которые могут возникнуть, если другие приложения используют один и тот же идентификатор сообщения для различных целей.

    Маршрутизация сообщений

    Система использует два метода для маршрутизации сообщений в процедуру окна: отправка сообщений в очередь первого входа, которая называется очередью сообщений, определенный системой объект памяти, в котором временно хранятся сообщения, и отправка сообщений непосредственно в процедуру окна.

    Сообщение, отправленное в очередь сообщений, называется сообщением в очереди. В основном это результат ввода пользователем с помощью мыши или клавиатуры, например WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN и WM_CHAR сообщений. К другим сообщениям в очереди относятся сообщения таймера, рисования и выхода: WM_TIMER, WM_PAINT и WM_QUIT. Большинство других сообщений, которые отправляются непосредственно в процедуру окна, называются сообщениями без очереди.

    • Сообщения в очереди
    • Сообщения без очереди

    Сообщения в очереди

    Система может отображать любое количество окон за раз. Для маршрутизации ввода с помощью мыши и клавиатуры в соответствующее окно система использует очереди сообщений.

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

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

    За исключением сообщения WM_PAINT , WM_TIMER и WM_QUIT сообщения система всегда публикует сообщения в конце очереди сообщений. Это гарантирует, что окно получает входные сообщения в правильной последовательности first in, first out (FIFO). Однако сообщение WM_PAINT , WM_TIMER и сообщение WM_QUIT хранятся в очереди и перенаправляются в процедуру окна, только если очередь не содержит других сообщений. Кроме того, несколько сообщений WM_PAINT для одного окна объединяются в одно WM_PAINT сообщение, консолидируя все недопустимые части клиентской области в одной области. Объединение WM_PAINT сообщений сокращает количество перерисовок содержимого клиентской области в окне.

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

    Приложение может удалить сообщение из очереди с помощью функции GetMessage . Чтобы проверить сообщение, не удаляя его из очереди, приложение может использовать функцию PeekMessage . Эта функция заполняет MSG сведениями о сообщении.

    После удаления сообщения из очереди приложение может использовать функцию DispatchMessage , чтобы направить систему на отправку сообщения в оконную процедуру для обработки. DispatchMessage принимает указатель на MSG , который был заполнен предыдущим вызовом функции GetMessage или PeekMessage . DispatchMessage передает дескриптор окна, идентификатор сообщения и два параметра сообщения в процедуру окна, но не проходит время публикации сообщения или положение курсора мыши. Приложение может получить эти сведения, вызывая функции GetMessageTime и GetMessagePos при обработке сообщения.

    Поток может использовать функцию WaitMessage для передачи управления другим потокам, если в очереди сообщений нет сообщений. Функция приостанавливает поток и не возвращается, пока новое сообщение не будет помещено в очередь сообщений потока.

    Можно вызвать функцию SetMessageExtraInfo , чтобы связать значение с очередью сообщений текущего потока. Затем вызовите функцию GetMessageExtraInfo , чтобы получить значение, связанное с последним сообщением, извлеченным функцией GetMessage или PeekMessage .

    Сообщения без очереди

    Непереправляемые сообщения немедленно отправляются в процедуру окна назначения, минуя очередь системных сообщений и очередь сообщений потока. Система обычно отправляет сообщения без очереди, чтобы уведомлять окно о событиях, влияющих на нее. Например, когда пользователь активирует новое окно приложения, система отправляет окну ряд сообщений, включая WM_ACTIVATE, WM_SETFOCUS и WM_SETCURSOR. Эти сообщения уведомляют окно о том, что оно было активировано, что ввод с помощью клавиатуры направляется в окно и что курсор мыши был перемещен в пределах окна. Сообщения, не отправляемые в очередь, также могут возникать при вызове приложением определенных системных функций. Например, система отправляет сообщение WM_WINDOWPOSCHANGED после того, как приложение использует функцию SetWindowPos для перемещения окна.

    Обработка сообщений

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

    Цикл сообщений

    Простой цикл сообщений состоит из одного вызова каждой из трех функций: GetMessage, TranslateMessage и DispatchMessage. Обратите внимание, что при возникновении ошибки GetMessage возвращает –1, что приводит к необходимости специального тестирования.

    MSG msg; BOOL bRet; while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) < if (bRet == -1) < // handle the error and possibly exit >else < TranslateMessage(&msg); DispatchMessage(&msg); >> 

    Функция GetMessage извлекает сообщение из очереди и копирует его в структуру типа MSG. Он возвращает ненулевое значение, если не встречается с сообщением WM_QUIT . В этом случае возвращается значение FALSE и завершается цикл. В однопотоковом приложении завершение цикла сообщений часто является первым шагом при закрытии приложения. Приложение может завершить свой собственный цикл с помощью функции PostQuitMessage, как правило, в ответ на сообщение WM_DESTROY в процедуре окна main приложения.

    Если указать дескриптор окна в качестве второго параметра GetMessage, из очереди будут извлекаться только сообщения для указанного окна. GetMessage также может фильтровать сообщения в очереди, извлекая только те сообщения, которые попадают в указанный диапазон. Дополнительные сведения о фильтрации сообщений см. в разделе Фильтрация сообщений.

    Цикл сообщений потока должен включать TranslateMessage , если поток должен получать ввод символов с клавиатуры. Система создает сообщения с виртуальным ключом (WM_KEYDOWN и WM_KEYUP) каждый раз, когда пользователь нажимает клавишу. Сообщение виртуального ключа содержит код виртуального ключа, который определяет, какая клавиша была нажата, но не ее значение символа. Чтобы получить это значение, цикл сообщений должен содержать TranslateMessage, который преобразует сообщение виртуального ключа в символьное сообщение (WM_CHAR) и помещает его обратно в очередь сообщений приложения. Символьное сообщение затем можно удалить при последующей итерации цикла сообщений и отправить в процедуру окна.

    Функция DispatchMessage отправляет сообщение в процедуру окна, связанную с дескриптором окна, указанным в структуре MSG . Если дескриптор окна HWND_TOPMOST, DispatchMessage отправляет сообщение в процедуры окон всех окон верхнего уровня в системе. Если дескриптор окна имеет значение NULL, DispatchMessage ничего не делает с сообщением.

    Поток main приложения запускает цикл сообщений после инициализации приложения и создания по крайней мере одного окна. После запуска цикл сообщений продолжает получать сообщения из очереди сообщений потока и отправлять их в соответствующие окна. Цикл сообщений завершается, когда функция GetMessage удаляет WM_QUIT сообщение из очереди сообщений.

    Для очереди сообщений требуется только один цикл сообщений, даже если приложение содержит много окон. DispatchMessage всегда отправляет сообщение в соответствующее окно; Это связано с тем, что каждое сообщение в очереди является структурой MSG , содержащей дескриптор окна, которому принадлежит сообщение.

    Цикл сообщений можно изменить различными способами. Например, можно получить сообщения из очереди, не отправляя их в окно. Это полезно для приложений, которые публикуют сообщения, не указывающие окно. Вы также можете направить GetMessage на поиск определенных сообщений, оставив другие сообщения в очереди. Это полезно, если необходимо временно обойти обычный порядок FIFO очереди сообщений.

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

    Если поток использует немодерное диалоговое окно, цикл сообщений должен включать функцию IsDialogMessage , чтобы диалоговое окно получало ввод с клавиатуры.

    Процедура окна

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

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

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

    Так как процедура окна совместно используется всеми окнами, принадлежащими одному классу, она может обрабатывать сообщения для нескольких разных окон. Чтобы определить конкретное окно, на которое влияет сообщение, процедура окна может проверить дескриптор окна, переданный вместе с сообщением. Дополнительные сведения о процедурах окна см. в разделе Процедуры окна.

    Фильтрация сообщений

    Приложение может выбрать определенные сообщения для извлечения из очереди сообщений (игнорируя другие сообщения), используя функцию GetMessage или PeekMessage для указания фильтра сообщений. Фильтр представляет собой диапазон идентификаторов сообщений (определяется первым и последним идентификаторами), дескриптором окна или и тем, и другим. GetMessage и PeekMessage используют фильтр сообщений для выбора сообщений, которые следует извлечь из очереди. Фильтрация сообщений полезна, если приложение должно искать в очереди сообщений сообщения, которые поступили позже в очередь. Это также полезно, если приложение должно обрабатывать входные (аппаратные) сообщения перед обработкой опубликованных сообщений.

    Константы WM_KEYFIRST и WM_KEYLAST можно использовать в качестве значений фильтра для получения всех сообщений клавиатуры; Для получения всех сообщений мыши можно использовать константы WM_MOUSEFIRST и WM_MOUSELAST .

    Любое приложение, которое фильтрует сообщения, должно гарантировать, что сообщение, удовлетворяющее фильтру сообщений, может быть опубликовано. Например, если приложение фильтрует WM_CHAR сообщение в окне, которое не получает ввод с клавиатуры, функция GetMessage не возвращает. Это фактически «зависает» приложение.

    Публикация и отправка сообщений

    Любое приложение может публиковать и отправлять сообщения. Как и в системе, приложение отправляет сообщение, копируя его в очередь сообщений, и отправляет сообщение, передавая данные сообщения в качестве аргументов в процедуру окна. Для публикации сообщений приложение использует функцию PostMessage . Приложение может отправлять сообщение, вызывая функцию SendMessage, BroadcastSystemMessage, SendMessageCallback, SendMessageTimeout, SendNotifyMessage или SendDlgItemMessage .

    Публикация сообщений

    Приложение обычно отправляет сообщение, уведомляющее определенное окно о выполнении задачи. PostMessage создает структуру MSG для сообщения и копирует сообщение в очередь сообщений. Цикл сообщений приложения в конечном итоге извлекает сообщение и отправляет его в соответствующую процедуру окна.

    Приложение может публиковать сообщение без указания окна. Если приложение предоставляет дескриптор окна NULL при вызове PostMessage, сообщение отправляется в очередь, связанную с текущим потоком. Так как дескриптор окна не указан, приложение должно обработать сообщение в цикле сообщений. Это один из способов создания сообщения, которое применяется ко всему приложению, а не к определенному окну.

    Иногда может потребоваться опубликовать сообщение во всех окнах верхнего уровня в системе. Приложение может публиковать сообщение во все окна верхнего уровня, вызвав PostMessage и указав HWND_TOPMOST в параметре hwnd .

    Распространенной ошибкой программирования является предположение, что функция PostMessage всегда публикует сообщение. Это не так, если очередь сообщений заполнена. Приложение должно проверка возвращаемое значение функции PostMessage, чтобы определить, было ли опубликовано сообщение, и, если оно не было, повторно отправить его.

    отправка сообщений

    Приложение обычно отправляет сообщение для уведомления процедуры окна о немедленном выполнении задачи. Функция SendMessage отправляет сообщение в процедуру окна, соответствующую заданному окну. Функция ожидает завершения обработки процедуры окна, а затем возвращает результат сообщения. Родительское и дочернее окна часто обмениваются сообщениями, отправляя сообщения друг другу. Например, родительское окно с элементом управления «Редактирование» в качестве дочернего окна может задавать текст элемента управления, отправляя ему сообщение. Элемент управления может уведомлять родительское окно об изменениях в тексте, выполненных пользователем, отправляя сообщения обратно родительскому окну.

    Функция SendMessageCallback также отправляет сообщение в процедуру окна, соответствующую заданному окну. Однако эта функция возвращается немедленно. После того как процедура окна обработает сообщение, система вызывает указанную функцию обратного вызова. Дополнительные сведения о функции обратного вызова см. в разделе Функция SendAsyncProc .

    Иногда может потребоваться отправить сообщение во все окна верхнего уровня в системе. Например, если приложение изменяет системное время, оно должно уведомить все окна верхнего уровня об изменении, отправив WM_TIMECHANGE сообщение. Приложение может отправить сообщение во все окна верхнего уровня, вызвав SendMessage и указав HWND_TOPMOST в параметре hwnd . Вы также можете транслировать сообщение во все приложения, вызвав функцию BroadcastSystemMessage и указав BSM_APPLICATIONS в параметре lpdwRecipients .

    С помощью функции InSendMessage или InSendMessageEx процедура окна может определить, обрабатывается ли сообщение, отправленное другим потоком. Эта возможность полезна, если обработка сообщений зависит от источника сообщения.

    Взаимоблокировки сообщений

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

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

    Чтобы избежать потенциальных взаимоблокировок в приложении, рассмотрите возможность использования функций SendNotifyMessage или SendMessageTimeout . В противном случае оконная процедура может определить, было ли полученное сообщение отправлено другим потоком путем вызова функции InSendMessage или InSendMessageEx . Перед вызовом любой из функций из предыдущего списка при обработке сообщения процедура окна должна сначала вызвать InSendMessage или InSendMessageEx. Если эта функция возвращает значение TRUE, оконная процедура должна вызвать функцию ReplyMessage перед любой функцией, которая вызывает поток для получения управления.

    Трансляция сообщений

    Каждое сообщение состоит из идентификатора сообщения и двух параметров: wParam и lParam. Идентификатор сообщения — это уникальное значение, указывающее назначение сообщения. Параметры предоставляют дополнительные сведения, относящиеся к конкретному сообщению, но параметр wParam обычно является значением типа, предоставляющим дополнительные сведения о сообщении.

    Широковещательная рассылка — это просто отправка сообщения нескольким получателям в системе. Чтобы транслировать сообщение из приложения, используйте функцию BroadcastSystemMessage , указав получателей сообщения. Вместо указания отдельных получателей необходимо указать один или несколько типов получателей. Это приложения, устанавливаемые драйверы, сетевые драйверы и драйверы устройств на уровне системы. Система отправляет широковещательные сообщения всем членам каждого указанного типа.

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

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

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

    Драйверы устройств системного уровня используют связанную функцию системного уровня для широковещательной рассылки системных сообщений.

    Запросы сообщений

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

    Чтобы опросить у получателей разрешение на выполнение заданного действия, используйте сообщение запроса. Вы можете создавать собственные сообщения запросов, задав значение BSF_QUERY в параметре dwFlags при вызове BroadcastSystemMessage. Каждый получатель сообщения запроса должен возвращать значение TRUE , чтобы функция отправляла сообщение следующему получателю. Если какой-либо получатель возвращает BROADCAST_QUERY_DENY, трансляция немедленно завершается, а функция возвращает ноль.

    Обратная связь

    Были ли сведения на этой странице полезными?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *