Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mllp server can't handle smartHL7 message sender when multiple messages are sent one after next #37

Open
kundeng opened this issue Oct 29, 2018 · 7 comments

Comments

@kundeng
Copy link

kundeng commented Oct 29, 2018

Hi,
I am using smartHL7 message sender http://smarthl7.com/tools.html along with your mllp server for a project.

It seems that when I send one message at a time, your mllp server can handle it correctly. However, if I try to send multiple messages one after next, it will fail with network errors.

This may not be a bug, depending on whether or not your code supports this kind of streaming or not.

My guess is that the client is trying to send all messages in one socket connection and it assumes that the server will split them up correctly.

How do I tweak your code to handle this scenario?

@svituz
Copy link
Member

svituz commented Nov 6, 2018

Hi @kundeng,
when you say "multiple messages" you mean separated by mllp characters or just starting with a new MSH?
The server simply continue to read the socket starting from the first mllp char (\x0b) and ending when it finds the sequence \x1c\x0d. After that, it reads the message and process the response based on the handlers. So if the tool sends a string like this (I use newline char here just for readability, it should be carriage return):

\x0bMSH|^~\&|SEND APP|SEND FAC|REC APP|REC FAC|20110708163514||RSP^K22^RSP_K21|1234|D|2.5|||||ITA||EN
MSA|AA|26775702551812240|
QAK|111069|OK||1|1|0
QPD|IHE PDQ Query|111069|@PID.3.1^[email protected]^SMITH||||
PID|1||10101^^^GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17&ISO||JOHN^SMITH^^^^^A||19690113|M|||VIA DELLE VIE^^CAGLIARI^^^100^H^^092009||||||||||||CAGLIARI|||||
MSH|^~\&|SEND APP|SEND FAC|REC APP|REC FAC|20110708163514||RSP^K22^RSP_K21|1234|D|2.5|||||ITA||EN
MSA|AA|26775702551812240|
QAK|111069|OK||1|1|0
QPD|IHE PDQ Query|111069|@PID.3.1^[email protected]^SMITH||||
PID|1||10101^^^GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17&ISO||JOHN^SMITH^^^^^A||19690113|M|||VIA DELLE VIE^^CAGLIARI^^^100^H^^092009||||||||||||CAGLIARI|||||\x1c\x0d

then the answer is no, the implementation doesn't handle it as two separated messages.
If you want to implement a behavior that splits the messages based on when it finds MSH, then you should implement your own _MLLPRequestHandler and MLLPServer in mllp.py. You can copy and paste them and just change the handle method.

@svituz
Copy link
Member

svituz commented Nov 6, 2018

I performed some tests: the server doesn't consider them as two messages also if you send them separated by mllp chars. In this case it reads the first and ignore others.

@kundeng
Copy link
Author

kundeng commented Nov 8, 2018

Hi, the following tweak will work, however it may need to tweaked further to close long-waiting receiving sockets:

def handle(self):
    while 1:
        try:
            self.handle0()
        except Exception:
            self.request.close()

    self.request.close()


def handle0(self):
    end_seq = self.eb + self.cr
    try:
        line = self.request.recv(3)
    except socket.timeout:
        self.request.close()
        return

    if line[:1] != self.sb:  # First MLLP char
        self.request.close()
        return

    while line[-2:] != end_seq:
        try:
            char = self.rfile.read(1)
            if not char:
                break
            line += char
        except socket.timeout:
            self.request.close()
            return

    message = self._extract_hl7_message(line.decode(self.encoding))
    if message is not None:
        try:
            response = self._route_message(message)
        except Exception:
            self.request.close()
        else:
            # encode the response
            self.wfile.write(response.encode(self.encoding))
    #self.request.close()

@jebrage
Copy link

jebrage commented Feb 22, 2019

@kundeng The methods above worked correctly as expected with Samsung Geo HC10. Thanks. Would it be there in the next version? I extended the handle method for now.

@thsieh123
Copy link

thsieh123 commented Apr 16, 2019

I also run into this issue. So basically the self.request.close() closes the socket. The client has to connect again. What is the benefit if the server closes socket connection for every message? Isn't that some sort of timeout can be used to close the connection. There are use cases where a large number of observations need to be uploaded. If every message needs to connect again instead of reuse the same socket connection, I wonder if the performance could be affected for both client and server.

The above code has a 'while True' which is not the ideal solution either. Maybe closing for every message is a cleaner solution?

@gfolbe318
Copy link

Was there ever a follow up on this? The solution that @kundeng proposed worked for me, but I am curious if a production-level implementation was ever considered?

@gfolbe318
Copy link

Additionally, thank you @kundeng for this solution! I +1'd your answer.

Would love to hear how this ended up working for you and/or if you modified it at all?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants