/// <summary> Reserves a future incoming message by ack ID. When the incoming message /// with the given ack ID arrives, the message will be available through /// the returned MessageReceipt. /// </summary> protected internal virtual NuGenMessageReceipt reserveResponse(System.String messageID) { NuGenMessageReceipt mr = new NuGenMessageReceipt(); receipts[messageID] = mr; return(mr); }
/// <summary> Sends a message to a responder system, receives the reply, and /// returns the reply as a Message object. This method is thread-safe - multiple /// threads can share an Initiator and call this method. Responses are returned to /// the calling thread on the basis of message ID. /// </summary> public virtual Message sendAndReceive(Message out_Renamed) { if (out_Renamed == null) { throw new NuGenHL7Exception("Can't encode null message", NuGenHL7Exception.REQUIRED_FIELD_MISSING); } //register message with response Receiver(s) (by message ID) Terser t = new Terser(out_Renamed); System.String messID = t.get_Renamed("/MSH-10"); NuGenMessageReceipt mr = this.conn.reserveResponse(messID); //log and send message System.String outbound = conn.Parser.encode(out_Renamed); try { this.conn.SendWriter.writeMessage(outbound); } catch (System.IO.IOException e) { conn.close(); throw e; } //wait for response bool done = false; Message response = null; long startTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; while (!done) { lock (mr) { try { System.Threading.Monitor.Wait(mr, TimeSpan.FromMilliseconds(500)); //if it comes, notifyAll() will be called } catch (System.Threading.ThreadInterruptedException) { } if (mr.Message != null) { //get message from receipt System.String inbound = mr.Message; //parse message response = conn.Parser.parse(inbound); done = true; } //if ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 > startTime + timeoutMillis) //throw new HL7Exception("Timeout waiting for response to message with control ID '" + messID); } } return(response); }
/// <summary> Given the ack ID (MSA-2) of a message, returns the corresponding /// MessageReceipt if one exists (ie if reserveResponse has been called for this /// ack ID). Otherwise (i.e. if no object is waiting for this message), returns null. /// This method can only be called once per ackId (the record is dropped with the /// call). /// </summary> protected internal virtual NuGenMessageReceipt findRecipient(System.String ackID) { //String ID = getParser().getAckID(message); NuGenMessageReceipt mr = null; if (ackID != null) { System.Object tempObject; tempObject = receipts[ackID]; receipts.Remove(ackID); mr = (NuGenMessageReceipt)tempObject; } return(mr); }
/// <summary> Processes a single incoming message by sending it to the appropriate /// internal location. If an incoming message contains /// an MSA-2 field, it is assumed that this message is meant as a reply to a message that has been sent /// earlier. In this case an attempt is give the message to the object /// that sent the corresponding outbound message. If the message contains an MSA-2 but there are no objects that /// appear to be waiting for it, it is discarded and an exception is logged. If the message does not /// contain an MSA-2 field, it is concluded that the message has arrived unsolicited. In this case /// it is sent to the Responder (in a new Thread). /// </summary> protected internal virtual void processMessage(System.String message) { System.String ackID = conn.Parser.getAckID(message); if (ackID == null) { Grunt g = new Grunt(this, conn, message); g.Start(); } else { NuGenMessageReceipt mr = conn.findRecipient(ackID); if (mr == null) { } else { mr.Message = message; } } }
/// <summary> Reserves a future incoming message by ack ID. When the incoming message /// with the given ack ID arrives, the message will be available through /// the returned MessageReceipt. /// </summary> protected internal virtual NuGenMessageReceipt reserveResponse(System.String messageID) { NuGenMessageReceipt mr = new NuGenMessageReceipt(); receipts[messageID] = mr; return mr; }