one websocket

1,254 views
Skip to first unread message

Russ Cox

unread,
May 30, 2013, 11:35:50 AM5/30/13
to uk...@google.com, Gary Burd, golang-dev
i was at a boston-area go users group meeting earlier this week and there was some confusion about the various websocket packages.

what is the relation between
?

can we make whatever changes are necessary to the one in the subrepo so that we can standardize on one?

russ

Gary Burd

unread,
May 31, 2013, 1:55:32 AM5/31/13
to golan...@googlegroups.com, uk...@google.com, Gary Burd
The packages have different APIs and implementations. 

My package gives the application more control and access to websocket features than the go.net package.

The go.net package supports the version of the protocol specified in the RFC and two older versions. My package supports the RFC version only.
 
  github.com/garyburd/twister/websocket

This is an early version of github.com/garyburd/go-websocket/websocket. To reduce confusion, I removed the package from godoc.org.
 
can we make whatever changes are necessary to the one in the subrepo so that we can standardize on one?

What changes are you willing to make? Are you willing to make incompatible changes to the API or drop support for old versions of the protocol?

Bobby Powers

unread,
May 31, 2013, 10:39:28 AM5/31/13
to Gary Burd, golang-dev, uk...@google.com
Do you have an example of the incompatible API changes you'd like?  It seems like most of the functionality of your package could be provided by adding a few methods to the go.net implementation.  Personally, one of the nice things I like about the go.net implementation is that it implements io.Reader and io.Writer - I see the usefulness of being able to access and set the opcodes of the messages, but I wouldn't want to see it done at the expense of being an io.ReadWriter.

yours,
Bobby

Daniel Theophanes

unread,
May 31, 2013, 12:04:09 PM5/31/13
to golan...@googlegroups.com, Gary Burd, uk...@google.com
I'm not convinced io.Reader and io.Writer is the correct choice for websockets. The RFC is clearly message based. Although you could theoretically stream large messages over web-sockets,
you would have to make sure the other end allows streaming, which is not the case right now with browser web-socket clients (they provide the entire message in one shot). The other issue with an io.Reader and io.Writer, is these interfaces imply you can do:
at := 0
for {
   n, err := ws.Write(bb)
   at += n
   if at == len(bb) {
      break
   }
}

Which in the websocket API with io.Writer, this would actually lead to incorrect messages being passed. So even with io.Writer, you still have to have your entire message in a single []byte to send.
As such, I would go as far as to say, the go.net websocket API is incorrect.

If you supported io.ReadWriter, you would probably need to do something like:
ws.BeginMessage(options)
ws.Write(bb)
ws.EndMessage()

msg := ws.ReadMessage
// msg implements io.Reader, can read a message until io.EOF.

-Daniel

Russ Cox

unread,
May 31, 2013, 3:41:17 PM5/31/13
to Gary Burd, golang-dev, uk...@google.com
> What changes are you willing to make? Are you willing to make incompatible changes to the API or drop support for old versions of the protocol?

I'd like to hear from ukai, but speaking just for me:

If there are good reasons to change the API, then sure, I am willing to make incompatible changes.
If there are good reasons to drop the old versions and not much harm, then sure, we can do that too.

This is one of the nice things about being in a subrepo.

Can you outline the concrete changes you'd suggest in the go.net one?

Russ

Fumitoshi Ukai (鵜飼文敏)

unread,
Jun 4, 2013, 12:24:26 AM6/4/13
to Russ Cox, Gary Burd, golang-dev
On Sat, Jun 1, 2013 at 4:41 AM, Russ Cox <r...@golang.org> wrote:
> What changes are you willing to make? Are you willing to make incompatible changes to the API or drop support for old versions of the protocol?

I'd like to hear from ukai, but speaking just for me:

If there are good reasons to change the API, then sure, I am willing to make incompatible changes.
If there are good reasons to drop the old versions and not much harm, then sure, we can do that too.

This is one of the nice things about being in a subrepo.

I'm fine to make incompatible changes to API if it's ok for users.  In this case, should we provide gofix for the change?

