duangeli1334 2018-09-21 20:15
浏览 198
已采纳

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

I'm trying to write code to stream data on a topic, like a radio station (one broadcaster, several listeners). I'm stuck on how to process a new WebSocket connection request without having a goroutine for each open WebSocket (that starts to get resource-intensive for many "listeners" to the same "station").

At the moment, I have a map of dataStream structs which look like this:

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

And here's the pseudocode for upgrading the request to a WebSocket, and then attempting to add a WebSocket connection to the dataStreams 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)
  }
}

And then here's the stream function mentioned in the above code block. One of these runs in the background for each dataStream (not for every WebSocket connection).

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
  }
}

The trouble with this approach is that in the process_request function, as soon as the flow reaches the bottom if statement of the 2nd and subsequent connections, after the new connection is appended to the dataStream.conns slice the function terminates closing the WebSocket connection! As a result, stream() is running in the background and polls that a closed connection has been added to the ds.conns slice and removes it.

Hence my question:

What approach should I take to maintain the WebSocket connection open for even after the process_request handler function returns, preferentially without running a separate goroutine for each connection?

  • 写回答

1条回答 默认 最新

  • doxzrb8721 2018-09-21 20:43
    关注

    The application must explicitly close a Gorilla connection. The connection is not automatically closed when the HTTP handler function returns.

    In this case, the application uses a defer statement to close the connection on return from the handler. Delete the defer statement to avoid closing the connection.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog