gorilla / websocket

Package gorilla/websocket is a fast, well-tested and widely used WebSocket implementation for Go.

Home Page:https://gorilla.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support WebAssembly / GopherJS

silbinarywolf opened this issue · comments

commented

While I understand that the following implementation exists:
https://github.com/gopherjs/websocket

It'd be nice if I could write code once for my game project that runs natively and on the web.

If I were to make a PR with support for GopherJS / WebAssembly and assuming the code is all good, would it be accepted?

I am not the owner of the project, but I think think a rough outline of your proposal will be required to answer your question. Some things that the outline might include:

  • Will this include the client API only? Will this include features that are only useful on the server like WritePeparedMessage?
  • What is the plan for Conn methods that cannot be supported in the browser (UnderlyingConn, SetPingHandler, SetPongHandler, ...)?
  • Same question for the Dialer. The Subprotocols field is the only relevant Dialer field in the browser. The header arguments to Dial method is cannot be supported in the browser.
  • How will the code be structured given that the Conn implementation will be completely different from the current code? Are there two packages that share a common interface for the connection or are build tags used to switch implementations in the current package?
commented

Thanks for giving me something to think about. I'm not convinced the following is a good idea, but it's currently unclear to me on how we could go about this in a better way.

  • The client API is all I personally need, so that'd be what I'd want to target initially and I haven't given it any thought really. I suppose it would need to fail on browsers but work for NodeJS?
  • I'm thinking SetPingHandler and SetPongHandler would become no-ops (assuming you only use for setting read deadlines)
  • Panic on header arguments that are impossible in the browser. If you're maintaining your code to work with both Web/Native, then you won't utilize arguments that aren't supported.
  • Build tags to switch between wasm and non-wasm code.

Regarding headers: Is it possible to write cross platform code that Dials a connection? When running in the browser, cookies, user agent and other headers are handled automatically by the browser. When running outside the browser, the application is responsible for supplying all of these headers.

Once the connection is hand, it does seem that cross platform code is possible.

Help wanted: Describe the subset of the package API that will work in the browser and describe how that API will be implemented in the browser.

I recently helped add WebAssembly support to pion/webrtc and have an open PR to do the same for goleveldb. I would be interested in building WebAssembly support for this package to and we would use it in libp2p/go-ws-transport and 0xProject/0x-mesh (my project at work).

Is this still something you're interested in and would you accept a PR?

After looking more at the API for gorilla/websocket, I think adding WebAssembly support is harder than I first imagined. The API surface area is large and too much of it would not translate well to the native JavaScript API (this is in contrast to pion/webrtc which closely mimics the JavaScript API and goleveldb where only a small portion of the code related to storage needed to be changed at all). For now, it was much easier for me to add WebAssembly support in the higher-level libp2p/go-ws-transport package. I can still help offer advice or review a PR if someone else wants to take this on.

For anyone who needs this feature now, I've implemented it v1.6.3 of my WebSocket library with @albrow's review.

See https://godoc.org/nhooyr.io/websocket#hdr-Wasm