Как реализовать отправку и получение данных hl7 в .NET в SSH-соединении - PullRequest
1 голос
/ 21 мая 2019

Я внедряю приложение в .Net. Я должен создать соединение по SSH, которое работает, но получение данных HL7 не удается. Пункт назначения - малиновый пи. Поэтому, когда я отлаживаю, что ssh-клиент подключен, порт перенаправляется, tcp-клиент также подключается, но нет ответа на мои запросы. Пожалуйста, предложите мне несколько примеров!

В этом проекте я уже реализовал его на Android - он отлично работает. Поэтому в .Net я попробовал библиотеку NHapiTools, а также пробовал прямой TcpClient. localPort = remotePort. Я использовал localIP = "localhost"

static void Main(string[] args)
    {
        try
        {
            PrivateKeyFile file = new PrivateKeyFile(@"./key/private.key");
        using (var client = new SshClient(remoteIP, sshPort, username, file))
            {
                client.Connect();
                var ci = client.ConnectionInfo;
                var port = new ForwardedPortLocal(localIP, localPort, client.ConnectionInfo.Host, remotePort);
                client.AddForwardedPort(port);
                port.Start();
                var req = "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5";

                ////TCP
                var tcpClient = new TcpClient();
                tcpClient.Connect(localIP, (int)localPort);
                Byte[] data = System.Text.Encoding.ASCII.GetBytes(req);

                using (var stream = tcpClient.GetStream())
                {
                    stream.Write(data, 0, data.Length);

                    using (var buffer = new MemoryStream())
                    {
                        byte[] chunk = new byte[4096];
                        int bytesRead;

                        while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
                        {
                            buffer.Write(chunk, 0, bytesRead);
                        }

                        data = buffer.ToArray();
                    }
                }
   //I used this also with same result -> no respond
   //SimpleMLLP
   /*
   var connection = new SimpleMLLPClient(localIP, localPort, 
   Encoding.UTF8);
   var response = connection.SendHL7Message(req);
   */
            }
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        Console.ReadLine();
    }

}

Итак, я показал, что размер буфера в TCP равен 0 (из-за тайм-аута). В тесте SimpleMLLP метод SendHK7Message никогда не возвращает

Ответы [ 2 ]

1 голос
/ 05 июня 2019

После нескольких дней борьбы я решил проблему.Основная ошибка была с переадресацией портов.Я бы рекомендовал использовать SSH.Net от Renci (была ошибка алгоритма с Tamir ssh).После создания ssh-соединения я использовал это для переадресации:

           var port = new ForwardedPortLocal(localIP, localPort, "localhost", remotePort);

Проверьте ваш локальный IP с помощью ipconfig / all в cmd.Или используйте 127.0.0.1 в качестве петлевого IP.SimpleMLLPClient не работал для меня, поэтому я использовал прямой запрос клиента tcp.Примерно так:

            TcpClient ourTcpClient = new TcpClient();
            ourTcpClient.Connect(localIP, (int)localPort); 
            NetworkStream networkStream = ourTcpClient.GetStream();

            var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());

            if (networkStream.CanWrite)
            {
                networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length);

                Console.WriteLine("Data was sent to server successfully....");
                byte[] receiveMessageByteBuffer = new byte[ourTcpClient.ReceiveBufferSize];
                var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);

                if (bytesReceivedFromServer > 0 && networkStream.CanRead)
                {
                    receivedMessage.Append(Encoding.UTF8.GetString(receiveMessageByteBuffer));
                }

                var message = receivedMessage.Replace("\0", string.Empty);
                Console.WriteLine("Received message from server: {0}", message);
            }

Таким образом, он дал мне мгновенный ответ с 0 байтами (без истечения времени ожидания).И тут приходит помощь Амит Джоши.Я использовал запрос, который он предложил с START_OF_BLOCK, CARRIAGE_RETURN и END_OF_BLOCK, и наконец начал работать.Спасибо, Амит Джоши!

Дополнительная информация: В Android (Java / Kotlin) сеанс jsch setPortForwardingL отлично работает с тремя параметрами:

        val session = jsch.getSession("user", sshIP, sshPort)
        session.setPassword("")
        jsch.addIdentity(privatekey.getAbsolutePath())
        // Avoid asking for key confirmation
        val prop = Properties()
        prop.setProperty("StrictHostKeyChecking", "no")
        session.setConfig(prop)
        session.connect(5000)
        session.setPortForwardingL(localForwardPort, "localhost", remotePort)

        val useTls = false
        val context = DefaultHapiContext()
        connection = context.newClient("localhost", localForwardPort, useTls)
