Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/middleware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ To accelerate your development, the Flamego core team and the community have bui
- [i18n](i18n.md) for providing internationalization and localization.
- [captcha](captcha.md) for generating and validating captcha images.
- [hcaptcha](hcaptcha.md) for providing [hCaptcha](https://www.hcaptcha.com/) verification.
- [sse](sse.md) for providing [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).

::: tip
If you notice any middleware that is missing from the list, please don't hesitate to [send a pull request to this page](https://github.com/flamego/flamego.dev/edit/main/docs/middleware/README.md)!
Expand Down
81 changes: 81 additions & 0 deletions docs/middleware/sse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
prev:
text: Middleware
link: ../middleware
---

# sse

The sse middleware provides [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) integration for [Flame instances](../core-concepts.md#instances).

You can read source code of this middleware on [GitHub](https://github.com/flamego/sse) and API documentation on [pkg.go.dev](https://pkg.go.dev/github.com/flamego/sse?tab=doc).

## Installation

The minimum requirement of Go is **1.18**.

```:no-line-numbers
go get github.com/flamego/sse
```

## Usage examples

:::: code-group
::: code-group-item main.go
```go:no-line-numbers{28}
package main

import (
"math/rand"
"net/http"
"time"

"github.com/flamego/flamego"
"github.com/flamego/sse"
"github.com/flamego/template"
)

var bulletins = []string{"Hello Flamego!", "Flamingo? No, Flamego!", "Most powerful routing syntax", "Slim core but limitless extensibility"}

type bulletin struct {
Data string
PublishedAt time.Time
}

func main() {
f := flamego.Classic()
f.Use(template.Templater(), flamego.Renderer())

f.Get("/", func(ctx flamego.Context, t template.Template) {
t.HTML(http.StatusOK, "index")
})

f.Get("/bulletin", sse.Bind(bulletin{}), func(msg chan<- *bulletin) {
for {
select {
case <-time.Tick(1 * time.Second):
Comment on lines +54 to +56
Copy link

Copilot AI May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving time.Tick(1 * time.Second) outside the loop to avoid creating a new ticker on every iteration, which could lead to resource inefficiencies.

Suggested change
for {
select {
case <-time.Tick(1 * time.Second):
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:

Copilot uses AI. Check for mistakes.
msg <- &bulletin{
Data: bulletins[rand.Intn(len(bulletins))],
PublishedAt: time.Now(),
}
}
}
})

f.Run()
}
```
:::
::: code-group-item templates/index.html
```html:no-line-numbers
<script src="https://cdn.jsdelivr.net/npm/way-js@0.2.1/dist/way.js"></script>
<p><b><span way-data="data"></span></b>[<span way-data="published-at"></span>]</p>
<script>
let es = new EventSource("/bulletin");
es.onmessage = (evt) => {
let bulletin = JSON.parse(evt.data);
way.set('data', bulletin.Data)
way.set('published-at', new Date(bulletin.PublishedAt).toLocaleString())
};
</script>
```