一个用于测试的 HL7 Server

说明

一个用于测试的 HL7 Server。在过NIST的认证时,需要演示检验数据通过HL7进行传输,所以写了这工具。

一个用于测试的 HL7 Server_第1张图片

HL7的消息解析和编码使用了NHapi。包含两个服务:

  • ReceiveService
  • SendService

这2个服务都继承自 BaseService 

  public class BaseService
    {
        protected ManualResetEvent _ServiceExitEvent = new ManualResetEvent(true);
        protected ManualResetEvent _NeedStopEvent = new ManualResetEvent(true);
        public ManualResetEvent ServiceExitEvent { get { return _ServiceExitEvent; } }
        public enum ServiceStatus{ INITIAL, BUSY, IDLE, EXIT, ERROR };
        public ServiceStatus _ServiceStatus;
        public string _ServiceName = "";
        protected bool _ServiceStop = true;
        protected Thread _Thread = null;

        public event EventHandler NotifyEvent;
        public virtual void OnNotifyEvent(NotifyEventArgs e)
        {
            EventHandler handler = NotifyEvent;
            if (handler != null)
            {
                //e.Message += String.Format(" at {0}", DateTime.Now.ToString());
                handler(this, e);
            }
        }

        public virtual bool Start()
        {
            if (!_ServiceStop)
            {
                OnNotifyEvent(new NotifyEventArgs("service is already running"));
                return false;
            }
            OnNotifyEvent(new NotifyEventArgs("service initial"));

            _Thread = new Thread(delegate()
            {
                _ServiceExitEvent.Reset();
                _NeedStopEvent.Reset();
                _ServiceStop = false;

                this.Run();

                OnNotifyEvent(new NotifyEventArgs("service exit"));
                _ServiceStop = true;
                _ServiceExitEvent.Set();
            });

            if (_ServiceName != "")
            {
                _Thread.Name = _ServiceName;
            }
            else
            {
                _Thread.Name = this.GetType().Name;
            }
            _Thread.Start();
            return true;
        }

        protected virtual void Run(){}

        protected bool NeedExit(int timeout)
        {
            return _NeedStopEvent.WaitOne(timeout, false);
        }

        public virtual bool Stop()
        {
            _NeedStopEvent.Set();
            return true;
        }

        public void Close()
        {
            if (!_ServiceStop && (_Thread != null))
            {
                _Thread.Abort();
            }
        }
    }
}

ReceiveService

ReceiveService用于监听Socket端口,当Socket连接时,创建一个ReceiveTask进行业务处理。

                    Socket client = server.Accept();
                    if (client != null)
                    {
                        ReceiveTask rm = new ReceiveTask(client, this);
                        totalCount++;
                    }

ReceiveTask

