对于初学者来说,使用 HL7 标准构建自定义应用程序可能是一项非常艰巨的任务。多年来,我已经构建了许多自定义 HL7 服务器应用程序,如果没有该领域其他人的帮助,我无法通过 Internet 与他们进行多次讨论。随着我越来越精通,我还收到了许多其他开发人员/客户的电子邮件,他们提出的问题与我开始使用该标准时所问的问题相同。因此,本着分享的精神,我决定整理一个示例/教程,说明任何处理 HL7 V2 标准的程序员在开始时应该知道的所有最基本的基础知识。

这是我的 HL7 文章系列的一部分。在我们开始本教程之前,请快速浏览一下我之前的文章“HL7 2.x 标准的简短介绍”。请注意,本教程假设您了解 Java 或任何等效的面向对象语言。对网络和线程编程的基本了解会很有用,但不是必需的。

“一个问题说得好,问题就解决了一半。” ~查尔斯凯特林

在我们继续之前,有几件事需要注意。尽管 HL7 标准本身不推荐用于消息通信的任何特定协议,但大多数 HL7 系统使用最小底层协议进行通信。本教程将向您展示如何使用此协议在 Java 中构建自定义 HL7 服务器。本教程不涉及诸如强大的错误处理、错误记录和通知、消息转换以及数据持久性等高级主题。但是,我确实计划很快就这些主题编写另一个教程。

什么是最小底层协议?

最低层协议(通常缩写为“MLLP”)是最流行的协议,用于使用 TCP/IP 传输 HL7 消息。因为 TCP/IP 将信息作为连续的字节流传输,所以通信代码需要包装协议才能识别每条消息的开始和结束。MLLP 通常用于满足这一要求,通常使用不可打印的字符作为核心 HL7 消息信息的环绕字符。这些包装字符有助于将 HL7 消息有效负载有效地封装为数据“块”,然后将其传输到接收系统。接收系统然后解开消息有效载荷,解析消息内容,然后通过返回响应消息(称为“ACK”或“NACK”)来确认收到此消息 HL7 中的消息)也包装其消息内容。在基于 MLLP 的系统中,源系统通常不会发送任何新消息,直到接收到先前传输的消息的确认消息。

需要记住的是,我上面描述的 MLLP 块是通过使用具有单字节值的字符来构建的。这些字符必须由交换信息的站点达成一致,因为消息内容中的数据可能与用于构建承载消息所需的 MLLP 块的字节值冲突。此外,在这些情况下,使用多字节字符编码(如 UTF-16 或 UTF-32)并不理想,因为这可能导致数据的字节值可能等于 MLLP 成帧字符,从而导致与 MLLP 包络相关的错误。因此,建议仅使用单字节值编码,例如 UTF-8、ISO-8859-x 等。有关此领域的更多信息,请参阅官方 HL7 文档。

什么是套接字?

