Eventsource golang:如何检测客户端断开连接?

     2023-02-16     276

关键词:

【中文标题】Eventsource golang:如何检测客户端断开连接?【英文标题】:Eventsource golang : how to detect client disconnection? 【发布时间】:2015-11-14 09:48:12 【问题描述】:

我正在开发基于 Twitter 标签的聊天室,其中包含服务器发送的事件,包 https://github.com/antage/eventsource

我有一个关于客户端断开连接的问题。我运行了一个 goroutine 向客户端发送消息,但是当客户端断开连接时,goroutine 仍然运行。

我不知道如何在服务器端检测到客户端断开连接。

func (sh StreamHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) 

    es := eventsource.New(
        &eventsource.Settings
            Timeout:        2 * time.Second,
            CloseOnTimeout: true,
            IdleTimeout:    2 * time.Second,
            Gzip:           true,
        ,
        func(req *http.Request) [][]byte 
            return [][]byte
                []byte("X-Accel-Buffering: no"),
                []byte("Access-Control-Allow-Origin: *"),
            
        ,
    )

    es.ServeHTTP(resp, req)

    go func() 
        var id int
        for 
            id++
            time.Sleep(1 * time.Second)
            es.SendEventMessage("blabla", "message", strconv.Itoa(id))
        
    ()


【问题讨论】:

【参考方案1】:

您可以查看ConsumersCount():

    go func() 
        var id int
        for es.ConsumersCount() > 0 
            id++
            es.SendEventMessage("blabla", "message", strconv.Itoa(id))
            time.Sleep(1 * time.Second)
        
        fmt.Println("closed")
    ()

有点 hacky,但它似乎工作。

您最好使用不同的包或滚动自己的包,这样您就可以更好地控制 goroutine 的生命周期。您可以在.Write 上检测到关闭的连接(此包未公开)。

如果你想要下面的 TCP 聊天服务器示例:chat-server。 还有一个视频教程:tutorial。

同样的基本模式应该适用于 SSE。

【讨论】:

感谢您的回答。我的问题是我使用的包没有提出 ConsumerCount() 函数。【参考方案2】:

您可以使用CloseNotifier 让您知道底层http 连接是否已关闭。喜欢:

notify := w.(http.CloseNotifier).CloseNotify()
go func() 
    <-notify
    // connection close, do cleanup, etc.
()

HTH

【讨论】:

【参考方案3】:

截至 2018 年 12 月,apparently CloseNotifier is deprecated。推荐的解决方案是使用Request 上下文。以下对我有用:

done := make(chan bool)
go func() 
        <-req.Context().Done()
        done <- true
()
<-done

【讨论】:

您是否有一个完整的示例适合原始问题,因为我无法让它工作?谢谢。 @anderspitman 有没有办法区分优雅的客户端断开连接和使用此方法的突然客户端断开连接? @ymerej 不是我所知道的。检测 TCP 断开连接实际上可能相当棘手。 不需要done 频道 - 只需直接使用&lt;-req.Context().Done() - 并使用selectdefault 进行非阻塞轮询。

每个应用程序应该只有一个 EventSource 对象吗?

】每个应用程序应该只有一个EventSource对象吗?【英文标题】:ShouldtherebeonlyoneEventSourceobjectperapp?【发布时间】:2012-07-2505:04:34【问题描述】:当使用Server-SentEvents时,客户端应该建立多个连接来接收它感兴趣的不同事件,还是应... 查看详情

Golang 从标准输入读取,如何检测特殊键(回车、退格...等)

】Golang从标准输入读取,如何检测特殊键(回车、退格...等)【英文标题】:Golangreadingfromstdin,howtodetectspecialkeys(enter,backspace...etc)【发布时间】:2017-03-0217:33:27【问题描述】:我有以下程序从标准输入读取用户输入:varinputstring="... 查看详情

如何使用 golang 上下文功能而不是 golang http 客户端发出 http 请求?

】如何使用golang上下文功能而不是golanghttp客户端发出http请求?【英文标题】:Howtoissuehttprequestwithgolangcontextcapabilitybutnotbygolanghttpclient?【发布时间】:2017-10-0403:21:29【问题描述】:我发现golang上下文对于在客户端-服务器请求范... 查看详情

如何使用 Windows 性能分析器查看 EventSource 创建的 ETW 事件?

】如何使用Windows性能分析器查看EventSource创建的ETW事件?【英文标题】:HowdoyouviewETWeventscreatedbyEventSourceusingWindowsPerformanceAnalyzer?【发布时间】:2013-01-0221:57:28【问题描述】:我想使用EventSource触发ETW事件并使用Windows性能分析器... 查看详情

如何将消息从golang的websocket服务器主动发送到客户端