For old versions of the protocol, it seems most browsers now supports the latest version, so I think it's ok to drop old ones.
As far as I know, safari/win uses old version, but I think few people are using it.

I think we should drop old versions and clean up code first, then change the API if necessary.
 

Can you outline the concrete changes you'd suggest in the go.net one?

As far as I remember,
- configure read size limit
  I think we can use io.Reader if user don't want to receive large message.
  it might be better to provide an API to know it has received full message, or partial message because of small buffer for Read.

- ping
  some user wants to send a Ping message.
  It's easy to expose it, but I'm wondering it is good API.
  what user really wants is keep-alive websocket connection by ping/pong with idle-timeout / pong-timeout, or so?
 
-- 
ukai

Russ

Gary Burd

unread,
Jun 4, 2013, 11:09:11 AM6/4/13
to golan...@googlegroups.com, Gary Burd, uk...@google.com
On Friday, May 31, 2013 12:41:17 PM UTC-7, rsc wrote:
Can you outline the concrete changes you'd suggest in the go.net one?

I think that my package is the better starting point for the "one" websocket package. My package meets a broader set of requirements, has simpler code and passes third party protocol compliance tests. I am willing to donate my code to the Go project.
Message has been deleted

Christoph Hack

unread,
Nov 30, 2013, 7:04:25 AM11/30/13
to golan...@googlegroups.com, Gary Burd, uk...@google.com
Sorry for retrieving this old thread, but why has the discussion and the integration process stopped? Handling or avoiding timeouts using the go.net/websocket package is still quite difficult without the ping/pong control frames.

-christoph

Andrew Gerrand

unread,
Dec 1, 2013, 9:37:56 PM12/1/13
to Gary Burd, golang-dev, Fumitoshi Ukai

On 5 June 2013 01:09, Gary Burd <gary...@gmail.com> wrote:
I think that my package is the better starting point for the "one" websocket package. My package meets a broader set of requirements, has simpler code and passes third party protocol compliance tests. I am willing to donate my code to the Go project.

My biggest issue with go.net/websocket is that its websocket.Conn is an io.ReadWriter, but websocket connections are message-based, not a stream. Using the websocket.Conn with types that expect typical io.ReadWriter semantics may cause messages to arrive at the client in fragments.

I have used go.net/websocket quite a bit and just now taken a look at garyburg/go-websocket, and the latter interface is a lot close to what is actually happening on the wire. It is a little more verbose to use the go.net package, but it is much easier to write the correct code.

All else being equal I'm in favor of replacing go.net/websocket with garyburd/go-websocket. If the latter is better tested, then that's just gravy.

Andrew

Daniel Theophanes

unread,
Dec 1, 2013, 9:40:58 PM12/1/13
to Andrew Gerrand, Gary Burd, Fumitoshi Ukai, golang-dev

I agree with agl and second on all points.

> --
>  
> ---
> You received this message because you are subscribed to a topic in the Google Groups "golang-dev" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-dev/646BVRh6s44/unsubscribe.
>
> To unsubscribe from this group and all its topics, send an email to golang-dev+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Daniel Theophanes

unread,
Dec 1, 2013, 9:43:11 PM12/1/13
to Andrew Gerrand, Gary Burd, Fumitoshi Ukai, golang-dev

I mean adg sorry Andrew.

Fumitoshi Ukai (鵜飼文敏)

unread,
Dec 1, 2013, 9:47:15 PM12/1/13
to Andrew Gerrand, Gary Burd, golang-dev

2013/12/2 Andrew Gerrand <a...@golang.org>


On 5 June 2013 01:09, Gary Burd <gary...@gmail.com> wrote:
I think that my package is the better starting point for the "one" websocket package. My package meets a broader set of requirements, has simpler code and passes third party protocol compliance tests. I am willing to donate my code to the Go project.

My biggest issue with go.net/websocket is that its websocket.Conn is an io.ReadWriter, but websocket connections are message-based, not a stream. Using the websocket.Conn with types that expect typical io.ReadWriter semantics may cause messages to arrive at the client in fragments.

My initial attempt to websocket package was somehow message oriented API, but Russ suggested to follow Read/Write API commonly used in go.
Maybe, we might want some common message oriented API? (for udp or so)

