33import io .github .cdimascio .dotenv .Dotenv ;
44import tools .jackson .databind .ObjectMapper ;
55
6- import java .io .IOException ;
76import java .net .URI ;
87import java .net .http .HttpClient ;
98import java .net .http .HttpRequest ;
109import java .net .http .HttpResponse ;
10+ import java .time .Duration ;
1111import java .util .Objects ;
1212import java .util .function .Consumer ;
1313
1414public class NtfyConnectionImpl implements NtfyConnection {
1515
16- private final HttpClient http = HttpClient . newHttpClient () ;
16+ private final HttpClient http ;
1717 private final String hostName ;
1818 private final ObjectMapper mapper = new ObjectMapper ();
1919
2020 public NtfyConnectionImpl () {
2121 Dotenv dotenv = Dotenv .load ();
2222 hostName = Objects .requireNonNull (dotenv .get ("HOST_NAME" ));
23+ this .http = HttpClient .newBuilder ()
24+ .connectTimeout (Duration .ofSeconds (10 ))
25+ .build ();
2326 }
2427
2528 public NtfyConnectionImpl (String hostName ) {
2629 this .hostName = hostName ;
30+ this .http = HttpClient .newBuilder ()
31+ .connectTimeout (Duration .ofSeconds (5 ))
32+ .build ();
2733 }
2834
2935 @ Override
30- public boolean send (String message ) {
31- HttpRequest httpRequest = HttpRequest .newBuilder ()
36+ public void send (String message , Consumer < Boolean > callback ) {
37+ HttpRequest request = HttpRequest .newBuilder ()
3238 .POST (HttpRequest .BodyPublishers .ofString (message ))
33- .header ("Cache" , "no" )
3439 .uri (URI .create (hostName + "/mytopic" ))
40+ .header ("Cache" , "no" )
41+ .timeout (Duration .ofSeconds (10 )) //request timeout
3542 .build ();
36- try {
37- //Todo: handle long blocking send requests to not freeze the JavaFX thread
38- //1. Use thread send message?
39- //2. Use async?
40- var reponse = http .send (httpRequest , HttpResponse .BodyHandlers .discarding ());
41- return true ;
42- } catch (IOException e ) {
43- System .out .println ("Error sending message" );
44- } catch (InterruptedException e ) {
45- System .out .println ("Interruped sending message" );
46- }
47- return false ;
43+
44+ http .sendAsync (request , HttpResponse .BodyHandlers .discarding ())
45+ .thenAccept (response -> {
46+ boolean success = response .statusCode () >= 200 && response .statusCode () < 300 ;
47+ callback .accept (success );
48+ })
49+ .exceptionally (throwable -> {
50+ System .err .println ("Error sending message: " + throwable .getMessage ());
51+ callback .accept (false );
52+ return null ;
53+ });
4854 }
4955
5056 @ Override
5157 public void receive (Consumer <NtfyMessageDto > messageHandler ) {
52- HttpRequest httpRequest = HttpRequest .newBuilder ()
58+ HttpRequest request = HttpRequest .newBuilder ()
5359 .GET ()
5460 .uri (URI .create (hostName + "/mytopic/json" ))
61+ .timeout (Duration .ofSeconds (30 )) //timeout för receive
5562 .build ();
5663
57- http .sendAsync (httpRequest , HttpResponse .BodyHandlers .ofLines ())
58- .thenAccept (response -> response .body ()
59- .map (s -> mapper .readValue (s , NtfyMessageDto .class ))
60- .forEach (messageHandler ));
64+ http .sendAsync (request , HttpResponse .BodyHandlers .ofLines ())
65+ .thenAccept (response -> {
66+ try {
67+ response .body ()
68+ .map (line -> {
69+ try {
70+ return mapper .readValue (line , NtfyMessageDto .class );
71+ } catch (Exception e ) {
72+ System .err .println ("Failed to parse message: " + line );
73+ return null ;
74+ }
75+ })
76+ .filter (Objects ::nonNull )
77+ .forEach (messageHandler );
78+ } catch (Exception e ) {
79+ System .err .println ("Stream processing error: " + e .getMessage ());
80+ }
81+ })
82+ .exceptionally (ex -> {
83+ System .err .println ("Error receiving messages: " + ex .getMessage ());
84+ return null ;
85+ });
6186 }
6287}
0 commit comments