您可以将套接字视为通过 TCP 或 UDP 协议传输信息的两台机器之间连接的“终端”的抽象。大多数现代语言(如 Java、C# 和 Ruby)通过丰富的类和/或接口库提供套接字编程支持。这减轻了应用程序员必须处理 ISO(国际标准组织)标准的 OSI(开放系统互连)模型的较低层的负担。使用套接字时,程序员正在使用“会话”层,因此无需处理 OSI 堆栈较低层提供的实时数据通信服务。Java 为套接字编程提供了极好的支持(通过 java.net 包)。

您需要的工具

  • JDK 1.4 SDK 或更高版本
  • Eclipse 或任何其他 Java IDE(甚至是文本编辑器)
  • 您还可以在此处在GitHub上找到本教程中演示的所有代码

入门

我们将采取小步骤,以便涵盖所有核心要素

  1. 构建一个能够传输和接收信息的简单 TCP/IP 客户端。

  2. 构建一个简单的 TCP/IP 服务器,能够接收和回应接收到的信息

  3. 构建简单的线程支持来处理来自客户端的许多并发连接

  4. 将 MLLP 和消息确认功能添加到服务器中

  5. 编写一个小的 TCP/IP 客户端,它将传输一个虚拟的 MLLP 包装的 HL7 消息

  6. 修改服务器类以构建基于 MLLP 的解析功能

  7. 修改服务器类,构建简单的确认功能

  8. 把它们放在一起

第 1 步(共 8 步) - 构建一个能够传输和接收信息的简单 TCP/IP 客户端

这是一个非常简单的 TCP 客户端,我们将使用它来理解套接字的工作原理。我们将使用此客户端通过各个步骤主要测试我们的服务器应用程序。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#859900">package</span> <span style="color:#93a1a1">com</span><span style="color:#859900">.</span><span style="color:#555555">saravanansubramanian</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.*</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.*</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">SimpleTCPEchoClient</span> <span style="color:#859900">{</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">args</span><span style="color:#859900">)</span> <span style="color:#268bd2">throws</span> <span style="color:#93a1a1">IOException</span> <span style="color:#859900">{</span><span style="color:#93a1a1">String</span> <span style="color:#93a1a1">testMessage</span> <span style="color:#859900">=</span> <span style="color:#2aa198">"This is a test message that the client will transmit"</span><span style="color:#859900">;</span><span style="color:#dc322f">byte</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">byteBuffer</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">testMessage</span><span style="color:#859900">.</span><span style="color:#555555">getBytes</span><span style="color:#859900">();</span><span style="color:#586e75">// Create socket that is connected to a server running on the same machine on port 1080</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">socket</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">Socket</span><span style="color:#859900">(</span><span style="color:#2aa198">"localhost"</span><span style="color:#859900">,</span> <span style="color:#2aa198">1080</span><span style="color:#859900">);</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Connected to Server"</span><span style="color:#859900">);</span><span style="color:#93a1a1">InputStream</span> <span style="color:#93a1a1">in</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">getInputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">OutputStream</span> <span style="color:#93a1a1">out</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">getOutputStream</span><span style="color:#859900">();</span><span style="color:#586e75">// Send the message to the server</span><span style="color:#93a1a1">out</span><span style="color:#859900">.</span><span style="color:#555555">write</span><span style="color:#859900">(</span><span style="color:#93a1a1">byteBuffer</span><span style="color:#859900">);</span><span style="color:#93a1a1">in</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">(</span><span style="color:#93a1a1">byteBuffer</span><span style="color:#859900">);</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Message received from Server: "</span> <span style="color:#859900">+</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">String</span><span style="color:#859900">(</span><span style="color:#93a1a1">byteBuffer</span><span style="color:#859900">));</span><span style="color:#586e75">// Close the socket and its streams</span><span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">close</span><span style="color:#859900">();</span><span style="color:#859900">}</span><span style="color:#859900">}</span>
</code></span></span></span>

从代码中可以看出,“Socket”类用于与本地运行的另一个侦听器应用程序建立连接,侦听端口 1080。一旦建立连接,就可以使用输入和写入通过此连接进行读写。输出流。完成后,我们只需关闭套接字即可。

我了解到人们会忘记你说过的话,人们会忘记你做过的事,但人们永远不会忘记你给他们带来的感受。~ 玛雅安吉洛

提示:在工业强度的应用程序中,如果不能立即建立连接,或者如果现有连接由于不可预见的原因(如果服务器应用程序崩溃,或意外关闭)而断开,客户端应用程序应重试一定次数之前放弃。我不会说明这个功能,因为它不在本教程的范围内;但是,将其包含在您的 HL7 应用程序中是一项非常有用的功能。

第 2 步(共 8 步) - 构建一个简单的 TCP/IP 服务器,能够接收和回应接收到的信息

现在我们已经在上一步中看到了一个 TCP 客户端示例,这里是一个简单的 TCP 服务器,它可以通过指定的端口接受来自客户端的连接,接收它传输的任何信息,并简单地将其回显。它将永远循环运行。我们通常使用“ServerSocket”类在 Java 中构建服务器应用程序。我们服务器的这个版本一次只能接受和处理一个连接。一旦客户端连接被服务器接受,我们就可以通过这个连接提供的输入和输出流进行读写。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#859900">package</span> <span style="color:#93a1a1">com</span><span style="color:#859900">.</span><span style="color:#555555">saravanansubramanian</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.*</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.*</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">SimpleTCPEchoServer</span> <span style="color:#859900">{</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">int</span> <span style="color:#93a1a1">BUFFER_SIZE</span> <span style="color:#859900">=</span> <span style="color:#2aa198">200</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">args</span><span style="color:#859900">)</span> <span style="color:#268bd2">throws</span> <span style="color:#93a1a1">IOException</span> <span style="color:#859900">{</span><span style="color:#93a1a1">ServerSocket</span> <span style="color:#93a1a1">serverSocket</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">ServerSocket</span><span style="color:#859900">(</span><span style="color:#2aa198">1080</span><span style="color:#859900">);</span><span style="color:#dc322f">int</span> <span style="color:#93a1a1">receivedMessageSize</span><span style="color:#859900">;</span><span style="color:#dc322f">byte</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">receivedByeBuffer</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#dc322f">byte</span><span style="color:#859900">[</span><span style="color:#93a1a1">BUFFER_SIZE</span><span style="color:#859900">];</span><span style="color:#859900">while</span> <span style="color:#859900">(</span><span style="color:#cb4b16">true</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">clientSocket</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">serverSocket</span><span style="color:#859900">.</span><span style="color:#555555">accept</span><span style="color:#859900">();</span>     <span style="color:#586e75">// Get client connection</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Handling client at "</span> <span style="color:#859900">+</span><span style="color:#93a1a1">clientSocket</span><span style="color:#859900">.</span><span style="color:#555555">getInetAddress</span><span style="color:#859900">().</span><span style="color:#555555">getHostAddress</span><span style="color:#859900">()</span> <span style="color:#859900">+</span> <span style="color:#2aa198">" through port "</span> <span style="color:#859900">+</span><span style="color:#93a1a1">clientSocket</span><span style="color:#859900">.</span><span style="color:#555555">getPort</span><span style="color:#859900">());</span><span style="color:#93a1a1">InputStream</span> <span style="color:#93a1a1">in</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">clientSocket</span><span style="color:#859900">.</span><span style="color:#555555">getInputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">OutputStream</span> <span style="color:#93a1a1">out</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">clientSocket</span><span style="color:#859900">.</span><span style="color:#555555">getOutputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">receivedMessageSize</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">in</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">(</span><span style="color:#93a1a1">receivedByeBuffer</span><span style="color:#859900">);</span><span style="color:#93a1a1">out</span><span style="color:#859900">.</span><span style="color:#555555">write</span><span style="color:#859900">(</span><span style="color:#93a1a1">receivedByeBuffer</span><span style="color:#859900">,</span> <span style="color:#2aa198">0</span><span style="color:#859900">,</span> <span style="color:#93a1a1">receivedMessageSize</span><span style="color:#859900">);</span><span style="color:#93a1a1">clientSocket</span><span style="color:#859900">.</span><span style="color:#555555">close</span><span style="color:#859900">();</span>  <span style="color:#586e75">// Close the socket.  We are done serving this client</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#859900">}</span>
</code></span></span></span>

提示:在生产 HL7 服务器应用程序中,您必须通过实施坚固的错误处理以及“自动重启”功能来确保服务器不会崩溃,以防服务器崩溃。此外,如果需要快速手动干预或写入操作系统的事件日志,您将希望通过电子邮件发送错误通知。

第 3 步,共 8 步 - 构建简单的线程支持来处理来自客户端的许多并发连接

到目前为止所展示的客户端和服务器示例都是极其简化的示例,可帮助您了解套接字通信的基础知识。我们实现的服务器一次只能处理一个连接。要处理多个连接,您必须使用线程。线程在 Java 中很容易实现。但是,它们也很容易被滥用。在 Java 中实现线程时,您必须确保各个线程不会干扰彼此的工作。这是因为线程共享相同的内存。在服务器的这个修改版本中,我们实例化一个新线程,并将服务器接受的每个传入连接传递给它自己的 ConnectionHandler 类。这将确保服务器快速准备好接受下一个等待连接到服务器的客户端,而不会出现任何明显的延迟。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#859900">package</span> <span style="color:#93a1a1">com</span><span style="color:#859900">.</span><span style="color:#555555">saravanansubramanian</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.IOException</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.InputStream</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.OutputStream</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.BindException</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.ServerSocket</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.Socket</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">SimpleThreadedEchoServer</span> <span style="color:#859900">{</span><span style="color:#268bd2">private</span> <span style="color:#dc322f">int</span> <span style="color:#93a1a1">listenPort</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">SimpleThreadedEchoServer</span><span style="color:#859900">(</span><span style="color:#dc322f">int</span> <span style="color:#93a1a1">aListenPort</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">listenPort</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">aListenPort</span><span style="color:#859900">;</span><span style="color:#859900">}</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">args</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">SimpleThreadedEchoServer</span> <span style="color:#93a1a1">server</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">SimpleThreadedEchoServer</span><span style="color:#859900">(</span><span style="color:#2aa198">1080</span><span style="color:#859900">);</span><span style="color:#93a1a1">server</span><span style="color:#859900">.</span><span style="color:#555555">acceptIncomingConnections</span><span style="color:#859900">();</span><span style="color:#859900">}</span><span style="color:#268bd2">private</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">acceptIncomingConnections</span><span style="color:#859900">()</span> <span style="color:#859900">{</span><span style="color:#859900">try</span> <span style="color:#859900">{</span><span style="color:#93a1a1">ServerSocket</span> <span style="color:#93a1a1">server</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">ServerSocket</span><span style="color:#859900">(</span><span style="color:#93a1a1">listenPort</span><span style="color:#859900">,</span> <span style="color:#2aa198">5</span><span style="color:#859900">);</span> <span style="color:#586e75">//Accept up to 5 clients in the queue</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Server has been started"</span><span style="color:#859900">);</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">clientSocket</span> <span style="color:#859900">=</span> <span style="color:#cb4b16">null</span><span style="color:#859900">;</span><span style="color:#859900">while</span> <span style="color:#859900">(</span><span style="color:#cb4b16">true</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">clientSocket</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">server</span><span style="color:#859900">.</span><span style="color:#555555">accept</span><span style="color:#859900">();</span><span style="color:#93a1a1">handleIncomingConnection</span><span style="color:#859900">(</span><span style="color:#93a1a1">clientSocket</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">}</span> <span style="color:#859900">catch</span> <span style="color:#859900">(</span><span style="color:#93a1a1">BindException</span> <span style="color:#93a1a1">e</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Unable to bind to port "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">listenPort</span><span style="color:#859900">);</span><span style="color:#859900">}</span> <span style="color:#859900">catch</span> <span style="color:#859900">(</span><span style="color:#93a1a1">IOException</span> <span style="color:#93a1a1">e</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Unable to instantiate a ServerSocket on port: "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">listenPort</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">handleIncomingConnection</span><span style="color:#859900">(</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">aConnectionToHandle</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">new</span> <span style="color:#268bd2">Thread</span><span style="color:#859900">(</span><span style="color:#859900">new</span> <span style="color:#93a1a1">ConnectionHandler</span><span style="color:#859900">(</span><span style="color:#93a1a1">aConnectionToHandle</span><span style="color:#859900">)).</span><span style="color:#555555">start</span><span style="color:#859900">();</span><span style="color:#859900">}</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">ConnectionHandler</span> <span style="color:#268bd2">implements</span> <span style="color:#93a1a1">Runnable</span> <span style="color:#859900">{</span><span style="color:#268bd2">private</span> <span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">connection</span><span style="color:#859900">;</span><span style="color:#268bd2">private</span> <span style="color:#dc322f">int</span> <span style="color:#93a1a1">receivedMessageSize</span><span style="color:#859900">;</span><span style="color:#268bd2">private</span> <span style="color:#dc322f">byte</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">receivedByeBuffer</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#dc322f">byte</span><span style="color:#859900">[</span><span style="color:#93a1a1">BUFFER_SIZE</span><span style="color:#859900">];</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">int</span> <span style="color:#93a1a1">BUFFER_SIZE</span> <span style="color:#859900">=</span> <span style="color:#2aa198">32</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">ConnectionHandler</span><span style="color:#859900">(</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">aClientSocket</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">connection</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">aClientSocket</span><span style="color:#859900">;</span><span style="color:#859900">}</span><span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">run</span><span style="color:#859900">()</span> <span style="color:#859900">{</span><span style="color:#859900">try</span> <span style="color:#859900">{</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Handling client at "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">connection</span><span style="color:#859900">.</span><span style="color:#555555">getInetAddress</span><span style="color:#859900">().</span><span style="color:#555555">getHostAddress</span><span style="color:#859900">()</span><span style="color:#859900">+</span> <span style="color:#2aa198">" on port "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">connection</span><span style="color:#859900">.</span><span style="color:#555555">getPort</span><span style="color:#859900">());</span><span style="color:#93a1a1">InputStream</span> <span style="color:#93a1a1">in</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">connection</span><span style="color:#859900">.</span><span style="color:#555555">getInputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">OutputStream</span> <span style="color:#93a1a1">out</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">connection</span><span style="color:#859900">.</span><span style="color:#555555">getOutputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">receivedMessageSize</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">in</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">(</span><span style="color:#93a1a1">receivedByeBuffer</span><span style="color:#859900">);</span><span style="color:#93a1a1">out</span><span style="color:#859900">.</span><span style="color:#555555">write</span><span style="color:#859900">(</span><span style="color:#93a1a1">receivedByeBuffer</span><span style="color:#859900">,</span> <span style="color:#2aa198">0</span><span style="color:#859900">,</span> <span style="color:#93a1a1">receivedMessageSize</span><span style="color:#859900">);</span><span style="color:#93a1a1">connection</span><span style="color:#859900">.</span><span style="color:#555555">close</span><span style="color:#859900">();</span>  <span style="color:#586e75">// Close the socket.  We are done serving this client</span><span style="color:#859900">}</span> <span style="color:#859900">catch</span> <span style="color:#859900">(</span><span style="color:#93a1a1">IOException</span> <span style="color:#93a1a1">e</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Error handling a client: "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">e</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#859900">}</span>
</code></span></span></span>

提示:在世界各地使用的许多 HL7 系统中,多个客户端可能会同时尝试连接到服务器(在不同端口或同一端口上)。服务器应用程序必须能够在没有太多延迟的情况下接受所有这些连接,然后接收、处理和确认从每个客户端收到的任何信息。

第 4 步(共 8 步) - 将 MLLP 和消息确认功能添加到服务器中

尽管到目前为止所展示的示例允许客户端和服务器来回传输简单的文本消息,但这还不足以与 HL7 系统进行通信。与 HL7 系统的通信需要使用 MLLP 协议和消息确认功能。在这一步中,我们将使用我们现有的服务器并添加代码以启用 MLLP 支持。我们还将在服务器中实现功能,以创建一个简单的确认消息并将其传输回客户端应用程序。

更多关于 MLLP

在本教程的开头,我将 MLLP 协议描述为一种包装协议,其中核心 HL7 消息被包裹在特殊字符中,以向接收应用程序发送消息信息传输的开始和结束信号。在处理 MLLP 时,您将配置和使用基本上三个字符组。它们是开始块结束块段分隔符. 使用 MLLP 协议传输的 HL7 消息以起始块字符为前缀,消息段以段分隔符终止,然后消息本身以两个字符终止,即结束块和回车符。大多数情况下,通常用于表示起始块的字符是 VT(垂直制表符),即 ASCII 11。FS(文件分隔符)、ASCII 28 用于表示结束块,使用 CR(ASCII 13)用于回车。

以下是使用与 MLLP 相关的包装字符“封装”传输的观察请求 HL7 消息的示例:

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code><SB>MSH^~\&199809091533ORU^R01856369D2.2<CR>
PID139385000343456<CR>
ORC123112312RAD19980909-0005<CR><EB><CR>
</code></span></span></span>

第 5 步(共 8 步) - 编写一个小型 TCP/IP 客户端,该客户端将传输一个虚拟的 MLLP 包装的 HL7 消息

这是修改后的原始 TCP 客户端以传输示例 HL7 消息。注意测试消息是如何用特殊字符包装的,如前所述(以粗体突出显示)。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#859900">package</span> <span style="color:#93a1a1">com</span><span style="color:#859900">.</span><span style="color:#555555">saravanansubramanian</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.net.*</span><span style="color:#859900">;</span><span style="color:#859900">import</span> <span style="color:#93a1a1">java.io.*</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">SimpleMLLPBasedTCPClient</span> <span style="color:#859900">{</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">char</span> <span style="color:#93a1a1">END_OF_BLOCK</span> <span style="color:#859900">=</span> <span style="color:#2aa198">'\u001c'</span><span style="color:#859900">;</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">char</span> <span style="color:#93a1a1">START_OF_BLOCK</span> <span style="color:#859900">=</span> <span style="color:#2aa198">'\u000b'</span><span style="color:#859900">;</span><span style="color:#268bd2">private</span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">char</span> <span style="color:#93a1a1">CARRIAGE_RETURN</span> <span style="color:#859900">=</span> <span style="color:#2aa198">13</span><span style="color:#859900">;</span><span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">args</span><span style="color:#859900">)</span> <span style="color:#268bd2">throws</span> <span style="color:#93a1a1">IOException</span> <span style="color:#859900">{</span><span style="color:#586e75">// Create a socket to connect to server running locally on port 1080</span><span style="color:#93a1a1">Socket</span> <span style="color:#93a1a1">socket</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">Socket</span><span style="color:#859900">(</span><span style="color:#2aa198">"localhost"</span><span style="color:#859900">,</span> <span style="color:#2aa198">1080</span><span style="color:#859900">);</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Connected to Server"</span><span style="color:#859900">);</span><span style="color:#93a1a1">StringBuffer</span> <span style="color:#93a1a1">testHL7MessageToTransmit</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">StringBuffer</span><span style="color:#859900">();</span><span style="color:#93a1a1">testHL7MessageToTransmit</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">START_OF_BLOCK</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"MSH|^~\\&|AcmeHIS|StJohn|CATH|StJohn|20061019172719||ORM^O01|MSGID12349876|P|2.3"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"PID|||20301||Durden^Tyler^^^Mr.||19700312|M|||88 Punchward Dr.^^Los Angeles^CA^11221^USA|||||||"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"PV1||O|OP^^||||4652^Paulson^Robert|||OP|||||||||9|||||||||||||||||||||||||20061019172717|20061019172718"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"ORC|NW|20061019172719"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"OBR|1|20061019172719||76770^Ultrasound: retroperitoneal^C4|||12349876"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">END_OF_BLOCK</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">);</span><span style="color:#93a1a1">InputStream</span> <span style="color:#93a1a1">in</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">getInputStream</span><span style="color:#859900">();</span><span style="color:#93a1a1">OutputStream</span> <span style="color:#93a1a1">out</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">getOutputStream</span><span style="color:#859900">();</span><span style="color:#586e75">// Send the MLLP-wrapped HL7 message to the server</span><span style="color:#93a1a1">out</span><span style="color:#859900">.</span><span style="color:#555555">write</span><span style="color:#859900">(</span><span style="color:#93a1a1">testHL7MessageToTransmit</span><span style="color:#859900">.</span><span style="color:#555555">toString</span><span style="color:#859900">().</span><span style="color:#555555">getBytes</span><span style="color:#859900">());</span><span style="color:#dc322f">byte</span><span style="color:#859900">[]</span> <span style="color:#93a1a1">byteBuffer</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#dc322f">byte</span><span style="color:#859900">[</span><span style="color:#2aa198">200</span><span style="color:#859900">];</span><span style="color:#93a1a1">in</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">(</span><span style="color:#93a1a1">byteBuffer</span><span style="color:#859900">);</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Received from Server: "</span> <span style="color:#859900">+</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">String</span><span style="color:#859900">(</span><span style="color:#93a1a1">byteBuffer</span><span style="color:#859900">));</span><span style="color:#586e75">// Close the socket and its streams</span><span style="color:#93a1a1">socket</span><span style="color:#859900">.</span><span style="color:#555555">close</span><span style="color:#859900">();</span><span style="color:#859900">}</span><span style="color:#859900">}</span>
</code></span></span></span>

第 6 步(共 8 步) - 修改服务器类以构建基于 MLLP 的解析功能

在这一步中,我们将向服务器(在连接处理程序类中)添加一个方法来处理使用套接字流从客户端接收到的字符流的解析。此解析例程的要点是,它将期望 MLLP 以正确的顺序/序列包装字符。如果没有,它将抛出异常并关闭与客户端的连接。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#268bd2">public</span> <span style="color:#93a1a1">String</span> <span style="color:#268bd2">getMessage</span><span style="color:#859900">(</span><span style="color:#93a1a1">InputStream</span> <span style="color:#93a1a1">anInputStream</span><span style="color:#859900">)</span> <span style="color:#268bd2">throws</span> <span style="color:#93a1a1">IOException</span>  <span style="color:#859900">{</span><span style="color:#dc322f">boolean</span> <span style="color:#93a1a1">end_of_message</span> <span style="color:#859900">=</span> <span style="color:#cb4b16">false</span><span style="color:#859900">;</span><span style="color:#93a1a1">StringBuffer</span> <span style="color:#93a1a1">parsedMessage</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">StringBuffer</span><span style="color:#859900">();</span><span style="color:#dc322f">int</span> <span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">=</span> <span style="color:#2aa198">0</span><span style="color:#859900">;</span><span style="color:#859900">try</span> <span style="color:#859900">{</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">anInputStream</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">();</span><span style="color:#859900">}</span> <span style="color:#859900">catch</span> <span style="color:#859900">(</span><span style="color:#93a1a1">SocketException</span> <span style="color:#93a1a1">e</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">System</span><span style="color:#859900">.</span><span style="color:#555555">out</span><span style="color:#859900">.</span><span style="color:#555555">println</span><span style="color:#859900">(</span><span style="color:#2aa198">"Unable to read from socket stream. "</span><span style="color:#859900">+</span> <span style="color:#2aa198">"Connection may have been closed: "</span> <span style="color:#859900">+</span> <span style="color:#93a1a1">e</span><span style="color:#859900">.</span><span style="color:#555555">getMessage</span><span style="color:#859900">());</span><span style="color:#859900">return</span> <span style="color:#cb4b16">null</span><span style="color:#859900">;</span><span style="color:#859900">}</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">==</span> <span style="color:#93a1a1">END_OF_TRANSMISSION</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">return</span> <span style="color:#cb4b16">null</span><span style="color:#859900">;</span><span style="color:#859900">}</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">!=</span> <span style="color:#93a1a1">START_OF_BLOCK</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">throw</span> <span style="color:#859900">new</span> <span style="color:#268bd2">RuntimeException</span><span style="color:#859900">(</span><span style="color:#2aa198">"Start of block character has not been received"</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">while</span> <span style="color:#859900">(!</span><span style="color:#93a1a1">end_of_message</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">anInputStream</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">();</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">==</span> <span style="color:#93a1a1">END_OF_TRANSMISSION</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">throw</span> <span style="color:#859900">new</span> <span style="color:#268bd2">RuntimeException</span><span style="color:#859900">(</span><span style="color:#2aa198">"Message terminated without end of message character"</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">==</span> <span style="color:#93a1a1">END_OF_BLOCK</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">anInputStream</span><span style="color:#859900">.</span><span style="color:#555555">read</span><span style="color:#859900">();</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">characterReceived</span> <span style="color:#859900">!=</span> <span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">throw</span> <span style="color:#859900">new</span> <span style="color:#268bd2">RuntimeException</span><span style="color:#859900">(</span><span style="color:#2aa198">"End of message character must be followed by a carriage return character"</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#93a1a1">end_of_message</span> <span style="color:#859900">=</span> <span style="color:#cb4b16">true</span><span style="color:#859900">;</span><span style="color:#859900">}</span> <span style="color:#859900">else</span> <span style="color:#859900">{</span><span style="color:#93a1a1">parsedMessage</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">((</span><span style="color:#dc322f">char</span><span style="color:#859900">)</span> <span style="color:#93a1a1">characterReceived</span><span style="color:#859900">);</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#859900">return</span> <span style="color:#93a1a1">parsedMessage</span><span style="color:#859900">.</span><span style="color:#555555">toString</span><span style="color:#859900">();</span><span style="color:#859900">}</span>
</code></span></span></span>

第 7 步(共 8 步) - 修改服务器类以构建简单的确认功能

接下来,我们将向服务器添加另外两个方法(同样,在连接处理程序类中)以构建简单的 HL7 消息确认以传输回客户端。第一种方法是帮助构建基本的消息确认功能。下面显示的方法是一个验证简化示例,以帮助理解如何构造确认消息。实际上,您将重新传输 MSH 和 MSA 段中的其他字段,例如发送设施、发送应用程序、应用程序版本和其他有用信息。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#268bd2">private</span> <span style="color:#93a1a1">String</span> <span style="color:#268bd2">getSimpleAcknowledgementMessage</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span> <span style="color:#93a1a1">aParsedHL7Message</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">aParsedHL7Message</span> <span style="color:#859900">==</span> <span style="color:#cb4b16">null</span><span style="color:#859900">)</span><span style="color:#859900">throw</span> <span style="color:#859900">new</span> <span style="color:#268bd2">RuntimeException</span><span style="color:#859900">(</span><span style="color:#2aa198">"Invalid HL7 message for parsing operation. Please check your inputs"</span><span style="color:#859900">);</span><span style="color:#93a1a1">String</span> <span style="color:#93a1a1">messageControlID</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">getMessageControlID</span><span style="color:#859900">(</span><span style="color:#93a1a1">aParsedHL7Message</span><span style="color:#859900">);</span><span style="color:#93a1a1">StringBuffer</span> <span style="color:#93a1a1">ackMessage</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">StringBuffer</span><span style="color:#859900">();</span><span style="color:#93a1a1">ackMessage</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">ackMessage</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">START_OF_BLOCK</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"MSH|^~\\&|||||||ACK||P|2.2"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#2aa198">"MSA|AA|"</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">messageControlID</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">END_OF_BLOCK</span><span style="color:#859900">)</span><span style="color:#859900">.</span><span style="color:#555555">append</span><span style="color:#859900">(</span><span style="color:#93a1a1">CARRIAGE_RETURN</span><span style="color:#859900">);</span><span style="color:#859900">return</span> <span style="color:#93a1a1">ackMessage</span><span style="color:#859900">.</span><span style="color:#555555">toString</span><span style="color:#859900">();</span><span style="color:#859900">}</span>
</code></span></span></span>

第二种支持方法是在确认消息中帮助解析接收到的需要重传的消息的消息控制id。下面第二个例程的某些部分可能看起来有点矫枉过正,但我​​故意这样做是为了说明如何使用字段分隔符解析 HL7 消息中的字段(一旦您可以解析一个字段,您就可以应用相同的概念来执行其他)。您可能还想在未找到消息控件 ID 时引发异常。

<span style="color:#5c5962"><span style="background-color:#ffffff"><span style="background-color:#f5f6fa"><code>    <span style="color:#268bd2">private</span> <span style="color:#93a1a1">String</span> <span style="color:#268bd2">getMessageControlID</span><span style="color:#859900">(</span><span style="color:#93a1a1">String</span> <span style="color:#93a1a1">aParsedHL7Message</span><span style="color:#859900">)</span> <span style="color:#859900">{</span><span style="color:#dc322f">int</span> <span style="color:#93a1a1">fieldCount</span> <span style="color:#859900">=</span> <span style="color:#2aa198">0</span><span style="color:#859900">;</span><span style="color:#93a1a1">StringTokenizer</span> <span style="color:#93a1a1">tokenizer</span> <span style="color:#859900">=</span> <span style="color:#859900">new</span> <span style="color:#93a1a1">StringTokenizer</span><span style="color:#859900">(</span><span style="color:#93a1a1">aParsedHL7Message</span><span style="color:#859900">,</span> <span style="color:#93a1a1">FIELD_DELIMITER</span><span style="color:#859900">);</span><span style="color:#859900">while</span> <span style="color:#859900">(</span><span style="color:#93a1a1">tokenizer</span><span style="color:#859900">.</span><span style="color:#555555">hasMoreElements</span><span style="color:#859900">())</span><span style="color:#859900">{</span><span style="color:#93a1a1">String</span> <span style="color:#93a1a1">token</span> <span style="color:#859900">=</span> <span style="color:#93a1a1">tokenizer</span><span style="color:#859900">.</span><span style="color:#555555">nextToken</span><span style="color:#859900">();</span><span style="color:#93a1a1">fieldCount</span><span style="color:#859900">++;</span><span style="color:#859900">if</span> <span style="color:#859900">(</span><span style="color:#93a1a1">fieldCount</span> <span style="color:#859900">==</span> <span style="color:#93a1a1">MESSAGE_CONTROL_ID_LOCATION</span><span style="color:#859900">){</span><span style="color:#859900">return</span> <span style="color:#93a1a1">token</span><span style="color:#859900">;</span><span style="color:#859900">}</span><span style="color:#859900">}</span><span style="color:#859900">return</span> <span style="color:#2aa198">""</span><span style="color:#859900">;</span><span style="color:#859900">}</span>
</code></span></span></span>

第 8 步(共 8 步) - 将它们放在一起

我们完了。如果您需要的话,我们基本上已经看到了从头开始组装自定义 HL7 应用程序所需的所有细节。通常,HL7 程序员不会重新发明轮子,而是使用免费软件或商业工具包来构建他/她的 HL7 消息传递应用程序。但是,即使在处理工具包时,也需要对套接字、MLLP 协议以及本教程中介绍的消息确认基础有基本的了解。我计划使用一个名为“HAPI”的流行 HL7 库编写关于 HL7 编程的整个系列文章。所以,请尽快在我的博客上注意这一点。

您可以在此处在GitHub上找到本教程中使用的完整源代码

结论

构建能够 24/7 全天候运行且无人值守的强大 HL7 系统并不容易。对于大多数程序员来说,一旦他们克服了最初的套接字编程障碍,HL7 2.x 相关编程中的大部分问题将围绕支持任何解析、转换、格式化和存储要求。随着 HL7 3.0* 标准越来越多地开始使用,这些问题应该会慢慢消失。但是,HL7 2.x 标准目前不会有任何进展。我们应该期望它在他们完全退休之前至少再坚持 10 年。在此之前,我们将不得不继续寻求为 HL7 消息传递构建更优雅、更坚固的解决方案。

提示:您需要设计系统,以便 MLLP 字符分组是可配置的。这样,客户可以将它们更改为他们需要的任何内容。您还应该允许围绕消息确认功能进行一些配置,例如传输的有关处理系统及其位置的信息(进入“MSH”段)。此外,还有用于指示系统是处于“测试”模式还是“生产模式”的配置。过去,我设置的可配置内容还包括消息控制 ID 起始编号或编号模式、电子邮件地址和错误日志位置(用于错误通知),以及连接重试尝试。

* - HL7 3.0 (RIM) 从未像许多人想象的那样在 2000 年代初及以后得到广泛采用,包括替换基于 V2 的消息接口。请参阅我关于 V3 标准的文章,以获取有关该标准尝试做什么、其优势、劣势以及它在现在漫长的医疗保健信息学历史中的遗产的更多信息。

原文链接:HL7 Programming using Java - Saravanan Subramanian

使用 Java 进行 HL7 编程相关推荐

  1. Scala程序设计:Java虚拟机多核编程实战(国内第一本Scala图书)

    Scala程序设计:Java虚拟机多核编程实战(国内第一本Scala图书) 基本信息 作者: (美)Venkat Subramaniam  译者: 郑晔 李剑 丛书名: 图灵程序设计丛书 出版社:人民 ...

  2. Netty:Java 领域网络编程的王者

    一.简介 1. 课程背景 分布式系统的根基在于网络编程,而 Netty 是 Java 领域网络编程的王者. 2. 课程内容 第一部分 NIO 编程,三大组件 第二部分 Netty 入门学习,Event ...

  3. Java 7并发编程实战手册

    2019独角兽企业重金招聘Python工程师标准>>> Java 7并发编程实战手册 本书是 Java 7 并发编程的实战指南,介绍了Java 7 并发API 中大部分重要而有用的机 ...

  4. JAVA网络IO编程

    2019独角兽企业重金招聘Python工程师标准>>> JAVA网络IO编程(BIO NIO AIO) 一.传统的BIO编程 1.网络编程的基本模型是C/S模型,即两个进程间的通信. ...

  5. 《Java Web高级编程——涵盖WebSockets、Spring Framework、JPA H

    2019独角兽企业重金招聘Python工程师标准>>> <Java Web高级编程--涵盖WebSockets.Spring Framework.JPA Hibernate和S ...

  6. Java 7 并发编程指南

    原文是发表在并发编程网上翻译后的 <Java 7 并发编程指南>,这里对其中的目录做个更加详细的描述,并且写出了重点说明,方便日后快速查阅.建议仔细查看每节的代码实现,非常具有参考价值.可 ...

  7. 阿里云 刷新缓存 java_【从入门到放弃-Java】并发编程-NIO-Buffer

    前言 上篇[从入门到放弃-Java]并发编程-NIO-Channel中我们学习到channel是双向通道,数据通过channel在实体(文件.socket)和缓冲区(buffer)中可以双向传输. 本 ...

  8. Java Review - 并发编程_ 回环屏障CyclicBarrier原理源码剖析

    文章目录 Pre 小Demo 类图结构 CyclicBarrier核心方法源码解读 int await() int await(long timeout, TimeUnit unit) int dow ...

  9. Java Review - 并发编程_ScheduledThreadPoolExecutor原理源码剖析

    文章目录 概述 类结构 核心方法&源码解析 schedule(Runnable command, long delay,TimeUnit unit) scheduleWithFixedDela ...

  10. Java Review - 并发编程_ArrayBlockingQueue原理源码剖析

    文章目录 概述 类图结构 构造函数 主要方法源码解析 offer操作 put操作 poll操作 take操作 peek操作 size 小结 概述 Java Review - 并发编程_LinkedBl ...

最新文章

  1. Android 开发入门学习
  2. PHP HashTable总结
  3. Java内存泄露的理解与解决
  4. 北斗导航 | GPS卫星导航技术重要人物简介
  5. 【结论】Number(jzoj(gz) 1781)
  6. kind富文本编辑器_在VueJs中集成UEditor 富文本编辑器
  7. java 为何 无效_java – 为什么compareTo无效导致Collections.sor...
  8. Codeforces-GYM101873 G Water Testing 皮克定理
  9. EVENT:10228 trace application of redo by kcocbk
  10. 微软MSDN原版所有系统合集我告诉你,Windows历史操作系统索引
  11. csdn官网(csdn官网免费下载)
  12. UDS诊断服务基础篇之27
  13. android视频的编辑(录制,裁剪,合成)(1)
  14. 浪涌、群脉冲、ESD等级标准
  15. 个人用户永久免费,可自动升级版Excel插件,使用VSTO开发,Excel催化剂功能第12波-快速生成、读取、导出条形码二维码...
  16. 笔记本玩游戏画面间歇卡顿的终极解决方案 ThrottleStop使用教程
  17. Shell学习(12)文件操作
  18. 科研:中科大论文查新查引所用论文数据库
  19. jenkin swindows启动_Windows下Nginx的启动、停止等命令
  20. 知识点滴 - 喝咖啡么

热门文章

  1. 【磨刀不误砍柴工】由传递函数绘出频率响应图
  2. 最全面贴片电阻知识,封装、尺寸、最大承受功率及选型统统包括-电子技术方案|电路图讲解
  3. CentOS7部署k8s集群
  4. Python读取Excel数据并进行函数拟合
  5. 如何识别英文单词java,自动识别英文单词显示(Android+Java)
  6. 泰坦尼克号幸存者预测
  7. 袖珍磁带的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  8. A Survey on Knowledge Graph-Based Recommender
  9. 智能路由器自建服务器,路由器怎么设置服务器_路由器搭建服务器
  10. 夜店App不应该是SNS,而应该是O2O