一個用于測試的 HL7 Server

說明

一個用于測試的 HL7 Server。在過NIST的認證時,需要演示檢驗數據通過HL7進行傳輸,所以寫了這工具。

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<NotifyEventArgs> NotifyEvent;public virtual void OnNotifyEvent(NotifyEventArgs e){EventHandler<NotifyEventArgs> 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<SendTask> 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<SendTask> GetTask(){List<SendTask> 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<SendTask>(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();}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67646.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67646.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67646.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 Go 和 gqlgen 實現 GraphQL API:實戰指南

使用 Go 和 gqlgen 實現 GraphQL API&#xff1a;實戰指南 在本文中&#xff0c;我將分享如何使用 Go 語言和 gqlgen 框架實現一個完整的 GraphQL API。我們將構建一個包含用戶、文章和評論功能的博客系統 API。 技術棧 Gogqlgen (GraphQL 框架)MySQL (數據存儲)Redis (緩存…

matlab快速入門(2)-- 數據處理與可視化

MATLAB的數據處理 1. 數據導入與導出 (1) 從文件讀取數據 Excel 文件&#xff1a;data readtable(data.xlsx); % 讀取為表格&#xff08;Table&#xff09;CSV 文件&#xff1a;data readtable(data.csv); % 自動處理表頭和分隔符文本文件&#xff1a;data load(data.t…

洛谷題目 P5994 [PA 2014] Kuglarz 題解 (本題較難)

題目傳送門&#xff1a; P5994 [PA 2014] Kuglarz - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) 前言&#xff1a; 本題涉及到最小生成樹中的 kruskal 算法和并查集算法&#xff0c;圖論基礎概念兩大知識點&#xff0c;瞎按對萊索沒有學過圖論的或最小生成樹的可能會對這道…

消息隊列篇--通信協議篇--網絡通信模型(OSI7層參考模型,TCP/IP分層模型)

一、OSI參考模型&#xff08;Open Systems Interconnection Model&#xff09; OSI參考模型是一個用于描述和標準化網絡通信功能的七層框架。它由國際標準化組織&#xff08;ISO&#xff09;提出&#xff0c;旨在為不同的網絡設備和協議提供一個通用的語言和結構&#xff0c;以…

C# Winform制作一個登錄系統

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登錄 {p…

10.7 LangChain Models深度解析:解鎖大模型集成與調優的全景攻略

LangChain Models深度解析:解鎖大模型集成與調優的全景攻略 關鍵詞: LangChain Models模塊、大模型集成、LLM調用優化、多模型管理、本地模型部署 一、Models模塊的定位:大模型應用的“中央調度器” 傳統開發的痛點: 碎片化集成:每個模型需單獨編寫適配代碼性能黑洞:缺…

記一次STM32編譯生成BIN文件過大的問題(基于STM32CubeIDE)

文章目錄 問題描述解決方法更多拓展 問題描述 最近在一個項目中使用了 STM32H743 單片機&#xff08;基于 STM32CubeIDE GCC 開發&#xff09;&#xff0c;它的內存分為了 DTCMRAM RAM_D1 RAM_D2 …等很多部分。其中 DTCM 的速度是比通常的內存要快的&#xff0c;缺點是不支持…

996引擎 -地圖-添加安全區

996引擎 -地圖-添加安全區 文件位置配置 cfg_startpoint.xls特效效果1345參考資料文件位置 文件位置服務端D:\996M2-lua\MirServer-lua\Mir200客戶端D:\996M2-lua\996M2_debug\dev配置 cfg_startpoint.xls 服務端\Mir200\Envir\DATA\cfg_startpoint.xls 填歪了也有可能只畫一…

【leetcode強化練習·二叉樹】同時運用兩種思維解題

本文參考labuladong算法筆記[【強化練習】同時運用兩種思維解題 | labuladong 的算法筆記] 有的題目可以同時用「遍歷」和「分解問題」兩種思路來解&#xff0c;你可以利用這些題目訓練自己的思維。 559. N 叉樹的最大深度 | 力扣 | LeetCode | 給定一個 N 叉樹&#xff0c;…

棧和隊列特別篇:棧和隊列的經典算法問題

圖均為手繪,代碼基于vs2022實現 系列文章目錄 數據結構初探: 順序表 數據結構初探:鏈表之單鏈表篇 數據結構初探:鏈表之雙向鏈表篇 鏈表特別篇:鏈表經典算法問題 數據結構:棧篇 數據結構:隊列篇 文章目錄 系列文章目錄前言一.有效的括號(leetcode 20)二.用隊列實現棧(leetcode…

ios swift畫中畫技術嘗試

繼上篇&#xff1a;iOS swift 后臺運行應用嘗試失敗-CSDN博客 為什么想到畫中畫&#xff0c;起初是看到后臺模式里有一個picture in picture&#xff0c;去了解了后發現這個就是小窗口視頻播放&#xff0c;方便用戶執行多任務。看小窗口視頻的同時&#xff0c;可以作其他的事情…

OpenAI推出o3-mini推理模型,首次免費開放,性能超越o1,AIME測試準確率高達87.3%

OpenAI在2025年初推出了一款新的推理模型o3-mini&#xff0c;這款模型標志著公司在提升性能的同時也降低了成本&#xff0c;并且首次向免費用戶提供訪問權限。o3-mini是OpenAI推理系列中最新、最具成本效益的模型&#xff0c;在科學、數學、編程等領域的性能顯著超越了之前的o1…

人生不止于職業發展

0 你的問題&#xff0c;我知道&#xff01; 工作意義是啥&#xff1f;職業發展在人生啥角色&#xff1f; 1 工作意義 農村人努力學習考上大學&#xff0c;得好工作&#xff0c;為逃離同村同齡人十幾歲就工廠打工命運&#xff0c;過不凡人生&#xff0c;實現改命的唯一途徑。…

【算法設計與分析】實驗3:動態規劃—最長公共子序列

目錄 一、實驗目的 二、實驗環境 三、實驗內容 四、核心代碼 五、記錄與處理 六、思考與總結 七、完整報告和成果文件提取鏈接 一、實驗目的 掌握動態規劃求解問題的思想&#xff1b;針對不同的問題&#xff0c;會利用動態規劃進行設計求解以及時間復雜度分析&#xff0…

動手學圖神經網絡(3):利用圖神經網絡進行節點分類 從理論到實踐

利用圖神經網絡進行節點分類:從理論到實踐 前言 在之前的學習中,大家對圖神經網絡有了初步的了解。本次教程將深入探討如何運用圖神經網絡(GNNs)來解決節點分類問題。在節點分類任務里,大家往往僅掌握少量節點的真實標簽,卻要推斷出其余所有節點的標簽,這屬于歸納式學…

單片機串口打印printf函數顯示內容(固件庫開發)

1.hal_usart.c 文件 #include <stdio.h> #include "hal_usart.h" #include "stm32F10x.h"//**要根據 使用的是哪個串口 對應修改 串口號 eg&#xff1a;USART1** void USART_PUTC(char ch) {/* 等待數據寄存器為空 */while((USART1->SR & …

網關登錄校驗

網關登錄校驗 單體架構時我們只需要完成一次用戶登錄、身份校驗&#xff0c;就可以在所有業務中獲取到用戶信息。而微服務拆分后&#xff0c;每個微服務都獨立部署&#xff0c;不再共享數據。也就意味著每個微服務都需要做登錄校驗&#xff0c;這顯然不可取。 鑒權思路分析 …

wxwidgets直接獲取系統圖標,效果類似QFileIconProvider

目前只做了windows版本&#xff0c;用法類似QFileIconProvider // 頭文件 #ifndef WXFILEICONPROVIDER_H #define WXFILEICONPROVIDER_H#include <wx/wx.h> #include <wx/icon.h> #include <wx/image.h> #include <wx/bmpcbox.h> // Include for wxB…

我的創作紀念日——成為創作者的 第365天(1年)

機緣 考研的結果讓我感到一陣絕望&#xff0c;就像單片機突然死機一樣&#xff0c;所有的努力像是被一場意外的中斷指令打亂了邏輯流程。曾經本科時因為競賽拿了一堆獎&#xff0c;內心充滿虛榮心和成就感&#xff0c;總覺得自己是一個“天選之子”&#xff0c;但考研的失利卻像…

React 封裝高階組件 做路由權限控制

React 高階組件是什么 官方解釋∶ 高階組件&#xff08;HOC&#xff09;是 React 中用于復用組件邏輯的一種高級技巧。HOC 自身不是 React API 的一部分&#xff0c;它是一種基于 React 的組合特性而形成的設計模式。 高階組件&#xff08;HOC&#xff09;就是一個函數&…