A fast, well-tested and widely used WebSocket implementation for Go.

Gorilla WebSocket

GoDoc CircleCI

Gorilla WebSocket is a Go implementation of the WebSocket protocol.

Documentation

Status

The Gorilla WebSocket package provides a complete and tested implementation of the WebSocket protocol. The package API is stable.

Installation

go get github.com/gorilla/websocket

Protocol Compliance

The Gorilla WebSocket package passes the server tests in the Autobahn Test Suite using the application in the examples/autobahn subdirectory.

Gorilla WebSocket compared with other packages

github.com/gorilla golang.org/x/net
RFC 6455 Features
Passes Autobahn Test Suite Yes No
Receive fragmented message Yes No, see note 1
Send close message Yes No
Send pings and receive pongs Yes No
Get the type of a received data message Yes Yes, see note 2
Other Features
Compression Extensions Experimental No
Read message using io.Reader Yes No, see note 3
Write message using io.WriteCloser Yes No, see note 3

Notes:

  1. Large messages are fragmented in Chrome's new WebSocket implementation.
  2. The application can get the type of a received data message by implementing a Codec marshal function.
  3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. Read returns when the input buffer is full or a frame boundary is encountered. Each call to Write sends a single frame message. The Gorilla io.Reader and io.WriteCloser operate on a single WebSocket message.
