You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by DmitryM <ns...@aol.com> on 2010/09/09 21:30:24 UTC

HTML streaming on Link click

Hello, guys

I need to stream HTML data to an iframe.
Here's what I do:

		Link<Void> l = new Link<Void>("pushLink"){
			private static final long serialVersionUID = 1L;
			
			@Override
			public void onClick() {
				((WebResponse)getResponse()).setContentType("text/html"); 
				((WebResponse)getResponse()).setHeader("Pragma", "no-cache"); 
				((WebResponse)getResponse()).setHeader("Cache-Control", "no-cache,
max-age=0, must-revalidate, no-store");
				((WebResponse)getResponse()).setHeader("Content-Disposition", "inline");
				getRequestCycle().setRequestTarget(new IRequestTarget(){

					@Override
					public void detach(RequestCycle requestCycle) {
					}

					@Override
					public void respond(RequestCycle requestCycle) {
						OutputStream os;
						try {
							os =
((WebResponse)requestCycle.getResponse()).getHttpServletResponse().getOutputStream();
							this.write(os);
						} catch (IOException e) {
							log.error("IOException while trying to get output stream", e);
						}
					}
					
					public void write(OutputStream os) {
					try {
						os.write("<!-- ... chunk of text to make browser start accepting data
... -->");
						os.write("<html>".getBytes());
						os.write("<body>".getBytes());
						os.write("<script>alert('Step 1');</script>".getBytes());
						os.flush();
						new CountDownLatch(1).await(5, TimeUnit.SECONDS);
						os.write("<script>alert('Step 2');</script>".getBytes());
						os.write("</body>".getBytes());
						os.write("</html>".getBytes());
						os.flush();
						os.close();
					} catch (IOException e) {
						log.error("Error while writing to the output stream", e);
					} catch (InterruptedException e) {
						log.error("Countdown latch interrupted", e);
					}
				}

...
};


The HTML template is as this:


	 # Test push 
	<iframe id="pushIframe" name="pushIframe" ></iframe>		


The 'streaming' intention doesn't work.
The HTML arrives to the client but all at once (not with the delay).

This is an emulation of a request which will be handled later. Instead of
the delay there will be calls to external services which really take a few
seconds.
And I need to inform the user that something is still happens and the
response will come (since there are multiple steps in the request processing
I need to display several messages).

Any suggestions?

Dmitry

P.S. I'm not sure if DynamicWebResource approach would work because there is
only an input stream which Wicket reads from. And I can't really 'push' data
down that stream.

-- 
View this message in context: http://apache-wicket.1842946.n4.nabble.com/HTML-streaming-on-Link-click-tp2533475p2533475.html
Sent from the Wicket - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: HTML streaming on Link click

Posted by DmitryM <ns...@aol.com>.
Okay, guys.
That was kind of 'false alarm'.
The output cache is on the NGINX level I have as a load balancer.

Wicket implementation itself works as expected.
A couple of notes here (for anybody interested in the topic):
- always add a 1Kb of 'padding' text in the beginning of the response (to
make browsers recognize the fact the stream data started to come)
- always do flush on the output stream after each 'meaningful' data chunk
written to the stream (to make it delivered to the browser)

That's it. 
Closing the topic.
-- 
View this message in context: http://apache-wicket.1842946.n4.nabble.com/Live-streaming-on-Link-click-tp2533475p2536127.html
Sent from the Wicket - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: HTML streaming on Link click

Posted by DmitryM <ns...@aol.com>.
Rodolfo,

No, I didn't test it w/WireShark or similar packet sniffer.
I can give it a shot...
I only tested it in Safari and FireFox (the matter is I only care about
Safari, or, rather, WebKit) for now, this would be an app to be accessed
from the phone.

The behaviour of the browsers (including iPhone Safari) is the same. I
click/tap the link, the browser waits for those 5 seconds I set up... then
displays 1st alert and after clicking/tapping OK immediately displays the
2nd alert.

Very frustrating. =(

-Dmitry
-- 
View this message in context: http://apache-wicket.1842946.n4.nabble.com/Live-streaming-on-Link-click-tp2533475p2533644.html
Sent from the Wicket - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: HTML streaming on Link click

Posted by Rodolfo Hansen <kr...@gmail.com>.
On Thu, 2010-09-09 at 14:11 -0700, DmitryM wrote:

> Rodolfo,
> 
> If you're asking about Wicket application settings, then yes, it's set to
> default 2-pass request processing with buffered pages rendering.
> 
> I thought the way the link is implemented it should not matter since I
> thought I would write directly into the HttpServlet output stream.
> And I really see the 
> 
> ((WebResponse)requestCycle.getResponse()).getHttpServletResponse().getOutputStream()
> 
> returns me an instance of something from the web server itself (in my case
> it's Jetty HttpConnection$Output)
> 
> Did I miss something?

No, sorry, it seems correct.

Did you use wireshark or something similar to make sure its not working
as expected?

It should work.

> 
> -Dmitry



Re: HTML streaming on Link click

Posted by DmitryM <ns...@aol.com>.
Rodolfo,

If you're asking about Wicket application settings, then yes, it's set to
default 2-pass request processing with buffered pages rendering.

I thought the way the link is implemented it should not matter since I
thought I would write directly into the HttpServlet output stream.
And I really see the 

((WebResponse)requestCycle.getResponse()).getHttpServletResponse().getOutputStream()

returns me an instance of something from the web server itself (in my case
it's Jetty HttpConnection$Output)

Did I miss something?

-Dmitry
-- 
View this message in context: http://apache-wicket.1842946.n4.nabble.com/Live-streaming-on-Link-click-tp2533475p2533591.html
Sent from the Wicket - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: HTML streaming on Link click

Posted by Rodolfo Hansen <kr...@gmail.com>.
Are you using a buffered web response ??


On Thu, 2010-09-09 at 12:30 -0700, DmitryM wrote:

> Hello, guys
> 
> I need to stream HTML data to an iframe.
> Here's what I do:
> 
> 		Link<Void> l = new Link<Void>("pushLink"){
> 			private static final long serialVersionUID = 1L;
> 			
> 			@Override
> 			public void onClick() {
> 				((WebResponse)getResponse()).setContentType("text/html"); 
> 				((WebResponse)getResponse()).setHeader("Pragma", "no-cache"); 
> 				((WebResponse)getResponse()).setHeader("Cache-Control", "no-cache,
> max-age=0, must-revalidate, no-store");
> 				((WebResponse)getResponse()).setHeader("Content-Disposition", "inline");
> 				getRequestCycle().setRequestTarget(new IRequestTarget(){
> 
> 					@Override
> 					public void detach(RequestCycle requestCycle) {
> 					}
> 
> 					@Override
> 					public void respond(RequestCycle requestCycle) {
> 						OutputStream os;
> 						try {
> 							os =
> ((WebResponse)requestCycle.getResponse()).getHttpServletResponse().getOutputStream();
> 							this.write(os);
> 						} catch (IOException e) {
> 							log.error("IOException while trying to get output stream", e);
> 						}
> 					}
> 					
> 					public void write(OutputStream os) {
> 					try {
> 						os.write("<!-- ... chunk of text to make browser start accepting data
> ... -->");
> 						os.write("<html>".getBytes());
> 						os.write("<body>".getBytes());
> 						os.write("<script>alert('Step 1');</script>".getBytes());
> 						os.flush();
> 						new CountDownLatch(1).await(5, TimeUnit.SECONDS);
> 						os.write("<script>alert('Step 2');</script>".getBytes());
> 						os.write("</body>".getBytes());
> 						os.write("</html>".getBytes());
> 						os.flush();
> 						os.close();
> 					} catch (IOException e) {
> 						log.error("Error while writing to the output stream", e);
> 					} catch (InterruptedException e) {
> 						log.error("Countdown latch interrupted", e);
> 					}
> 				}
> 
> ...
> };
> 
> 
> The HTML template is as this:
> 
> 
> 	 # Test push 
> 	<iframe id="pushIframe" name="pushIframe" ></iframe>		
> 
> 
> The 'streaming' intention doesn't work.
> The HTML arrives to the client but all at once (not with the delay).
> 
> This is an emulation of a request which will be handled later. Instead of
> the delay there will be calls to external services which really take a few
> seconds.
> And I need to inform the user that something is still happens and the
> response will come (since there are multiple steps in the request processing
> I need to display several messages).
> 
> Any suggestions?
> 
> Dmitry
> 
> P.S. I'm not sure if DynamicWebResource approach would work because there is
> only an input stream which Wicket reads from. And I can't really 'push' data
> down that stream.
>