-- 
ukai

Andrew Gerrand

unread,
Dec 1, 2013, 9:56:54 PM12/1/13
to Fumitoshi Ukai (鵜飼文敏), Gary Burd, golang-dev
On 2 December 2013 13:47, Fumitoshi Ukai (鵜飼文敏) <uk...@google.com> wrote:
My initial attempt to websocket package was somehow message oriented API, but Russ suggested to follow Read/Write API commonly used in go.

I remember that discussion. It did seem like the right move at the time. But, in retrospect, IMO it's not the right fit.
 
Maybe, we might want some common message oriented API? (for udp or so)

Maybe. I'd rather experiment with what we have now, then for something more broadly useful later.

The garyburd/go-websocket interface:

func (c *Conn) NextReader() (messageType int, r io.Reader, err error)
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error)

is not general purpose, as it includes the messageType result/argument. I don't think such a thing is useful in the UDP protocol.

Andrew

Andrew Gerrand

unread,
Dec 1, 2013, 10:12:03 PM12/1/13
to Fumitoshi Ukai (鵜飼文敏), Gary Burd, golang-dev
Note that Gary's websocket package is now part of Gorilla: https://github.com/gorilla/websocket

Fumitoshi Ukai (鵜飼文敏)

unread,
Dec 1, 2013, 10:34:03 PM12/1/13
to Andrew Gerrand, Gary Burd, golang-dev



2013/12/2 Andrew Gerrand <a...@golang.org>


On 2 December 2013 13:47, Fumitoshi Ukai (鵜飼文敏) <uk...@google.com> wrote:
My initial attempt to websocket package was somehow message oriented API, but Russ suggested to follow Read/Write API commonly used in go.

I remember that discussion. It did seem like the right move at the time. But, in retrospect, IMO it's not the right fit.

Agree.
 
 
Maybe, we might want some common message oriented API? (for udp or so)

Maybe. I'd rather experiment with what we have now, then for something more broadly useful later.

The garyburd/go-websocket interface:

func (c *Conn) NextReader() (messageType int, r io.Reader, err error)
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error)

is not general purpose, as it includes the messageType result/argument. I don't think such a thing is useful in the UDP protocol.

Yeah.
How about drop messageType from here, and get/set it via Reader or Write with type assertion to websocket specific interface?
or make messageType for some type? for udp, we could use that for accessing peer address.

-- 
ukai


Andrew

Russ Cox

unread,
Dec 1, 2013, 10:50:27 PM12/1/13
to Fumitoshi Ukai (鵜飼文敏), Andrew Gerrand, Gary Burd, golang-dev
Reader/Writer may not be the right fit, but I think you still need to have a story for why someone can't send a 4GB wire message and DoS your server. It might be just a max that the user has to set (or override) on a connection.

Russ

Andrew Gerrand

unread,
Dec 1, 2013, 10:55:44 PM12/1/13
to Russ Cox, Fumitoshi Ukai (鵜飼文敏), Gary Burd, golang-dev

On 2 December 2013 14:50, Russ Cox <r...@golang.org> wrote:
Reader/Writer may not be the right fit, but I think you still need to have a story for why someone can't send a 4GB wire message and DoS your server. It might be just a max that the user has to set (or override) on a connection.

I don't understand this point. Here's how the gorilla/websocket package receives a message from its Conn:

_, r, err := c.NextReader()
// handle rr
// read from r

Presumably you could wrap r in an io.LimitedReader or similar to avoid reading forever. In any case, it's up to the user of package websocket to avoid this trap (and it doesn't look like package websocket buffers whole messages anywhere).

Andrew

Andrew Gerrand

unread,
Dec 1, 2013, 10:57:35 PM12/1/13
to Fumitoshi Ukai (鵜飼文敏), Gary Burd, golang-dev

On 2 December 2013 14:34, Fumitoshi Ukai (鵜飼文敏) <uk...@google.com> wrote:
How about drop messageType from here, and get/set it via Reader or Write with type assertion to websocket specific interface?
or make messageType for some type? for udp, we could use that for accessing peer address.

