问题内容
我使用 Go 已经有一段时间了,但之前从未使用过 SSE。我遇到了一个问题,有人可以提供一个仅发送给特定用户(连接)的服务器发送事件的工作示例吗?
我正在使用 gorilla - 会话进行身份验证,并且我想使用 UserID 来分隔连接。
或者我应该通过 Ajax 使用 5 秒轮询?
非常感谢
这是我发现并尝试过的:
https://gist.github.com/ismasan/3fb75381cd2deb6bfa9c 它不会发送给个人用户,并且如果连接关闭,go func 也不会停止
https://github.com/striversity/gotr/blob/master/010-server-sent-event-part-2/main.go 这正是我所需要的,但一旦连接被删除。所以现在,一旦您在私人窗口中关闭并打开浏览器,它就根本无法工作。另外,如上所述,Go 例程继续进行。
正确答案
创建一个“代理”来将消息分发给连接的用户:
type broker struct {
// users is a map where the key is the user id
// and the value is a slice of channels to connections
// for that user id
users map[string][]chan []byte
// actions is a channel of functions to call
// in the broker's goroutine. the broker executes
// everything in that single goroutine to avoid
// data races.
actions chan func()
}
// run executes in a goroutine. it simply gets and
// calls functions.
func (b *broker) run() {
for a := range b.actions {
a()
}
}
func newbroker() *broker {
b := &broker{
users: make(map[string][]chan []byte),
actions: make(chan func()),
}
go b.run()
return b
}
// adduserchan adds a channel for user with given id.
func (b *broker) adduserchan(id string, ch chan []byte) {
b.actions 登录后复制
在包级别使用代理声明变量:
var broker = newbroker()
登录后复制
使用代理编写 sse 端点:
func sseEndpoint(w http.ResponseWriter, r *http.Request) {
// I assume that user id is in query string for this example,
// You should use your authentication code to get the id.
id := r.FormValue("id")
// Do the usual SSE setup.
flusher := w.(http.Flusher)
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
// Create channel to receive messages for this connection.
// Register that channel with the broker.
// On return from the function, remove the channel
// from the broker.
ch := make(chan []byte)
broker.addUserChan(id, ch)
defer broker.removeUserChan(id, ch)
for {
select {
case 登录后复制
向您的应用程序添加代码以调用 broker.sendtouser。
以上就是Golang 服务器向每个用户发送的事件的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!