gpt4 book ai didi

go - 如何在 HTTP 处理函数返回后保持 WebSocket 连接打开?

转载 作者:IT王子 更新时间:2023-10-29 01:12:04 31 4
gpt4 key购买 nike

我正在尝试编写代码以流式传输某个主题的数据,例如广播电台(一个广播员,多个听众)。我坚持如何处理一个新的 WebSocket 连接请求,而无需为每个打开的 WebSocket 设置一个 goroutine(对于同一“站”的许多“监听器”来说,这开始占用大量资源)。

目前,我有一个 dataStream 结构图,如下所示:

struct dataStream {
data chan byte[]
conns []*websocket.Connection
}

下面是将请求升级到 WebSocket 的伪代码,然后尝试将 WebSocket 连接添加到数据流 conns:

func process_request(w http.ResponseWriter, r *http.Request) {
// hundred lines of business logic...
c := upgrade websocket connection
defer c.Close()
if dataStream exists {
append the new connection c to the dataStream.conns slice
} else {
create new dataStream
append the new connection c to the dataStream.conns slice
stream(dataStream)
}
}

然后是上面代码块中提到的stream函数。其中之一在每个数据流的后台运行(不是每个 WebSocket 连接)。

func stream(ds *dataStream) {
ticker := time.NewTicker(poll every ~10 seconds)
go func() { // this is to poll and remove closed connections
for _ = range ticker.C {
for traverse ds.conns {
ping all connections, remove any closed ones and free memory
if len(ds.conns == 0){ // no more connections are listening to this dataStream
delete the ds dataStream and free the memory
stop ticker
return // kill goroutine and free the memory
}
}
}}()
while len(ds.conns) != 0 { // while there are open connections
fetch any available <-ds.data from channel
write the data as websocket message to each connection
}
}

这种方法的问题在于,在process_request函数中,一旦流程到达第2个及后续连接的底部if语句,在新连接之后附加到 dataStream.conns slice 函数终止 关闭 WebSocket 连接! 因此,stream() 在后台运行并且轮询已关闭的连接已添加到 ds.conns slice 并将其删除。

因此我的问题是:

即使在 process_request 处理程序函数返回后,我应该采取什么方法来保持 WebSocket 连接打开,最好不要为每个连接运行单独的 goroutine?

最佳答案

应用程序必须显式关闭 Gorilla 连接。当 HTTP 处理程序函数返回时,连接不会自动关闭。

在这种情况下,应用程序使用 defer 语句在从处理程序返回时关闭连接。删除 defer 语句以避免关闭连接。

关于go - 如何在 HTTP 处理函数返回后保持 WebSocket 连接打开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52450573/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com