diff --git a/changelog/unreleased/sse-keepalive.md b/changelog/unreleased/sse-keepalive.md new file mode 100644 index 00000000000..8b61ffba7d4 --- /dev/null +++ b/changelog/unreleased/sse-keepalive.md @@ -0,0 +1,5 @@ +Bugfix: make SSE keepalive interval configurable + +To prevent intermediate proxies from closing the SSE connection admins can now configure a `SSE_KEEPALIVE_INTERVAL`. + +https://github.com/owncloud/ocis/pull/10411 diff --git a/services/sse/README.md b/services/sse/README.md index 11e47b7c9eb..d6a5f1ecb1b 100644 --- a/services/sse/README.md +++ b/services/sse/README.md @@ -12,3 +12,8 @@ Log services like the `userlog`, `clientlog` and `sse` are responsible for compo ## Subscribing Clients can subscribe to the `/sse` endpoint to be informed by the server when an event happens. The `sse` endpoint will respect language changes of the user without needing to reconnect. Note that SSE has a limitation of six open connections per browser which can be reached if one has opened various tabs of the Web UI pointing to the same Infinite Scale instance. + +## Keep SSE Connections Alive + +Some intermediate proxies drop connections after an idle time with no activity. If this is the case, configure the `SSE_KEEPALIVE_INTERVAL` envvar. This will send periodic SSE comments to keep connections open. + diff --git a/services/sse/pkg/config/config.go b/services/sse/pkg/config/config.go index fef62abc111..10f3af10059 100644 --- a/services/sse/pkg/config/config.go +++ b/services/sse/pkg/config/config.go @@ -2,6 +2,7 @@ package config import ( "context" + "time" "github.com/owncloud/ocis/v2/ocis-pkg/shared" ) @@ -14,7 +15,8 @@ type Config struct { Debug Debug `mask:"struct" yaml:"debug"` Tracing *Tracing `yaml:"tracing"` - Service Service `yaml:"-"` + Service Service `yaml:"-"` + KeepAliveInterval time.Duration `yaml:"keepalive_interval" env:"SSE_KEEPALIVE_INTERVAL" desc:"To prevent intermediate proxies from closing the SSE connection, send periodic SSE comments to keep it open." introductionVersion:"7.0"` Events Events HTTP HTTP `yaml:"http"` diff --git a/services/sse/pkg/service/service.go b/services/sse/pkg/service/service.go index aac0cdd426b..df94316acbc 100644 --- a/services/sse/pkg/service/service.go +++ b/services/sse/pkg/service/service.go @@ -2,6 +2,7 @@ package service import ( "net/http" + "time" "github.com/go-chi/chi/v5" "github.com/r3labs/sse/v2" @@ -81,6 +82,18 @@ func (s SSE) HandleSSE(w http.ResponseWriter, r *http.Request) { stream := s.sse.CreateStream(uid) stream.AutoReplay = false + if s.c.KeepAliveInterval != 0 { + ticker := time.NewTicker(s.c.KeepAliveInterval) + defer ticker.Stop() + go func() { + for range ticker.C { + s.sse.Publish(uid, &sse.Event{ + Comment: []byte("keepalive"), + }) + } + }() + } + // add stream to URL q := r.URL.Query() q.Set("stream", uid)