小的公司是做健康管理软件的,之前对接的都是体检中心,从没有和His对接过接口。这次客户居然给我们抛了一个大难题-
HL7医疗系统传输的协议,我查了很多资料,说是现在很多医院都是用HL7来实现数据传输的,没想到是我们太low了。
之后我就决定,好好研究研究这玩意,网上能找到关于C# 这方面的资料少的可怜。
1.通过HL7Spy工具发送一次MLLP的请求
我们先来看一张图吧
这是hl7工具的界面
打开工具后,选择菜单File-New就会出现一个新窗口,接着选择菜单Tools-Seed Messages(MLLP)
会出现如图右边一样的一个配置窗口,在窗口中配置请求地址的信息,如下图
这里的配置属性,其它应该不需要多说,大家都能看的懂
唯一一个需要特别注意的是 Frame Start 和 Frame End 这两个属性 ,他们分别表示MLLP格式的一头两尾
“\x” 代表转义符,0b、1c、0d分别代表16进制编码 ,可查看:http://ascii.911cha.com/
配置完成之后回到了首页,如下图,勾选上Show的3个复选框,点击Single就可以发送了
如果是发送成功的,则会返回:AA,否则有可能返回其它错误,比如说远程连接强制关闭
下图是成功
HL7Spy下载地址:https://download.csdn.net/download/sjb2mln/11566476
2.MLLP协议一头两尾的封装,并使用TCP发送
(1).我们先来看看MLLP消息格式的封装吧
在HL7通讯协议中,消息(Message)是数据在系统之间交换的基本单元,每条消息都有各自的消息类型, 用于定义
消息目的消息类型中有触发事件。一个消息由多个段(Segment)组成,每一段都有相应的名称,用于界定其内容或功能。
而一个段又由多个数据字段(Data Field)组成。一个消息中的第一个段总是消息头段(Message head segment),它指明
了发送和接收的程序名、消息类型、以及一个唯一的消息ID号码等,接下去段的构成由消息的类型决定。如,PID段
(Patient Identification Data)包括姓名、地址、社会保险号等。一个数据字段又有可能由多个组件组成。有些消息可进
一步由事件码(event code)细分。
每个消息头代表了不同的含义,一般一个消息都是以MSH开头的。每个版本的HL7协议都有详细的介绍,这个不同的项目定义也不同。每个段都是以换行结尾,每个数据之间用“|”分割。像这个例子
MSH|^~\&|XHHIMS||PEIS||201105105737||ORU^R01^ORU_R01|4f521b61-25d6-444e-ba75-474944eef5ea|P|2.6|||NE|AL||utf-8
PID||P961234|||董^^^DONG HONG WEI||19580101|0
PV1||3|||||||||||||||||1||||||||||||||||||||H0001
ORC|SN|01D1133139||||||||||||||||31809108638^CR|^||||||||||D|||放射科^^1123
OBR|1||01D11331139|04118^数字拍片-颈椎侧位||||||||||||||||||20181010093741||CR|F|||||||||YS100163&胡|YS100163&胡||||||||||||^CR诊断报告单
OBX|1|CWE|04118^数字拍片-颈椎侧位||颈椎曲度变直,。^颈椎退行性变。||||||F||||||1123
(2).确认消息格式无误后就可以使用了
微软官网提到:块字符参数是必须将接收或通过 MLLP 适配器发送的 HL7 消息的特殊字符。 这些字符会形成一个块采用以下格式:
https://docs.microsoft.com/zh-cn/biztalk/adapters-and-accelerators/accelerator-hl7/mllp-transport-properties-dialog-box-ui-help
看了一头雾水,难道说是把
或者说把
小的最后是把消息的每一段转成字节放到字节集合中,每一段字节中用
具体代码是这样的:
//创建发送数据套接字
Socket stSend;
stSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint tempRemoteIP = new IPEndPoint(IPAddress.Parse("112.222.220.135"), 10033);
//根据IP地址和端口号创建远程终结点
EndPoint epTemp = (EndPoint)tempRemoteIP;
stSend.Connect(epTemp);
//连接远程主机的8000端口号
string str = @"MSH|^~\&|RIS||EMR||20160510152754||ORU^R01^ORU_R01|6DF1C7ED-8220-4681-A97F-5C1153C0DB71|P|2.6|||NE|AL||utf-8";
int iLength = str.Length;
//获取要发送的数据的长度
Byte[] bySend = new byte[iLength];
//根据获取的长度定义一个Byte类型数组
bySend = Encoding.UTF8.GetBytes(str.ToString());
string str1 = @"PID||1005354518|||沈英1ss12aaa^^^LI ZHONG TAO||19530615000000|2";
int iLength1 = str1.Length;
//获取要发送的数据的长度
Byte[] bySend1 = new byte[iLength1];
//根据获取的长度定义一个Byte类型数组
bySend1 = Encoding.UTF8.GetBytes(str1.ToString());
string str2 = @"PV1||2|妇肿病区^21030402^036||||||||||||||||2||||||||||||||||||||H0002|||||20160510093900";
int iLength2 = str2.Length;
//获取要发送的数据的长度
Byte[] bySend2 = new byte[iLength2];
//根据获取的长度定义一个Byte类型数组
bySend2 = Encoding.UTF8.GetBytes(str2.ToString());
string str4 = @"ORC|SN|02D2016051000478|||||||||||||||||||||||||||D|||妇产科B超室(光谷)^^210305";
int iLength4 = str4.Length;
//获取要发送的数据的长度
Byte[] bySend4 = new byte[iLength4];
//根据获取的长度定义一个Byte类型数组
bySend4 = Encoding.UTF8.GetBytes(str4.ToString());
string str5 = @"OBR|1||02D2016051000478|02766^妇彩-盆腔(三维)||||||||||||||||||20160510152727||RAD|F|||||||||102056&婧|102056&婧||||||||||||^三维彩超报告单两幅图";
int iLength5 = str4.Length;
//获取要发送的数据的长度
Byte[] bySend5 = new byte[iLength5];
//根据获取的长度定义一个Byte类型数组
bySend5 = Encoding.UTF8.GetBytes(str5.ToString());
List listData = new List();
listData.AddRange(new byte[] { 11 });
listData.AddRange(bySend);
listData.AddRange(new byte[] { 13 });
listData.AddRange(bySend1);
listData.AddRange(new byte[] { 13 });
listData.AddRange(bySend2);
listData.AddRange(new byte[] { 13 });
listData.AddRange(bySend4);
listData.AddRange(new byte[] { 13 });
listData.AddRange(bySend5);
listData.AddRange(new byte[] { 13 });
listData.AddRange(new byte[] { 28 });
listData.AddRange(new byte[] { 13 });
byte[] byteData = listData.ToArray();
int i = stSend.Send(byteData);
代码下载:https://download.csdn.net/download/sjb2mln/11568389