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
Labels
Milestone

Comments

@lukescott
Copy link

@lukescott lukescott commented Jul 25, 2013

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 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 robpike commented Aug 4, 2013

Comment 2:

Labels changed: removed feature.

@rsc
Copy link
Contributor

@rsc rsc commented Nov 27, 2013

Comment 3:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 4:

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

@rsc
Copy link
Contributor

@rsc 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

@klausenbusk klausenbusk commented Mar 20, 2016

3 year later, and nothing had happened yet.

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Mar 20, 2016

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

@GeorgeLyon GeorgeLyon commented Aug 17, 2016

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 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 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 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 cpq commented Sep 29, 2018

@klausenbusk thanks, appreciated!

@mkungla
Copy link
Contributor

@mkungla mkungla commented Sep 6, 2019

why is it still open issue?

@bradfitz
Copy link
Contributor

@bradfitz 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 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 Jun 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.