1

I am trying to implement a simple UI which shall be showing the logs written in my server console. Have searched but couldn't find a solution which satisfies my requirement.

As per my design, I have a java program using Apache common-io api for tailing log file. It helps me to reduce memory overhead, I do not want to keep large chunks in memory. So when client makes a request, server shall start reading file and send the read data incrementally and shall keep showing until client stops receiving. I do not wish to send multiple request because that would make application read file again and again adding to which I would need to maintain a state/offset (possible solution but avoiding it).

I tried to check for JAX-RS using Asynchronous Response but that doesn't seem to help. I am not sure if HTTP/2 is gonna help.

Please help me understand how this can be achieved, and if I would need to implement socket programming at client and server side or if there is any such protocol which can be used. I am open to modify tech stack.

Thanks

Kaustav Sarkar
  • 181
  • 2
  • 8

2 Answers2

0

You can use any protocol that supports long lasting streaming connections (which there are many).

If you're already using JAX-RS, then StreamingOutput might be what you want.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I tried the solution using below approach but that is giving me solution in one go rather than sending that in chunks. try { for (int i = 0; i < 100; i++) { synchronized (Thread.currentThread()) { Thread.currentThread().wait(3000); writer.write("i = " + i + "\n"); } } } catch (Exception ex) { } writer.flush(); } – Kaustav Sarkar Aug 23 '18 at 08:48
  • To be clear what I need is similar to what we see in Jenkins Console Logs. It keeps on refreshing the logs itself. Rather than sending the entire response at once I want the data to stream in chunks to the client not all at one go as a stream – Kaustav Sarkar Aug 23 '18 at 08:52
  • I'm not sure I understand what you're talking about. Are you looking to flush after every line? – Kayaman Aug 23 '18 at 09:00
  • Exactly... Sending over each line without having to make new connection Everytime – Kaustav Sarkar Aug 23 '18 at 09:08
  • So send them over. Just flush after each line. Your example code that uses `Thread.currentThread().wait(3000);` is really bad by the way. It looks like you don't know `Thread.sleep(3000);`. – Kayaman Aug 23 '18 at 09:10
  • I tried flushing after each line... That doesn't work either. – Kaustav Sarkar Aug 23 '18 at 09:16
0

After bit of more searching I finally found a bunch of ways of achieving what I mentioned. Before I would like to explain how it cannot be achieved using HTTP (Rest specifically).

HTTP Way: There are few ways in HTTP and/or HTTP2 where you can create a long lasting connection using long-polling in both versions or using multiplexing property present in http2. In both cases the underlying protocol in TCP so there not much difference. However, in HTTP/HTTP2 transactions occur in a fashion where once server receives a request and sends response back, it doesn't expect client to receive response again neither client expects to receive one. So one complete cycle includes a pair of request and response. Hence, if you try to send another response you cannot do that because neither client nor server would be able to receive or send that respectively. There are many resources in Google for more in-depth information.This has a good explanation and references

So I tried to check if I can use some socket coding in order to keep the connection alive and transmit data. Luckily I stumbled upon another way to achieve that.

Two of which I felt make more sense for my requirement are as follows. I would not try to explain them just to avoid providing wrong information here since I myself am trying to get more insight.

1. Server-Side Events(SSE)

2. WebSockets

This will give a fare idea about them.

Kaustav Sarkar
  • 181
  • 2
  • 8