】如何将消息从golang的websocket服务器主动发送到客户端【英文标题】:Howtosendthemessagesactivelyfromgolang\'swebsocketservertoclient【发布时间】:2018-05-2405:12:56【问题描述】:我是golang和websocket的新手。我正在尝试编写一个websocket服务器... 查看详情

发送连接升级后,如何在golang中将客户端http连接升级到websockets

】发送连接升级后,如何在golang中将客户端http连接升级到websockets【英文标题】:HowcanIupgradeaclienthttpconnectiontowebsocketsingolangaftersendingtheconnectionupgrade【发布时间】:2019-04-0513:24:10【问题描述】:我需要一个可以从httpget响应升级到... 查看详情

golang 强制 net/http 客户端使用 IPv4 / IPv6

】golang强制net/http客户端使用IPv4/IPv6【英文标题】:golangforcenet/httpclienttouseIPv4/IPv6【发布时间】:2018-10-3000:39:15【问题描述】:我使用go1.11net/http并想检测一个域是否仅限ipv6。你做了什么?我创建自己的DialContext是因为我想检测... 查看详情

所有事件的 HTML5 EventSource 侦听器?

】所有事件的HTML5EventSource侦听器?【英文标题】:HTML5EventSourcelistenerforallevents?【发布时间】:2012-04-1314:04:25【问题描述】:我在我的JavaScript客户端应用程序中使用EventSource推送通知。我可以像这样附加事件监听器:source.addEventL... 查看详情

EventSource 与轮询 ajax 的效率/开销?

】EventSource与轮询ajax的效率/开销?【英文标题】:Efficiency/overheadofEventSourcevspolledajax?【发布时间】:2012-01-0905:06:34【问题描述】:我正在编写一个简单的应用程序,它在使用方面与聊天应用程序非常相似。主持人启动一个“房... 查看详情

在 Go 中关闭 grpc 服务器时如何检测错误?

...检测gRPC服务器关闭,例如import(pb"mysample.com/api/rpc""google.golang.org/grpc")varstreampb.SearchProdu 查看详情

如何检测客户端的时区?

】如何检测客户端的时区?【英文标题】:Howtodetectthetimezoneofaclient?【发布时间】:2011-03-0109:13:54【问题描述】:如何在jsp中获取客户端/请求时区?【问题讨论】:【参考方案1】:很遗憾,此信息未在HTTP标头中传递。通常您需... 查看详情

如何在通用应用程序中禁用任务并行库的 ETW EventSource?

】如何在通用应用程序中禁用任务并行库的ETWEventSource?【英文标题】:HowtodisableTaskParallelLibrary\'sETWEventSourceinaUniversalApp?【发布时间】:2015-02-1208:43:42【问题描述】:任务并行库使用EventTracingforWindows(ETW)进行日志记录。显然,在... 查看详情

客户端检测

...识别浏览器的能力。采用这种方式不必顾及特定的浏览器如何如何,只要确定浏览器支持特定的能力,就可以给出解决方案。能力检测的理想代码:functionisHostMethod(object,property){vart=typeofob 查看详情

server-sentevents(sse)&eventsource客户端使用与服务器基础实现(基于node.js)(代码片段)

文章目录目的基础说明客户端使用服务器实现注意事项总结目的传统的Web前后台通讯主要是使用HTTP方式进行的,通常是前台需要什么就主动向后台请求,后台无法直接向前台发送数据。通常后台数据如果频繁变动的话前... 查看详情

使用 golang 客户端从远程 kubernetes 命令流式输出

】使用golang客户端从远程kubernetes命令流式输出【英文标题】:Streamoutputfromremotekubernetescommandwithgolangclient【发布时间】:2021-09-0511:39:51【问题描述】:我正在使用golangkubernetes客户端来创建kubernetespod并在其中执行远程命令。但是... 查看详情

Spring Websocket - 如何检测客户端断开连接

】SpringWebsocket-如何检测客户端断开连接【英文标题】:SpringWebsocket-HowcanIdetectclientdisconnect【发布时间】:2016-12-1318:10:49【问题描述】:我是春天的新手我有这门课:publicclassServerextendsTextWebSocketHandlerimplementsWebSocketHandlerWebSocketSess... 查看详情

Symfony / Mercure / JS EventSource 不发送 cookie

】Symfony/Mercure/JSEventSource不发送cookie【英文标题】:Symfony/Mercure/JSEventSourcedon\'tsendcookie【发布时间】:2021-09-0301:17:51【问题描述】:我已经阻止这个问题2天了。我正在尝试为Mercure设置身份验证,以便客户可以订阅“私人”集线... 查看详情

如何在客户端使用 JavaScript 来检测页面是不是已加密?

】如何在客户端使用JavaScript来检测页面是不是已加密?【英文标题】:HowcanIuseJavaScriptontheclientsidetodetectifthepagewasencrypted?如何在客户端使用JavaScript来检测页面是否已加密?【发布时间】:2010-09-2121:34:32【问题描述】:是否可以... 查看详情