Owner
Gorilla Web Toolkit
Gorilla is a web toolkit for the Go programming language that provides useful, composable packages for writing HTTP-based applications.
Gorilla Web Toolkit
Comments
  • Implement Compression Extensions

    Implement Compression Extensions

    Draft RFC: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-17

    Work remaining:

    • [ ] Add fields to Dialer for specifying compression options.

    • [ ] Add fields to Upgrader for specifying compression options.

    • [ ] Add compression negotiation Upgrader.

    • [ ] Add compression negotiation to Dialer.

    • [ ] Add function to enable/disable write compression:

      // EnableWriteCompression enables and disables write compression of
      // subsequent text and binary messages. This function is a noop if
      // compression was not negotiated with the peer.
      func (c *Conn) EnableWriteCompression(enable bool) {
             c.enableWriteCompression = enable
      }
      
  • ⚠️ New maintainers needed

    ⚠️ New maintainers needed

    I am stepping down as the maintainer of the gorilla/WebSocket project.

    I am looking for a new maintainer for the project. The new maintainer should have a track record of successfully maintaining an open-source project and implementing RFCs.

    Potential maintainers can gain the required experience by contributing to this project. I need help triaging issues, reviewing PRs, and fixing issues labeled "help wanted." If you are interested, jump in and start contributing.

    If you rely on the quality and ongoing maintenance of this package, please get involved by helping to maintain this package or finding people to help maintain the project.

  • Improve

    Improve "Origin" check logic to compare scheme & ports

    This function - "checkSameOrigin" here: https://github.com/gorilla/websocket/blob/master/server.go#L74

    compares the request Host header with the request Origin header.

    I'm using a client where the Host header contains the port (which is legit according to these docs). So it has:

    Host: example.com:443
    

    (actually the client code sets it here: https://github.com/daltoniam/Starscream/blob/master/Sources/WebSocket.swift#L590 )

    The Origin header contains scheme and might contain the port (see spec here). In my case it looks like so:

    Origin: wss://example.com
    

    Since wss://example.com is equivalent to wss://example.com:443, it should match the Host above.

    I propose to enhance checkSameOrigin to support schemes, ports and default ports.

  • dead lock in websocket.Upgrade on linux/arm (raspberry pi) with crosscompile

    dead lock in websocket.Upgrade on linux/arm (raspberry pi) with crosscompile

    Testcase: Echo example (javascript client --> golang server).

    https://gist.github.com/tmichel/7390690

    ws.go cross compiled in windows for ARM (linux/raspberry pi). go version go1.8 windows/amd64 latest gorilla/websocket version.

    Problem: call to: conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)

    does not return?

    After one or two minutes I got an exception.

    With golang ws server on windows I have no problem.

    Here is the stack dump, profile and heap:

    goroutine 19 [running]: runtime/pprof.writeGoroutineStacks(0x4a1140, 0x108a1320, 0x0, 0x10811500) C:/Go/src/runtime/pprof/pprof.go:603 +0x58 runtime/pprof.writeGoroutine(0x4a1140, 0x108a1320, 0x2, 0x20, 0x117c0) C:/Go/src/runtime/pprof/pprof.go:592 +0x30 runtime/pprof.(*Profile).WriteTo(0x4c7b90, 0x4a1140, 0x108a1320, 0x2, 0x108a1320, 0x4cd738) C:/Go/src/runtime/pprof/pprof.go:302 +0x2b0 net/http/pprof.handler.ServeHTTP(0x10896dc1, 0x9, 0x4a3110, 0x108a1320, 0x108acf00) C:/Go/src/net/http/pprof/pprof.go:209 +0x168 net/http/pprof.Index(0x4a3110, 0x108a1320, 0x108acf00) C:/Go/src/net/http/pprof/pprof.go:221 +0x17c net/http.HandlerFunc.ServeHTTP(0x358158, 0x4a3110, 0x108a1320, 0x108acf00) C:/Go/src/net/http/server.go:1942 +0x34 net/http.(*ServeMux).ServeHTTP(0x4cd738, 0x4a3110, 0x108a1320, 0x108acf00) C:/Go/src/net/http/server.go:2238 +0x108 net/http.serverHandler.ServeHTTP(0x10874080, 0x4a3110, 0x108a1320, 0x108acf00) C:/Go/src/net/http/server.go:2568 +0x7c net/http.(*conn).serve(0x1089f4a0, 0x4a36e8, 0x10877aa0) C:/Go/src/net/http/server.go:1825 +0x528 created by net/http.(*Server).Serve C:/Go/src/net/http/server.go:2668 +0x234

    goroutine 1 [IO wait]: net.runtime_pollWait(0x76da2f78, 0x72, 0x0) C:/Go/src/runtime/netpoll.go:164 +0x44 net.(*pollDesc).wait(0x108160fc, 0x72, 0x0, 0x109051c0) C:/Go/src/net/fd_poll_runtime.go:75 +0x28 net.(*pollDesc).waitRead(0x108160fc, 0xffffffff, 0x0) C:/Go/src/net/fd_poll_runtime.go:80 +0x24 net.(*netFD).accept(0x108160c0, 0x0, 0x4a1218, 0x109051c0) C:/Go/src/net/fd_unix.go:430 +0x15c net.(*TCPListener).accept(0x1080c0e0, 0x202504, 0x1089f780, 0x2fb618) C:/Go/src/net/tcpsock_posix.go:136 +0x20 net.(*TCPListener).AcceptTCP(0x1080c0e0, 0x6983c, 0x10835f18, 0x10835f1c) C:/Go/src/net/tcpsock.go:215 +0x3c net/http.tcpKeepAliveListener.Accept(0x1080c0e0, 0x358080, 0x1089f740, 0x4a3760, 0x108103c0) C:/Go/src/net/http/server.go:3044 +0x1c net/http.(*Server).Serve(0x10874080, 0x4a31f0, 0x1080c0e0, 0x0, 0x0) C:/Go/src/net/http/server.go:2643 +0x1ac net/http.(*Server).ListenAndServe(0x10874080, 0x10874080, 0x1) C:/Go/src/net/http/server.go:2585 +0x90 net/http.ListenAndServe(0x33ed25, 0x5, 0x0, 0x0, 0x108000f0, 0x108000f0) C:/Go/src/net/http/server.go:2787 +0x70 main.main() e:/gopath/src/ttt/ws/ws.go:21 +0x68

    goroutine 4 [semacquire]: sync.runtime_notifyListWait(0x10810508, 0x0) C:/Go/src/runtime/sema.go:297 +0x138 sync.(*Cond).Wait(0x10810500) C:/Go/src/sync/cond.go:57 +0x78 net/http.(*connReader).abortPendingRead(0x1084e0f0) C:/Go/src/net/http/server.go:686 +0xbc net/http.(*conn).hijackLocked(0x1090a120, 0x3583c8, 0x1090a168, 0x10912130, 0x76da2ff0, 0x241c08) C:/Go/src/net/http/server.go:292 +0x2c net/http.(*response).Hijack(0x10814090, 0x0, 0x0, 0x0, 0x0, 0x0) C:/Go/src/net/http/server.go:1892 +0xb8 github.com/gorilla/websocket.(*Upgrader).Upgrade(0x1083ad84, 0x4a3110, 0x10814090, 0x10874100, 0x10810640, 0x15, 0x10874180, 0x0) e:/gopath/src/github.com/gorilla/websocket/server.go:164 +0x314 github.com/gorilla/websocket.Upgrade(0x4a3110, 0x10814090, 0x10874100, 0x10810640, 0x400, 0x400, 0x0, 0x0, 0x10818024) e:/gopath/src/github.com/gorilla/websocket/server.go:269 +0x68 main.wsHandler(0x4a3110, 0x10814090, 0x10874100) e:/gopath/src/ttt/ws/ws.go:38 +0xac net/http.HandlerFunc.ServeHTTP(0x357fa4, 0x4a3110, 0x10814090, 0x10874100) C:/Go/src/net/http/server.go:1942 +0x34 net/http.(*ServeMux).ServeHTTP(0x4cd738, 0x4a3110, 0x10814090, 0x10874100) C:/Go/src/net/http/server.go:2238 +0x108 net/http.serverHandler.ServeHTTP(0x10874080, 0x4a3110, 0x10814090, 0x10874100) C:/Go/src/net/http/server.go:2568 +0x7c net/http.(*conn).serve(0x1090a120, 0x4a36e8, 0x10810460) C:/Go/src/net/http/server.go:1825 +0x528 created by net/http.(*Server).Serve C:/Go/src/net/http/server.go:2668 +0x234

    goroutine 5 [IO wait]: net.runtime_pollWait(0x76da2f00, 0x72, 0x1084e0fd) C:/Go/src/runtime/netpoll.go:164 +0x44 net.(*pollDesc).wait(0x108161fc, 0x72, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_poll_runtime.go:75 +0x28 net.(*pollDesc).waitRead(0x108161fc, 0x1084e0fd, 0x1) C:/Go/src/net/fd_poll_runtime.go:80 +0x24 net.(*netFD).Read(0x108161c0, 0x1084e0fd, 0x1, 0x1, 0x0, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_unix.go:250 +0x148 net.(*conn).Read(0x1080c0f8, 0x1084e0fd, 0x1, 0x1, 0x0, 0x0, 0x0) C:/Go/src/net/net.go:181 +0x58 net/http.(*connReader).backgroundRead(0x1084e0f0) C:/Go/src/net/http/server.go:656 +0x44 created by net/http.(*connReader).startBackgroundRead C:/Go/src/net/http/server.go:652 +0xd4

    goroutine 51 [IO wait]: net.runtime_pollWait(0x76da2e10, 0x72, 0x1091a000) C:/Go/src/runtime/netpoll.go:164 +0x44 net.(*pollDesc).wait(0x108164bc, 0x72, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_poll_runtime.go:75 +0x28 net.(*pollDesc).waitRead(0x108164bc, 0x1091a000, 0x1000) C:/Go/src/net/fd_poll_runtime.go:80 +0x24 net.(*netFD).Read(0x10816480, 0x1091a000, 0x1000, 0x1000, 0x0, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_unix.go:250 +0x148 net.(*conn).Read(0x10878790, 0x1091a000, 0x1000, 0x1000, 0x0, 0x0, 0x0) C:/Go/src/net/net.go:181 +0x58 net/http.(*connReader).Read(0x10896cf0, 0x1091a000, 0x1000, 0x1000, 0x0, 0x0, 0x0) C:/Go/src/net/http/server.go:754 +0x168 bufio.(*Reader).fill(0x109000c0) C:/Go/src/bufio/bufio.go:97 +0xf4 bufio.(*Reader).ReadSlice(0x109000c0, 0xa, 0x0, 0x8d, 0x5e4dff9c, 0x0, 0x0) C:/Go/src/bufio/bufio.go:338 +0x9c bufio.(*Reader).ReadLine(0x109000c0, 0x8, 0x9, 0x0, 0x0, 0x80, 0x7d30c) C:/Go/src/bufio/bufio.go:367 +0x24 net/textproto.(*Reader).readLineSlice(0x10810ec0, 0x0, 0x1f8b40, 0x1f8b54, 0x80, 0x332160) C:/Go/src/net/textproto/reader.go:55 +0x44 net/textproto.(*Reader).ReadLine(0x10810ec0, 0x108acd80, 0x80000000, 0x0, 0x80000000) C:/Go/src/net/textproto/reader.go:36 +0x1c net/http.readRequest(0x109000c0, 0x0, 0x108acd80, 0x0, 0x0) C:/Go/src/net/http/request.go:918 +0x5c net/http.(*conn).readRequest(0x1089f6e0, 0x4a36e8, 0x10811240, 0x0, 0x0, 0x0) C:/Go/src/net/http/server.go:934 +0x214 net/http.(*conn).serve(0x1089f6e0, 0x4a36e8, 0x10811240) C:/Go/src/net/http/server.go:1763 +0x3b4 created by net/http.(*Server).Serve C:/Go/src/net/http/server.go:2668 +0x234

    goroutine 52 [IO wait]: net.runtime_pollWait(0x76da2d98, 0x72, 0x10917000) C:/Go/src/runtime/netpoll.go:164 +0x44 net.(*pollDesc).wait(0x108165bc, 0x72, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_poll_runtime.go:75 +0x28 net.(*pollDesc).waitRead(0x108165bc, 0x10917000, 0x1000) C:/Go/src/net/fd_poll_runtime.go:80 +0x24 net.(*netFD).Read(0x10816580, 0x10917000, 0x1000, 0x1000, 0x0, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_unix.go:250 +0x148 net.(*conn).Read(0x108787a0, 0x10917000, 0x1000, 0x1000, 0x0, 0x0, 0x0) C:/Go/src/net/net.go:181 +0x58 net/http.(*connReader).Read(0x10896d20, 0x10917000, 0x1000, 0x1000, 0x0, 0x0, 0x0) C:/Go/src/net/http/server.go:754 +0x168 bufio.(*Reader).fill(0x10896810) C:/Go/src/bufio/bufio.go:97 +0xf4 bufio.(*Reader).ReadSlice(0x10896810, 0xa, 0x0, 0x8d, 0x1e9f4, 0x0, 0x0) C:/Go/src/bufio/bufio.go:338 +0x9c bufio.(*Reader).ReadLine(0x10896810, 0x14, 0x9, 0x10811300, 0x0, 0x80, 0x10850000) C:/Go/src/bufio/bufio.go:367 +0x24 net/textproto.(*Reader).readLineSlice(0x10811300, 0x10811300, 0x1f8b40, 0x1f8b54, 0x80, 0x332160) C:/Go/src/net/textproto/reader.go:55 +0x44 net/textproto.(*Reader).ReadLine(0x10811300, 0x108ace00, 0x80000000, 0x0, 0x80000000) C:/Go/src/net/textproto/reader.go:36 +0x1c net/http.readRequest(0x10896810, 0x0, 0x108ace00, 0x0, 0x0) C:/Go/src/net/http/request.go:918 +0x5c net/http.(*conn).readRequest(0x1089f740, 0x4a36e8, 0x108112e0, 0x0, 0x0, 0x0) C:/Go/src/net/http/server.go:934 +0x214 net/http.(*conn).serve(0x1089f740, 0x4a36e8, 0x108112e0) C:/Go/src/net/http/server.go:1763 +0x3b4 created by net/http.(*Server).Serve C:/Go/src/net/http/server.go:2668 +0x234

    goroutine 54 [IO wait]: net.runtime_pollWait(0x76da2e88, 0x72, 0x1089678d) C:/Go/src/runtime/netpoll.go:164 +0x44 net.(*pollDesc).wait(0x108faf7c, 0x72, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_poll_runtime.go:75 +0x28 net.(*pollDesc).waitRead(0x108faf7c, 0x1089678d, 0x1) C:/Go/src/net/fd_poll_runtime.go:80 +0x24 net.(*netFD).Read(0x108faf40, 0x1089678d, 0x1, 0x1, 0x0, 0x4a1938, 0x4a00e4) C:/Go/src/net/fd_unix.go:250 +0x148 net.(*conn).Read(0x10878638, 0x1089678d, 0x1, 0x1, 0x0, 0x0, 0x0) C:/Go/src/net/net.go:181 +0x58 net/http.(*connReader).backgroundRead(0x10896780) C:/Go/src/net/http/server.go:656 +0x44 created by net/http.(*connReader).startBackgroundRead C:/Go/src/net/http/server.go:652 +0xd4

    Profile: goroutine profile: total 7 2 @ 0x3d008 0x38354 0x377d8 0x135f14 0x135f64 0x1373ec 0x146b64 0x1fd88c 0x6c15c

    0x377d7 net.runtime_pollWait+0x43 C:/Go/src/runtime/netpoll.go:164

    0x135f13 net.(*pollDesc).wait+0x27 C:/Go/src/net/fd_poll_runtime.go:75

    0x135f63 net.(*pollDesc).waitRead+0x23 C:/Go/src/net/fd_poll_runtime.go:80

    0x1373eb net.(*netFD).Read+0x147 C:/Go/src/net/fd_unix.go:250

    0x146b63 net.(*conn).Read+0x57 C:/Go/src/net/net.go:181

    0x1fd88b net/http.(*connReader).backgroundRead+0x43 C:/Go/src/net/http/server.go:656

    2 @ 0x3d008 0x38354 0x377d8 0x135f14 0x135f64 0x1373ec 0x146b64 0x1fddb4 0xfd5c4 0xfe3e8 0xfe5c0 0x1a024c 0x1a00c4 0x1f8b68 0x1fedfc 0x202b18 0x6c15c

    0x377d7 net.runtime_pollWait+0x43 C:/Go/src/runtime/netpoll.go:164

    0x135f13 net.(*pollDesc).wait+0x27 C:/Go/src/net/fd_poll_runtime.go:75

    0x135f63 net.(*pollDesc).waitRead+0x23 C:/Go/src/net/fd_poll_runtime.go:80

    0x1373eb net.(*netFD).Read+0x147 C:/Go/src/net/fd_unix.go:250

    0x146b63 net.(*conn).Read+0x57 C:/Go/src/net/net.go:181

    0x1fddb3 net/http.(*connReader).Read+0x167 C:/Go/src/net/http/server.go:754

    0xfd5c3 bufio.(*Reader).fill+0xf3 C:/Go/src/bufio/bufio.go:97

    0xfe3e7 bufio.(*Reader).ReadSlice+0x9b C:/Go/src/bufio/bufio.go:338

    0xfe5bf bufio.(*Reader).ReadLine+0x23 C:/Go/src/bufio/bufio.go:367

    0x1a024b net/textproto.(*Reader).readLineSlice+0x43 C:/Go/src/net/textproto/reader.go:55

    0x1a00c3 net/textproto.(*Reader).ReadLine+0x1b C:/Go/src/net/textproto/reader.go:36

    0x1f8b67 net/http.readRequest+0x5b C:/Go/src/net/http/request.go:918

    0x1fedfb net/http.(*conn).readRequest+0x213 C:/Go/src/net/http/server.go:934

    0x202b17 net/http.(*conn).serve+0x3b3 C:/Go/src/net/http/server.go:1763

    1 @ 0x2ade84 0x2adcdc 0x2aacb4 0x2b0cb4 0x2b0f1c 0x204094 0x20502c 0x205f84 0x202c8c 0x6c15c

    0x2ade83 runtime/pprof.writeRuntimeProfile+0x77 C:/Go/src/runtime/pprof/pprof.go:632

    0x2adcdb runtime/pprof.writeGoroutine+0x73 C:/Go/src/runtime/pprof/pprof.go:594

    0x2aacb3 runtime/pprof.(*Profile).WriteTo+0x2af C:/Go/src/runtime/pprof/pprof.go:302

    0x2b0cb3 net/http/pprof.handler.ServeHTTP+0x167 C:/Go/src/net/http/pprof/pprof.go:209

    0x2b0f1b net/http/pprof.Index+0x17b C:/Go/src/net/http/pprof/pprof.go:221

    0x204093 net/http.HandlerFunc.ServeHTTP+0x33 C:/Go/src/net/http/server.go:1942

    0x20502b net/http.(*ServeMux).ServeHTTP+0x107 C:/Go/src/net/http/server.go:2238

    0x205f83 net/http.serverHandler.ServeHTTP+0x7b C:/Go/src/net/http/server.go:2568

    0x202c8b net/http.(*conn).serve+0x527 C:/Go/src/net/http/server.go:1825

    1 @ 0x3d008 0x38354 0x377d8 0x135f14 0x135f64 0x138684 0x150238 0x14e860 0x207364 0x206324 0x2060a4 0x206ca0 0x2b11fc 0x3cbc0 0x6c15c

    0x377d7 net.runtime_pollWait+0x43 C:/Go/src/runtime/netpoll.go:164

    0x135f13 net.(*pollDesc).wait+0x27 C:/Go/src/net/fd_poll_runtime.go:75

    0x135f63 net.(*pollDesc).waitRead+0x23 C:/Go/src/net/fd_poll_runtime.go:80

    0x138683 net.(*netFD).accept+0x15b C:/Go/src/net/fd_unix.go:430

    0x150237 net.(*TCPListener).accept+0x1f C:/Go/src/net/tcpsock_posix.go:136

    0x14e85f net.(*TCPListener).AcceptTCP+0x3b C:/Go/src/net/tcpsock.go:215

    0x207363 net/http.tcpKeepAliveListener.Accept+0x1b C:/Go/src/net/http/server.go:3044

    0x206323 net/http.(*Server).Serve+0x1ab C:/Go/src/net/http/server.go:2643

    0x2060a3 net/http.(*Server).ListenAndServe+0x8f C:/Go/src/net/http/server.go:2585

    0x206c9f net/http.ListenAndServe+0x6f C:/Go/src/net/http/server.go:2787

    0x2b11fb main.main+0x67 e:/gopath/src/ttt/ws/ws.go:21

    0x3cbbf runtime.main+0x1e3 C:/Go/src/runtime/proc.go:185

    1 @ 0x3d008 0x3d0d0 0x4da58 0x7cbf8 0x1fda64 0x1fc098 0x203b14 0x241c28 0x242cbc 0x2b147c 0x204094 0x20502c 0x205f84 0x202c8c 0x6c15c

    0x4da57 sync.runtime_notifyListWait+0x137 C:/Go/src/runtime/sema.go:297

    0x7cbf7 sync.(*Cond).Wait+0x77 C:/Go/src/sync/cond.go:57

    0x1fda63 net/http.(*connReader).abortPendingRead+0xbb C:/Go/src/net/http/server.go:686

    0x1fc097 net/http.(*conn).hijackLocked+0x2b C:/Go/src/net/http/server.go:292

    0x203b13 net/http.(*response).Hijack+0xb7 C:/Go/src/net/http/server.go:1892

    0x241c27 github.com/gorilla/websocket.(*Upgrader).Upgrade+0x313 e:/gopath/src/github.com/gorilla/websocket/server.go:164

    0x242cbb github.com/gorilla/websocket.Upgrade+0x67 e:/gopath/src/github.com/gorilla/websocket/server.go:269

    0x2b147b main.wsHandler+0xab e:/gopath/src/ttt/ws/ws.go:38

    0x204093 net/http.HandlerFunc.ServeHTTP+0x33 C:/Go/src/net/http/server.go:1942

    0x20502b net/http.(*ServeMux).ServeHTTP+0x107 C:/Go/src/net/http/server.go:2238

    0x205f83 net/http.serverHandler.ServeHTTP+0x7b C:/Go/src/net/http/server.go:2568

    0x202c8b net/http.(*conn).serve+0x527 C:/Go/src/net/http/server.go:1825

    HEAP:

    heap profile: 1: 16 [1: 16] @ heap/1048576 1: 16 [1: 16] @ 0x1b8c18 0x1b89e4 0x1ba7e4 0x21a100 0x2b178c 0x3cb74 0x6c15c

    0x1b8c17 vendor/golang_org/x/net/http2/hpack.addDecoderNode+0x1f3 C:/Go/src/vendor/golang_org/x/net/http2/hpack/huffman.go:144

    0x1b89e3 vendor/golang_org/x/net/http2/hpack.init.1+0x6f C:/Go/src/vendor/golang_org/x/net/http2/hpack/huffman.go:127

    0x1ba7e3 vendor/golang_org/x/net/http2/hpack.init+0x158f C:/Go/src/vendor/golang_org/x/net/http2/hpack/tables.go:353

    0x21a0ff net/http.init+0xb3 C:/Go/src/net/http/transport.go:2184

    0x2b178b main.init+0x47 e:/gopath/src/ttt/ws/ws.go:63

    0x3cb73 runtime.main+0x197 C:/Go/src/runtime/proc.go:173

    0: 0 [0: 0] @ 0x2ac4b4 0x2aacb4 0x2b0cb4 0x2b0f1c 0x204094 0x20502c 0x205f84 0x202c8c 0x6c15c

    0x2ac4b3 runtime/pprof.writeHeap+0x63 C:/Go/src/runtime/pprof/pprof.go:489

    0x2aacb3 runtime/pprof.(*Profile).WriteTo+0x2af C:/Go/src/runtime/pprof/pprof.go:302

    0x2b0cb3 net/http/pprof.handler.ServeHTTP+0x167 C:/Go/src/net/http/pprof/pprof.go:209

    0x2b0f1b net/http/pprof.Index+0x17b C:/Go/src/net/http/pprof/pprof.go:221

    0x204093 net/http.HandlerFunc.ServeHTTP+0x33 C:/Go/src/net/http/server.go:1942

    0x20502b net/http.(*ServeMux).ServeHTTP+0x107 C:/Go/src/net/http/server.go:2238

    0x205f83 net/http.serverHandler.ServeHTTP+0x7b C:/Go/src/net/http/server.go:2568

    0x202c8b net/http.(*conn).serve+0x527 C:/Go/src/net/http/server.go:1825

    runtime.MemStats

    Alloc = 417584

    TotalAlloc = 417584

    Sys = 21568636

    Lookups = 17

    Mallocs = 6452

    Frees = 396

    HeapAlloc = 417584

    HeapSys = 1703936

    HeapIdle = 688128

    HeapInuse = 1015808

    HeapReleased = 0

    HeapObjects = 6056

    Stack = 393216 / 393216

    MSpan = 10856 / 16384

    MCache = 2400 / 16384

    BuckHashSys = 722973

    GCSys = 17501184

    OtherSys = 1214559

    NextGC = 4473924

    PauseNs = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

    NumGC = 0

    DebugGC = false

  • Add support for fasthttp

    Add support for fasthttp

    So this is a bit of a "speculative" PR in that I don't know if you guys are open to this kind of contribution and also whether the way I have written it matches the rest of the project.

    The basic idea is I need websocket support in a project which uses the relatively new Go HTTP package fasthttp.

    Gorilla websocket seemed like the best option to add this.

    As you can see in the diff I have refactored various non-exported utility functions to make them usable from both net/http and fasthttp code, and then I added a FastHTTPUpgrader. The way fasthttp does hijacking is quite a bit different (and better IMO) than net/http, so the FastHTTPUpgrader .UpgradeHandler() is quite a bit more sane than the one for the standard Upgrader.Upgrade().

    The existing tests pass but I did not add any tests for my addition. I could do that but didn't want to spend the time if this PR would be rejected.

  • wss client sample

    wss client sample

    Hi .

    We are trying to create a secure WS with self signed certificates . Taken the chat sample changed home.html to use wss and it works. BUT When a GO client (already working without tls) , and are getting various results from x509: certificate signed by unknown authority if skipverify = false to tls: oversized record received with length 20527 when its true . sample client (with commented code of some of the trial and error) , server , html and cert creator (from tls package) is attached .

    chat1.zip

    Thanks, Guy .

  • It eats tremendous amout of memory on high load

    It eats tremendous amout of memory on high load

    Hello I tried to use it for real time MMO game. And got a problem with garbage collector working constantly. With 1000 clients each sending and receiving 100 messages per second library generates ~10 Gb of memory in 2 minutes. In contrast, google's x/net/websocket generates about 10 times less work for gc. Here is 2 first line from profiler gathered during 2 min of work:

    (pprof) top10 12.02GB of 12.47GB total (96.38%) Dropped 63 nodes (cum <= 0.06GB) Showing top 10 nodes out of 35 (cum >= 0.10GB) flat flat% sum% cum cum% 6.73GB 53.94% 53.94% 6.73GB 53.94% bytes.makeSlice 2.30GB 18.45% 72.38% 9.02GB 72.38% io/ioutil.readAll

    Here is a place where the memory usage get generated g1 g2

    It could be easily fixed when you would allow passing pre-allocated buffers as arguments to readMessage instead of allocating it per each frame.

    I am ready to provide any further information when you are interested.

  • Sometimes i got

    Sometimes i got "unexpected reserved bits 0x40" with client of unity by BestHttp

    My Unity client with the lib of BestHttp. And on production env, server sometimes got err "unexpected reserved bits 0x40". I don't understand, please help me, thanks.

  • gorilla always encouter unexpected EOF, but google's version works well

    gorilla always encouter unexpected EOF, but google's version works well

    For easy to deployment, I use golang to re-implement my python's websocket client but always encouter the unexpected EOF error. Actually, my programs implement a pipeline of HTTP to websocket to HTTP, the websocket client keeps a long connection to a remote http server and proxy the remote request to the local http backend. The test method is using the apache httpd tool: ab -n 10000 -c 300 http://remote-http-domain/ Both the python client and the google's code.google.com/p/go.net/websocket are work well. Sorry about I'm an one-day-old golang newer and the next Monday I must commit my codes, so I just issue this problem and no further advice. Thanks for your consideration!

  • Allocate write buffers only when needed

    Allocate write buffers only when needed

    A write buffer is allocated to the connection for the lifetime of the connection, but the buffer is only needed when the application is writing a message. Use the Go 1.3 sync.Pool type (https://code.google.com/p/go/source/detail?r=2d9fe00d6ce1) to get and put write buffers as needed.

  • [feature] Avoid unnecessary heap allocations

    [feature] Avoid unnecessary heap allocations

    https://github.com/gorilla/websocket/blob/ae1634f6a98965ded3b8789c626cb4e0bd78c3de/conn.go#L951

    In our profiles this is the number one source of heap allocations, because a messageReader is allocated for every single message read. A messageReader is nothing more than a *Conn so this really doesn't seem necessary to be heap allocated.

    I think a very simple solution without changing the code much would be to have a messageReader value (not pointer) stored on the Conn that can be re-used instead of a heap allocated object. The messageReader and reader pointers could still exist and then just point to the address of the value on the Conn. This would work fine as long as there are not multiple readers inflight or they need to outlive their time as .reader/.messageReader, I don't know the code well enough but I would assume this isn't the case.

    I'm happy to make a patch for this.

  • unreasonable

    unreasonable

    c.readErrCount++ if c.readErrCount >= 1000 { panic("repeated read on failed websocket connection") } application long time run maybe happen error ,therefore shouldn't panic.

  • [question]

    [question]

    Describe the problem you're having

    A clear and concise description of what the bug is.

    Versions

    Go version: go version

    package version: run git rev-parse HEAD inside the repo

    "Show me the code!"

    A minimal code snippet can be useful, otherwise we're left guessing!

    Hint: wrap it with backticks to format it

  • [question] concurrent write to websocket connection with mutex.Lock()

    [question] concurrent write to websocket connection with mutex.Lock()

    Describe the problem you're having

    Using the gorilla/websocket package I sometimes get the following error, despite using mutex.Lock: concurrent write to websocket connection

    Versions

    • Go version: 1.18
    • package version: v1.5.0

    "Show me the code!"

    type WebsocketClient struct {
    	websocket   *websocket.Conn
    	mutex            sync.Mutex
    }
    
    func (websocketClient *WebsocketClient) sendMessage(msg interface{}) error {
    	websocketClient.mutex.Lock()
    	defer websocketClient.mutex.Unlock()
    
    	return websocketClient.websocket.WriteJSON(msg)
    }
    

    In an http handler the websocket clients get created:

    ws, err := upgrader.Upgrade(w, r, nil)
    ...
    clients[id] = &WebsocketClient{
        websocket: ws,
    }
    

    The sendMessage function gets called from multiple go-routines and the WriteJSON never gets called directly anywhere else. From my understanding the mutex.Lock() should prevent concurrent websocket writes.

  • [bug] Websocket subprotocol is not chosen on client preferance

    [bug] Websocket subprotocol is not chosen on client preferance

    Describe the bug

    From the Websocket RFC6455:

    For client side:

    |Sec-WebSocket-Protocol| header field, with a list of values indicating which protocols the client would like to speak, ordered by preference.

    And for server side:

    Either a single value representing the subprotocol the server is ready to use or null. The value chosen MUST be derived from the client's handshake, specifically by selecting one of the values from the |Sec-WebSocket-Protocol| field that the server is willing to use for this connection (if any).

    So if the client provides a few options for subprotocol. The server should choose the first one it supports.

    Right now, if client provides a few options, lib choose the first one it supports (and not the first one from the client).

    e.g. So if the client sends Sec-WebSocket-Protocol: wamp.2.cbor, wamp.2,json and server supports wamp.2,json, wamp.2.cbor then wamp.2,json will be chosen but not wamp.2.cbor as it should be.

    A clear and concise description of what the bug is.

    Lib version: all :)

    Code Snippets The problem is in server.go: selectSubprotocol func:

    		clientProtocols := Subprotocols(r)
    		for _, serverProtocol := range u.Subprotocols {
    			for _, clientProtocol := range clientProtocols {
    				if clientProtocol == serverProtocol {
    					return clientProtocol
    				}
    			}
    		}
    
    

    should be changed to:

            clientProtocols := Subprotocols(r)
            for _, clientProtocol := range clientProtocols {
                for _, serverProtocol := range u.Subprotocols {
                    if clientProtocol == serverProtocol {
                        return clientProtocol
                    }
                }
            }
    
Encrypted-websocket-chat - Encrypted websocket chat using golang

Encrypted websocket chat First version written in python This version should be

Sep 15, 2022
Websocket-chat - A simple websocket chat application
Websocket-chat - A simple websocket chat application

WebSocket Chat App This is a simple chat app based on websockets. It allows user

Jan 25, 2022
A modern, fast and scalable websocket framework with elegant API written in Go
A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Dec 29, 2022
BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication.

BrisGolang BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication. Usage You can play

Nov 1, 2021
Client Implementation of eosio state-history websocket.

Client Implementation of eosio state-history websocket.

Dec 6, 2022
API that upgrades connection to use websocket. Contains server and client and testing how they communicate

Websocket Test API How to execute First run server using: make run-server. Then run many client instances with: make run-client. Then start typing in

Dec 25, 2021
Minimal and idiomatic WebSocket library for Go

websocket websocket is a minimal and idiomatic WebSocket library for Go. Install go get nhooyr.io/websocket Highlights Minimal and idiomatic API First

Dec 31, 2022
Websocket server. Get data from provider API, clean data and send to websoket, when it's changed.

Описание Сервис получает данные по киберспортивным матчам CS:GO от провайдера, структурирует, очищает от лишнего и отправляет всем активным вебсокет к

Apr 6, 2022
Go-distributed-websocket - Distributed Web Socket with Golang and Redis
Go-distributed-websocket - Distributed Web Socket with Golang and Redis

go-distributed-websocket Distributed Web Socket with Golang and Redis Dependenci

Oct 13, 2022
Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets.

websocketd websocketd is a small command-line tool that will wrap an existing command-line interface program, and allow it to be accessed via a WebSoc

Dec 31, 2022
WebSocket Command Line Client written in Go

ws-cli WebSocket Command Line Client written in Go Installation go get github.com/kseo/ws-cli Usage $ ws-cli -url ws://echo.websocket.org connected (

Nov 12, 2021
proxy your traffic through CDN using websocket

go-cdn2proxy proxy your traffic through CDN using websocket what does it do example server client thanks what does it do you can use this as a library

Dec 7, 2022
Chat bots (& more) for Zoom by figuring out their websocket protocol
Chat bots (& more) for Zoom by figuring out their websocket protocol

zoomer - Bot library for Zoom meetings Good bot support is part of what makes Discord so nice to use. Unfortunately, the official Zoom API is basicall

Dec 14, 2022
Tiny WebSocket library for Go.

RFC6455 WebSocket implementation in Go.

Dec 28, 2022
Simple example for using Turbos Streams in Go with the Gorilla WebSocket toolkit.

Go Example for TurboStreams over WebSockets Simple example for using Turbos Streams in Go with the Gorilla WebSocket toolkit.

Dec 22, 2022
:notes: Minimalist websocket framework for Go
:notes: Minimalist websocket framework for Go

melody ?? Minimalist websocket framework for Go. Melody is websocket framework based on github.com/gorilla/websocket that abstracts away the tedious p

Dec 23, 2022
Terminal on browser via websocket

Terminal on browser via websocket. Supportted OS Linux Mac

Dec 27, 2022
run shell scripts by websocket with go lauguage
run shell scripts by websocket with go lauguage

go_shell_socket run shell scripts by websocket with go lauguage Usage pull project get gin and websocket with go get config config.json file build it

Mar 9, 2022
simpleChatInGo - This is a simple chat that i made for fun asnd learn more about websocket
simpleChatInGo - This is a simple chat that i made for fun asnd learn more about websocket

simpleChatInGo This is a simple chat that i made for fun asnd learn more about websocket deploy For deploy this you only need to run the command : $ d

Sep 21, 2022