Before getting too bogged down in the details here: does anyone want to write code that can either send/receive datagrams or websocket messages interchangeably? Websocket is like TCP in that it guarantees delivery, while UDP does not. I don't see a good use case for a common interface.

Fumitoshi Ukai (鵜飼文敏)

unread,
Dec 1, 2013, 10:59:11 PM12/1/13
to Russ Cox, Andrew Gerrand, Gary Burd, golang-dev



2013/12/2 Russ Cox <r...@golang.org>

Reader/Writer may not be the right fit, but I think you still need to have a story for why someone can't send a 4GB wire message and DoS your server. It might be just a max that the user has to set (or override) on a connection.

I think major issue with current go.net/websocket is that it uses single Reader/Writer and not visible message boundary for the user.  
garyburd's API provides Reader/Writer for each message, so your point would not be an issue?

-- 
ukai


Russ


Russ Cox

unread,
Dec 1, 2013, 11:03:12 PM12/1/13
to Fumitoshi Ukai (鵜飼文敏), Andrew Gerrand, Gary Burd, golang-dev
Sorry, I clearly misremembered. That sounds fine. I thought people were saying message like []byte.

Russ

Fumitoshi Ukai (鵜飼文敏)

unread,
Dec 1, 2013, 11:04:42 PM12/1/13
to Andrew Gerrand, Gary Burd, golang-dev



2013/12/2 Andrew Gerrand <a...@golang.org>
Hmm.
How about following the way of archive/tar or so?
It reads an file by the EOF, then call Next() to get a next file.
 
-- 
ukai

Andrew Gerrand

unread,
Dec 4, 2013, 2:53:02 AM12/4/13
to Fumitoshi Ukai (鵜飼文敏), Gary Burd, golang-dev
I don't really want to design a new API here.

The main question is whether the go.net/websocket package should be replaced.

Gary's websocket package has found a home in the Gorilla Web Toolkit.
Does it need to be part of the Go project?
Do we retire go.net/websocket? Do we change the API of go.net/websocket?
Do we do nothing?


stephen....@gmail.com

unread,
Dec 7, 2013, 2:03:23 PM12/7/13
to golan...@googlegroups.com, Fumitoshi Ukai (鵜飼文敏), Gary Burd
Doing nothing IMO is the worst option.

I think we either need to change the API of go.net/websocket to support message-based things, or retire it in favor of gorilla/websocket.

I haven't had a chance to look at gorilla/websocket, but how does it hold up against Safari / iOS devices? I remember some websocket packages had problems with those because they use such dated versions of the websocket protocol.

If gorilla/websocket works well with older websocket protocol versions (like go.net/websocket does) then I am in favor of using gorilla/websocket.

Stephen

Gary Burd

unread,
Dec 7, 2013, 9:50:11 PM12/7/13
to golan...@googlegroups.com, Fumitoshi Ukai (鵜飼文敏), Gary Burd, stephen....@gmail.com
On Saturday, December 7, 2013 11:03:23 AM UTC-8, stephen....@gmail.com wrote:
If gorilla/websocket works well with older websocket protocol versions (like go.net/websocket does) then I am in favor of using gorilla/websocket.

The go.net/websocket package does not support older versions of the protocol. See https://codereview.appspot.com/10480043/

stephen....@gmail.com

unread,
Dec 7, 2013, 10:57:37 PM12/7/13
to golan...@googlegroups.com, Fumitoshi Ukai (鵜飼文敏), Gary Burd, stephen....@gmail.com
I stand corrected.

I am in favor of using using gorilla/websocket over go.net/websocket.

Stephen

mortdeus

unread,
Dec 8, 2013, 2:05:58 AM12/8/13
to golan...@googlegroups.com, uk...@google.com, Gary Burd
It would be cool if we could some how abstract websocket.Conn so that we can connect to a appengine channel using the websocket api. Currently there isnt a way to connect a channel between a go appengine server and a native client developed in Go. Currently there is only a JS client for us to connect to. 
  

mortdeus

unread,
Dec 8, 2013, 2:10:30 AM12/8/13
to golan...@googlegroups.com, uk...@google.com, Gary Burd