ReceiveTask 启动一个 Thread进行数据处理。

    public class ReceiveTask
    {
        public static string parse_segment_def = "2.5.1";
        public ReceiveTask(Socket socket, ReceiveService svr)
        {
            Thread thread = new Thread(delegate()
                {
                    Receive(socket, svr);
                });
            thread.Name = "ReceiveMsg";
            thread.Start();
        } 

  protected void Receive(Socket socket, ReceiveService svr)
        {
            IPEndPoint ieClient = socket.RemoteEndPoint as IPEndPoint;
            IPEndPoint ieServer = socket.LocalEndPoint as IPEndPoint;
            svr.OnNotifyEvent(new NotifyEventArgs("receive message from " + ieClient.ToString()));

            string msg = "";
            byte[] data = new byte[1024]; ;
            int recv = 0;
            while (true)
            {
                recv = socket.Receive(data, data.Length, SocketFlags.None);
                if (recv == 0)
                {
                    break;
                }

                msg += Encoding.UTF8.GetString(data, 0, recv);
            }
            Hashtable ht = ParseMsg(msg);
            if (ht == null)
            {
                svr.OnNotifyEvent(new NotifyEventArgs("parse message error"));
                return;
            }
            string id= AddToReceiveQueue(ieClient.ToString(), msg, ieServer.ToString(), ht);
            if (id == "")
            {
                svr.OnNotifyEvent(new NotifyEventArgs("fail to connect database"));
                return;
            }
            if (!AddToReminder(id))
            {
                svr.OnNotifyEvent(new NotifyEventArgs("fail to connect database"));
                return;
            }
            socket.Close();
            ReceiveService.donetotal++;
        }

 ORU_R01消息的处理

 ORU_R01消息是常见的检验数据的消息。具体的结构可以查阅HL7的手册。

                imsg = parser.Parse(msg, ReceiveTask.parse_segment_def);
                msgtype = imsg.GetType().Name;

                if (msgtype.Equals("ORU_R01", StringComparison.OrdinalIgnoreCase))
                {
                    ORU_R01 data = imsg as ORU_R01;
                    ht.Add("MessageType", msgtype); 
                    ht.Add("MessageControlID", data.MSH.MessageControlID.Value);             
                    ORU_R01_PATIENT_RESULT p=data.GetPATIENT_RESULT(0);
                    ht.Add("PatientID", p.PATIENT.PID.GetPatientIdentifierList(0).IDNumber.Value);
                }

SendService 

SendService用于把数据发给各业务节点

    public class SendService : BaseService
    {
        public static int totalCount=0;
        public static int donetotal=0;
        protected override void Run()
        {
            List ls = null;
            do
            {
                ls = SendTask.GetTask();
                totalCount += ls.Count;
                if (ls != null)
                {
                    foreach (SendTask st in ls)
                    {
                        st.sendSvr = this;
                        if (st.Send())
                        {
                            donetotal++;
                            OnNotifyEvent(new NotifyEventArgs("id:" + st.id + "  has send successfully!"));
                        }
                        else
                        {
                            OnNotifyEvent(new NotifyEventArgs("id:" + st.id + "  has send fail!"));
                        }

                    }
                }
            } while (!NeedExit(1000));
        }
    }

SendTask 

 发送时使用SendTask进行发送 

    public class SendTask
    {
        public string id = "";
        public string sender = "";
        public string receiver = "";
        public string msg = "";
        public DateTime? msgtime = null;
        public SendService sendSvr;
        public SendTask()
        {
          
        }
        public static List GetTask()
        {
            List ls = null;
            string strSQL = "select top 20 * from SendQueue";
            ArrayList al = new ArrayList();
            DataTable dt = new DataTable();
            if (DataExecute.ExecuteSql(DataExecute.DBConnectString, strSQL, al, dt))
            {
                ls = new List(5);
                foreach (DataRow dr in dt.Rows)
                {
                    SendTask st = new SendTask();
                    st.id = dr["id"].ToString().Trim();
                    st.sender = dr["sender"].ToString().Trim();
                    st.receiver = dr["receiver"].ToString().Trim();
                    st.msg = dr["msg"].ToString().Trim();
                    DateTime time = DateTime.Now;
                    if (DateTime.TryParse(dr["msgtime"].ToString().Trim(), out time))
                    {
                        st.msgtime = time;
                    }
                    else
                    {
                        st.msgtime = null;
                    }
                    ls.Add(st);
                }
            }
            return ls;
        }

        public bool DeleteTask()
        {
            string strSQL = "insert into MsgQueue_Log(msgtime,sender,msg,receiver,senttime,sentsucc) values(?,?,?,?,getdate(),1)";
            ArrayList al = new ArrayList();
            al.Add(new OleDbParameter("msgtime", msgtime));
            al.Add(new OleDbParameter("sender", sender));
            al.Add(new OleDbParameter("msg", msg));
            al.Add(new OleDbParameter("receiver", receiver));
            DataExecute.ExecuteSql(DataExecute.DBConnectString, strSQL, al);

            strSQL = "delete from SendQueue where id=?";
            al = new ArrayList();
            al.Add(new OleDbParameter("id", id));
            return DataExecute.ExecuteSql(DataExecute.DBConnectString, strSQL, al);
        }

        public static void AddSendTask(string receiver, string msg)
        {
            string strSQL = "insert into sendqueue(msg, receiver) values(?, ?)";
            ArrayList al = new ArrayList();
            al.Add(new OleDbParameter("msg", msg));
            al.Add(new OleDbParameter("receiver", receiver));
            DataExecute.ExecuteSql(DataExecute.DBConnectString, strSQL, al);
        }

        public bool Send()
        {
            IPAddress ip = null;
            int port = 0;
            string[] sa = receiver.Split(':');
            if (sa.Count() == 2)
            {
                if (!IPAddress.TryParse(sa[0], out ip))
                {
                    sendSvr.OnNotifyEvent(new NotifyEventArgs("there are some problems on ip adress;"));
                    return false;
                }
                if (!int.TryParse(sa[1], out port))
                {
                    sendSvr.OnNotifyEvent(new NotifyEventArgs("there are some problems on port or ip;"));
                    return false;
                }
            }
            else
            {
                sendSvr.OnNotifyEvent(new NotifyEventArgs("there are some problems on ip and port adress;"));
                return false;
            }

            IPEndPoint ie = new IPEndPoint(ip, port);
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            if (client == null)
            {
                return false;
            }

            try
            {
                client.Connect(ie);
            }
            catch (SocketException e)
            {
                sendSvr.OnNotifyEvent(new NotifyEventArgs(e.Message));
                return false;
            }
            int i= client.Send(Encoding.UTF8.GetBytes(msg));
            client.Close();
            return DeleteTask();
        }
    }

你可能感兴趣的:(Microsoft,Visual,Studio开发技术分享,医疗行业开发技术分享,服务器,前端,C#,健康医疗)