In one of my controllers, I'm doing some SSE async streaming (see here), and I have it working great in a barebones test project. In the test project, I don't have a default view set, so it seems to just pass through - perfect!
Now I'm trying to put it into my existing larger project, however, I'm finding that forwarding it to any view messes it up and I can't figure out how to simply skip the rendering of a view. Because I have a default view now, it refuses to just pass through.
I've blindly tried a few things: $c->detach
, $c->forward(undef)
, overriding the "end" method. None have succeeded in skipping the view rendering - it always passes it on to my default view.
Any ideas?
Edit
Not super relevant, but the action in question:
sub time_server : Path('/events') {
my ( $self, $c ) = @_;
$c->res->content_type('text/event-stream');
$timer_model->( $c, $c->response->write_fh );
}
Catalyst::Action::Renderview
has a small set of criteria it uses when deciding whether or not to call the view. It will skip running the view if:
HEAD
request.$c->response->body
to a defined value.$c->response->status
is set to 204 ("No Content") or any 3xx (redirection).$c->error
contains one or more errors and $c->stash->{template}
hasn't been set (so that finalize_error
can do its job instead).Honestly this isn't the best possible arrangement, but what I would try in your situation is setting $c->res->body("");
in your time_server
action. An empty body won't write anything, and your headers are already finalized since you've called write_fh
, but an empty string is still defined so it'll keep RenderView from doing anything.