Golang 服务器向每个用户发送的事件

2024年 2月 6日 93.3k 0

golang 服务器向每个用户发送的事件

问题内容

我使用 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)其它相关文章!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论