Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/net/websocket: server should ping on an interval #5958

Closed
lukescott opened this issue Jul 25, 2013 · 16 comments
Closed

x/net/websocket: server should ping on an interval #5958

lukescott opened this issue Jul 25, 2013 · 16 comments

Comments

@lukescott
Copy link

RFC6455 has a ping/pong function that allows the server to discover if the client isn't
responding. The go.net/websocket library will respond to pings, but cannot send them or
do anything with pongs.

What I'd like to see is some sort of PingInterval / PongTimeout value that causes pings
to be sent on a timer, and then timeout the connection if a pong hasn't been received.

Perhaps this can be done in the Read function, or done in a go routine. It would likely
have to use SetReadDeadline, but I'm not sure how that would work with the existing
exported function.
@robpike
Copy link
Contributor

robpike commented Aug 4, 2013

Comment 1:

Labels changed: added priority-later, feature, removed priority-triage.

Status changed to Accepted.

@robpike
Copy link
Contributor

robpike commented Aug 4, 2013

Comment 2:

Labels changed: removed feature.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 3:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 4:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 5:

Labels changed: added repo-net.

@mikioh mikioh changed the title go.net/websocket: server should ping on an interval x/net/websocket: server should ping on an interval Dec 23, 2014
@mikioh mikioh added repo-net and removed repo-net labels Dec 23, 2014
@mikioh mikioh changed the title x/net/websocket: server should ping on an interval websocket: server should ping on an interval Jan 4, 2015
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc changed the title websocket: server should ping on an interval x/net/websocket: server should ping on an interval Apr 14, 2015
@rsc rsc modified the milestones: Unreleased, Unplanned Apr 14, 2015
@rsc rsc removed the repo-net label Apr 14, 2015
@klausenbusk
Copy link

3 year later, and nothing had happened yet.

@bradfitz
Copy link
Contributor

@klausenbusk, see https://golang.org/wiki/NoMeToo

Perhaps you can elaborate on why this is a problem for you in practice? Can you describe your environment? Do underlying TCP keep-alive mechanisms not adequately cull dead connections?

@herkyl
Copy link

herkyl commented Apr 14, 2016

Haproxy removes connections that have not pinged for X minutes. So golang websocket connections are cut off every 2 minutes in my case.

@GeorgeLyon
Copy link

TCP keep alive != websocket keepalive because in the case there is a proxy between the client and server, tcp keepalives will go between the proxy and each endpoint, whereas websocket ping pong works and to end.

@danmux
Copy link

danmux commented Feb 12, 2018

You can 'manually' send a ping frame - what is worse tho is that whether the remote side sends a pong in response or not, makes no difference - it is discarded, with no api to allow the client code to respond to a dead client.

I suspect the intention of x/net/websocket would be to defer to the underlying net timeout mechanism, but provides no mechanism to extend the read deadline on a good frame read.

@cpq
Copy link

cpq commented Sep 29, 2018

@danmux any hint on how pings could be sent manually? The marshalling function looks like this:

func marshal(v interface{}) (msg []byte, payloadType byte, err error) {
	switch data := v.(type) {
	case string:
		return []byte(data), TextFrame, nil
	case []byte:
		return data, BinaryFrame, nil
	}
	return nil, UnknownFrame, ErrNotSupported
}

It is either text or binary, with no way to set the type to PingFrame.

@klausenbusk
Copy link

klausenbusk commented Sep 29, 2018

@danmux any hint on how pings could be sent manually? The marshalling function looks like this:

codec := websocket.Codec{Marshal: func(v interface{}) (data []byte, payloadType byte, err error) {
	return nil, websocket.PingFrame, nil
}}
if err := codec.Send(ws, nil); err != nil {
	ws.Close()
}

@cpq
Copy link

cpq commented Sep 29, 2018

@klausenbusk thanks, appreciated!

@mkungla
Copy link
Contributor

mkungla commented Sep 6, 2019

why is it still open issue?

@bradfitz
Copy link
Contributor

bradfitz commented Sep 6, 2019

@mkungla, because it's not yet implemented. Or are you asking why people haven't prioritized fixing this?

@odeke-em
Copy link
Member

odeke-em commented Jun 6, 2020

Thanks everyone for the engagement on this issue, and for the patience.

We no longer maintain x/net/websocket and instead recommend these libraries:

But at least a work around of manual pings was suggested by @danmux in #5958 (comment), and code was provided by @klausenbusk in #5958 (comment).

Thus, I shall close this issue. Thank you again.

@odeke-em odeke-em closed this as completed Jun 6, 2020
@golang golang locked and limited conversation to collaborators Jun 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests