如何保持golang.org/x/net/websocket打开?

I'm naively use _, err := ws.Read(msg) to keep a Web socket open in my code. I don't think it works reliably.

In other code I've noticed people doing a sleep loop. What's the correct way to keep a Web socket open & stable? I assume the underlying library does ping/pongs?

Update: I'm pretty confident that the client.go is to blame since it doesn't seem to redial after a disconnect is seen on the server. I made a video demonstrating the issue.

douguanyun2169
douguanyun2169 是的,这是正确的。这个想法是,套接字应该保持打开状态并保持健壮,直到它收到URL消息有效负载为止。但是在我的示例中,它并不健壮。
4 年多之前 回复
doucanrui1735
doucanrui1735 开始认为是我的客户端是问题所在:github.com/kaihendry/WebSocketHook/tree/master/client似乎无法判断何时断开连接。
4 年多之前 回复
dongshui2254
dongshui2254 我也很想看到乒乓球。例如,如果客户睡觉,我希望能够说出超时时间,最近一次见过的时间等等。
4 年多之前 回复

2个回答



我误解了您的原始问题。</ p>

不,您马上就这样做。 基本上,您需要阻止处理程序返回以保持websocket连接保持活动状态。 如果您不关心该消息,则将其丢弃,不对其进行任何处理。</ p>

人们执行该消息的一种常见方法是拥有专用的 Read </ code>并 Write </ code> goroutine,类似于:</ p>

  func fishHandler(ws * websocket.Conn){
id:= ws.RemoteAddr()。String( )+“-” + ws.Request()。RemoteAddr +“-” + ws.Request()。UserAgent()
sockets [id] = ws

go writePump(ws)
readPump(ws)

}

func readPump(ws * websocket.Conn){
延迟ws.Close()
msg:= make([] byte,512)
_,err:= ws.Read(msg)

if err!= nil {
return
}
}

func writePump(ws * websocket.Conn){
//将写入消息放在此处
}
</ code> </ pre>
</ div>

展开原文

原文

I misread your original question.

No you're doing it the right away. You basically need to block the handler from returning to keep the websocket connection alive. If you don't care about the message, just discard it and do nothing with it.

A common way people do it is to have a dedicated Read and Write goroutine, something like:

func fishHandler(ws *websocket.Conn) {
    id := ws.RemoteAddr().String() + "-" + ws.Request().RemoteAddr + "-" + ws.Request().UserAgent()
    sockets[id] = ws

    go writePump(ws)
    readPump(ws)
}

func readPump(ws *websocket.Conn) {
    defer ws.Close()
    msg := make([]byte, 512)
    _, err := ws.Read(msg)
    if err != nil {
        return
    }
}

func writePump(ws *websocket.Conn) {
    // Hand the write messages here
}

dongzhihong3940
dongzhihong3940 在读取和写入中使用“泵”一词的替代方法是什么? 我认为这个词没有足够的描述性。 流?
大约 2 年之前 回复
dousi4950
dousi4950 嗯,如果我用正确的方式做事,为什么我的代码中存在我想知道的稳定性问题? github.com/kaihendry/WebSocketHook/blob/master/server/main.go
4 年多之前 回复
dongsun2789
dongsun2789 没错,检查此处的错误没有任何意义,我只是想保留尽可能多的原始代码。 至于一个单独的goroutine,它的可读性更高,尤其是当您处理多个Read时的Read(我想更多的是带有通道和内容的图片),但最终还是可读性。
4 年多之前 回复
doumaoao0182
doumaoao0182 在这种情况下,检查ws.Read的err也没有多大意义。
4 年多之前 回复
dongritan5654
dongritan5654 如果客户端意外发送了二进制或文本消息,则在ws.Read之后调用ws.Close也很有意义。
4 年多之前 回复
drkbpwk609294
drkbpwk609294 考虑到websocket.Conn.Write在内部受互斥锁保护,我不明白为什么需要专用的Write goroutine。
4 年多之前 回复



golang.org/x/net/websocket并未实现RFC 6455中的ping-pong,但大猩猩websocket 实现。</ n> Gorilla websocket的最小示例</ p>

  c:=时间。  Tick(pingInterval)
go func(){
_:=范围c {
如果err:= conn.WriteControl(Ping ...); err!= nil {
处理错误
}
}
}()

conn.SetPongHandler(func(string)error {return conn.SetReadDeadline(time.Now ().Add(pingInterval))})
go func(){
for {
if ,err:= conn.NextReader(); err!= nil {
处理错误
}
}
}()
</ code> </ pre>
</ div>

展开原文

原文

golang.org/x/net/websocket does not implement ping-pong from RFC 6455, but the gorilla websocket implementation does. Minimal example with Gorilla websocket

c := time.Tick(pingInterval)
go func(){
       for  _ := range c {
           if err := conn.WriteControl(Ping...); err != nil {
                 handle error 
            }
      }
   }()

          -----

conn.SetPongHandler(func(string) error { return conn.SetReadDeadline(time.Now().Add(pingInterval)) })
go func(){
      for {
           if _, _, err := conn.NextReader(); err != nil {
                handle error
           }
       }
    }()

doumianfeng6979
doumianfeng6979 所以他们都是双方,这是你在说什么吗? 需要一些时间来提出最小的示例来尝试这一点。 =)
4 年多之前 回复
doubi9999
doubi9999 都在同一边。 对等WriteControl ping控制消息,然后通过PongHandler处理pong。 通过SetPingHandler响应ping对于另一端就足够了。
4 年多之前 回复
douding_1073
douding_1073 谢谢,尽管我不太了解客户端实现了什么以及服务器实现了什么。 你能说清楚一点吗?
4 年多之前 回复
dream02008
dream02008 我添加最小的例子。
4 年多之前 回复
dpz1983
dpz1983 即使使用“ github.com/gorilla/websocket”,也没有最小的ping / pong示例。 有人告诉我github.com/gorilla/websocket/blob/master/examples/chat/conn.go是一个起点,但它没有说明如何编写客户端二进制文件以及如何观察超时等。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问