STARLIKE C.350 CRYSTAL;pdf

Информационноесопровождение.Инструкцияпонастройке
взаимодействияМИСссервисамиТФОМСЯО.
Система обмена сообщениями между участниками информационных систем построена на базе платформы RabbitMQ, обеспечивающей высокую производительность и надежность промышленного уровня, имеющей обширный набор компонентов по взаимодействию с ней. (Подробней см. http://rabbitmq.com (описание платформы) и http://www.rabbitmq.com/devtools.html (описание клиентов и инструментов разработчика). Терминология
RabbitMQ — платформа, реализующая систему обмена сообщениями между компонентами программной системы (Message Oriented Middleware) на основе стандарта AMQP (Advanced Message Queuing Protocol). МИС – медицинская информационная система МО – медицинская организация ЯО, участвующая в процессе информационного взаимодействия посредствам одного или нескольких участников информационного взаимодействия. Участник информационного взаимодействия (УИВ) – компонент информационной системы МО, представленный отдельной МИС. Описаниепринциповвзаимодействия
RabbitMQ реализует очереди (queues). Взаимодействие осуществляется путем отправки сообщений в очередь ТФ ОМС ЯО с именем TFOMS.Queue.7ADB0C1E‐D488‐4C2B‐97FF‐
52D003FC47BD, и приемом сообщений из очереди, соответствующего УИВ с именем TFOMS.Queue.{client_id}. Где client_id глобальный уникальный идентификатор (GUID) УИВ. client_id назначается ТФ ОМС ЯО, каждому УИВ согласно предоставленной из МО информации. Рисунок 1. Общая схема информационного взаимодействия Рисунок 2. Концептуальная схема передачи и обработки сообщений СоединениесRabbitMQ
Сервер RabbitMQ размещается в ТФ ОМС. Доступ к нему возможен только внутри защищенной сети VipNET. Для определения IP адреса сервера RabbitMQ в сети VipNET каждому УИВ необходимо взять виртуальный IP адрес узла 76 (ЯрТФОМС) SP TNO. Программнаяреализация
Для взаимодействия с RabbitMQ необходимо реализовать два процесса: 1. Процесс публикации в очередь ТФ ОМС 2. Процесс приема сообщений из очереди УИВ Каждое отправляемое и принимаемое сообщение должно иметь заголовок сообщения и его тело. В заголовке сообщения передается информация следующего содержания: 1. protocol ‐ тип протокола передаваемого в теле сообщения содержимого. (См. Порядок обмена данными между учреждениями здравоохранения Ярославской области) 2. client_id – идентификатор УИВ отправляющего сообщения 3. package_id – идентификатор сообщения. В теле сообщения в формате XML передается само сообщение согласно порядка обмена данными между учреждениями здравоохранения Ярославской области. Примерреализации
Все примеры написаны с использованием клиента под платформу .Net. Созданиеподключения
private ConnectionFactory GetFactory() { ConnectionFactory factory = new ConnectionFactory(); factory.UserName = "tf_account"; factory.Password = "tf_account"; factory.VirtualHost = "/"; factory.Protocol = Protocols.DefaultProtocol; factory.HostName = "11.0.0.99"; //Виртуальный IP узла 76 (ЯрТФОМС) SP TNO factory.Port = AmqpTcpEndpoint.UseDefaultPort; return factory; } Отправкасообщения
private void SendMessage( string messageBody ) { try { var connection = GetFactory(); using( IConnection conn = connection.CreateConnection() ) { using( IModel channel = conn.CreateModel() ) { string queueName = "TFOMS.Queue.7ADB0C1E‐D488‐4C2B‐97FF‐52D003FC47BD"; channel.QueueDeclare( queueName, true, false, false, null ); // Publish message byte[] messageBodyBytes = System.Text.Encoding.UTF8.GetBytes( messageBody ); var builder = new RabbitMQ.Client.Content.BytesMessageBuilder( channel ); builder.Headers["protocol"] = Protocol; builder.Headers["client_id"] = ClientId; builder.Headers["package_id"] = OutgoingPackageId; ( ( IBasicProperties )builder.GetContentHeader() ).DeliveryMode = 2; builder.WriteBytes( messageBodyBytes ); channel.BasicPublish( "", queueName, ( IBasicProperties )builder.GetContentHeader(), builder.GetContentBody() ); channel.Close( 200, "Goodbye" ); } } } catch( Exception expn ) { MessageBox.Show( expn.Message ); } } ПриемсообщенияизочередиУИВ
Возможны два подхода к процессу получения. 1. Периодически опрашивать «свою» очередь 2. Через создание получателя Рассмотрим пример на основе создания получателя работающего в отдельном потоке. void _subscribeWorker_DoWork( object sender, DoWorkEventArgs eventArgs ) { var worker = sender as BackgroundWorker; if( worker == null ) { return; } using( IConnection connection = GetFactory().CreateConnection() ) { using( IModel channel = connection.CreateModel() ) { channel.QueueDeclare("TFOMS.Queue.E20AD2CF‐2936‐4329‐9AF4‐56B2FDAB0F3D", true, false, false, null ); QueueingBasicConsumer consumer = new QueueingBasicConsumer( channel ); //Подключаем "свою" очередь String consumerTag = channel.BasicConsume( "TFOMS.Queue.E20AD2CF‐2936‐4329‐9AF4‐56B2FDAB0F3D", false, consumer ); while( true ) { if( worker.CancellationPending ) { break; } try { RabbitMQ.Client.Events.BasicDeliverEventArgs e; // Ожидаю получения сообщения if( consumer.Queue.Dequeue( 1000, out e ) ) { IBasicProperties props = e.BasicProperties; byte[] body = e.Body; // Обработка входящего сообщения Dispatcher.BeginInvoke( new Action<string>( SetSubscribedMessageText ), System.Text.Encoding.UTF8.GetString( body ) ); channel.BasicAck( e.DeliveryTag, false ); } } catch( RabbitMQ.Client.Exceptions.OperationInterruptedException ex ) { break; } } channel.Close( 200, "Goodbye" ); } } }