1 голос
/ 22 мая 2019

Вы не используете протокол MLLP (также называемый LLP) при отправке сообщения.

Description                 HEX     ASCII   Symbol
Message starting character  0B      11      <VT>
Message ending characters   1C,0D   28,13   <FS>,<CR>

Таким образом, когда вы отправляете сообщение в Listener (сервер TCP / MLLP), он ищет Start Block во входящих данных. Это никогда не находит это. Это просто отбрасывает все ваше сообщение с учетом мусора. Следовательно, вы ничего не получаете от слушателя.

При реализации MLLP ваше сообщение (материал, который вы пишете на сокете) должно выглядеть что-то , как показано ниже:

<VT>MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5<FS><CR>

Обратите внимание, что <VT>, <CR> и <FS> являются заполнителями в вышеприведенном сообщении.

Вы можете обратиться к этой статье для получения подробной информации (Прочтите шаг 4 и далее):

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace SimpleMllpHl7ClientAdvanced
{
    public class Program
    {
        private static char END_OF_BLOCK = '\u001c';
        private static char START_OF_BLOCK = '\u000b';
        private static char CARRIAGE_RETURN = (char)13;
        static void Main(string[] args)
        {
            TcpClient ourTcpClient = null;
            NetworkStream networkStream = null;
            var testHl7MessageToTransmit = new StringBuilder();
            //a HL7 test message that is enveloped with MLLP as described in my article
            testHl7MessageToTransmit.Append(START_OF_BLOCK)
                .Append("MSH|^~\\&|AcmeHIS|StJohn|CATH|StJohn|20061019172719||ORM^O01|MSGID12349876|P|2.3")
                .Append(CARRIAGE_RETURN)
                .Append("PID|||20301||Durden^Tyler^^^Mr.||19700312|M|||88 Punchward Dr.^^Los Angeles^CA^11221^USA|||||||")
                .Append(CARRIAGE_RETURN)
                .Append("PV1||O|OP^^||||4652^Paulson^Robert|||OP|||||||||9|||||||||||||||||||||||||20061019172717|20061019172718")
                .Append(CARRIAGE_RETURN)
                .Append("ORC|NW|20061019172719")
                .Append(CARRIAGE_RETURN)
                .Append("OBR|1|20061019172719||76770^Ultrasound: retroperitoneal^C4|||12349876")
                .Append(CARRIAGE_RETURN)
                .Append(END_OF_BLOCK)
                .Append(CARRIAGE_RETURN);
            try
            {
                //initiate a TCP client connection to local loopback address at port 1080
                ourTcpClient = new TcpClient();
                ourTcpClient.Connect(new IPEndPoint(IPAddress.Loopback, 1080));
                Console.WriteLine("Connected to server....");
                //get the IO stream on this connection to write to
                networkStream = ourTcpClient.GetStream();
                //use UTF-8 and either 8-bit encoding due to MLLP-related recommendations
                var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());
                if (networkStream.CanWrite)
                {
                    //send a message through this connection using the IO stream
                    networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length);
                    Console.WriteLine("Data was sent data to server successfully....");
                    var receiveMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());
                    var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);
                    // Our server for this example has been designed to echo back the message
                    // keep reading from this stream until the message is echoed back
                    while (bytesReceivedFromServer > 0)
                    {
                        if (networkStream.CanRead)
                        {
                            bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);
                            if (bytesReceivedFromServer == 0)
                            {
                                break;
                            }
                        }                            
                    }
                    var receivedMessage = Encoding.UTF8.GetString(receiveMessageByteBuffer);
                    Console.WriteLine("Received message from server: {0}", receivedMessage);
                }
                Console.WriteLine("Press any key to exit...");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                //display any exceptions that occur to console
                Console.WriteLine(ex.Message);
            }
            finally
            {
                //close the IO strem and the TCP connection
                networkStream?.Close();
                ourTcpClient?.Close();
            }
        }
    }
}

Вы должны изменить следующую строку кода, как показано ниже:

var req = START_OF_BLOCK + "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5" + END_OF_BLOCK + CARRIAGE_RETURN;

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

...