Fumitoshi Ukai (鵜飼文敏)

unread,
Dec 8, 2013, 7:36:33 AM12/8/13
to mortdeus, golang-dev, Gary Burd
I agree we should change go.net/websocket API.
what changes would be required?  Adding message based API? (reader or writer per message, or requires Next or WriteHeader at message boundaries?)
I also think it should be modified in handshaking, especially subprotocol dispatching.
how much do we need to preserve API compatibility?

-- 
ukai


2013/12/8 mortdeus <mort...@gocos2d.org>

m.sriv...@gmail.com

unread,
Feb 23, 2014, 8:05:09 AM2/23/14
to golan...@googlegroups.com, mortdeus, Gary Burd, uk...@google.com
Hi,

I am using the go.net/websocket package that shipped along with v1.2.  After going through this discussion, I am curious to know if I could still bank on that or go with 3rd-party package.  Personally, I prefer the standard packages, how much ever good the other packages might be.

Thanks and rgds,
Vatsan

Andrew Gerrand

unread,
Feb 23, 2014, 10:16:44 PM2/23/14
to m.sriv...@gmail.com, golang-dev, mortdeus, Gary Burd, Fumitoshi Ukai
It seems like progress toward consolidation has stalled. I used gorilla/websocket for a recent personal project and found it gave me everything I needed.

Srivathsan: you can still bank on the go.net/websocket package sticking around for a while. Why do you prefer it over the others, though? It seems strange that you prefer it "how much ever good the other packages might be." Why is that?

Andrew

Vatsan

unread,
Feb 23, 2014, 10:31:19 PM2/23/14
to Andrew Gerrand, golang-dev, mortdeus, Gary Burd, Fumitoshi Ukai
@Andrew: nothing but a subjective bias on my part.  To the extent possible, I try to stick with standard distributions.  go.net/websocket, even though it is still not part of the standard (go) library, it is shipped along with v1.2 but under $GOROOT/pkg/src/code.google.com/p/go.net/websocket.  Hence my choice of that.

My original question was a consequence of my understanding of this discussion thread wherein I see that go.net/websocket is in for a change.

rgds,
Vatsan

minux

unread,
Feb 23, 2014, 10:46:07 PM2/23/14
to Vatsan, Andrew Gerrand, golang-dev, mortdeus, Gary Burd, Fumitoshi Ukai
On Sun, Feb 23, 2014 at 10:31 PM, Vatsan <m.sriv...@gmail.com> wrote:
@Andrew: nothing but a subjective bias on my part.  To the extent possible, I try to stick with standard distributions.  go.net/websocket, even though it is still not part of the standard (go) library, it is shipped along with v1.2 but under $GOROOT/pkg/src/code.google.com/p/go.net/websocket
Are you sure go.net is shipped with Go 1.2 in $GOROOT/src/pkg/code.google.com/p/go.net/websocket
(I assumed you made a typo here, $GOROOT/pkg doesn't contain src).

If it's shipped in that location, then it means it will override user's installation of go.net, which is
certainly not intended.

Vatsan

unread,
Feb 23, 2014, 11:21:26 PM2/23/14
to minux, Andrew Gerrand, golang-dev, mortdeus, Gary Burd, Fumitoshi Ukai
@minux: my apologies, I still don't know how it go into my $GOROOT.  The original tar.gz of v1.2 binaries doesn't have it

rgds,
Vatsan

minux

unread,
Feb 23, 2014, 11:27:15 PM2/23/14
to Vatsan, Andrew Gerrand, golang-dev, mortdeus, Gary Burd, Fumitoshi Ukai
On Sun, Feb 23, 2014 at 11:21 PM, Vatsan <m.sriv...@gmail.com> wrote:
@minux: my apologies, I still don't know how it go into my $GOROOT.  The original tar.gz of v1.2 binaries doesn't have it
Probably when you use older version of Go (pre 1.2), you go get code.google.com/p/go.net without
having GOPATH set (or exported), and it installed to your GOROOT.
Reply all
Reply to author
Forward
0 new messages