Giter Site home page Giter Site logo

gorilla / websocket Goto Github PK

View Code? Open in Web Editor NEW
21.2K 381.0 3.4K 536 KB

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

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

License: BSD 3-Clause "New" or "Revised" License

Go 99.39% Makefile 0.61%
go websocket golang gorilla gorilla-web-toolkit websockets

websocket's Introduction

gorilla/websocket

testing codecov godoc sourcegraph

Gorilla WebSocket is a Go implementation of the WebSocket protocol.

Gorilla Logo

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.

websocket's People

Contributors

apoorvajagtap avatar attilaolah avatar bluetech avatar chebyrash avatar codenoid avatar coreydaley avatar elithrar avatar fancycode avatar fzambia avatar garyburd avatar jeanbza avatar johnrichardrinehart avatar juliens avatar kisielk avatar mstmdev avatar nak3 avatar ninedraft avatar pcarranza avatar pwaller avatar reeze avatar rfyiamcool avatar rhavar avatar samb1729 avatar seikichi avatar seppo0010 avatar tapocol avatar thak1411 avatar thedevsaddam avatar unafraid avatar y3llowcake avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

websocket's Issues

Getting build error on Ubunut

I'm getting the following error trying to build on Ubuntu 13.10

github.com/gorilla/websocket

../../gorilla/websocket/client.go:167: undefined: net.Dialer

My build works fine on Windows. Is there something odd/different on Ubuntu?

NewClient Example Usage - golang based client

Hi folks!

Looking to use websocket.NewClient() to create a golang based websocket client (rather than a browser based ws client) but couldn't find any examples.

func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {

I'm mostly stuck on what to provide for net.Conn. I couldn't easily find anything in the existing code, tests or even google.

Is there an example someone could help point me at?

Thanks a bunch!

Specifying separate dial host and http "Host:" header

I'm making a proxy which can handle web sockets. Everything is fine except I can't easily specify the Host: header correctly.

The problem is, some random client connects inbound with example.com, which proxies to foo.internal. foo.internal ends up seeing Origin: example.com and Host: foo.internal. I want the internal server to see Host: example.com.

This can be achieved in two ways I can immediately think of. I could implement my own Dial method:

websocket/client.go

Lines 182 to 227 in ecff5aa

netConn, err := netDial("tcp", hostPort)
if err != nil {
return nil, nil, err
}
defer func() {
if netConn != nil {
netConn.Close()
}
}()
if err := netConn.SetDeadline(deadline); err != nil {
return nil, nil, err
}
if u.Scheme == "wss" {
cfg := d.TLSClientConfig
if cfg == nil {
cfg = &tls.Config{ServerName: hostNoPort}
} else if cfg.ServerName == "" {
shallowCopy := *cfg
cfg = &shallowCopy
cfg.ServerName = hostNoPort
}
tlsConn := tls.Client(netConn, cfg)
netConn = tlsConn
if err := tlsConn.Handshake(); err != nil {
return nil, nil, err
}
if !cfg.InsecureSkipVerify {
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
return nil, nil, err
}
}
}
if len(d.Subprotocols) > 0 {
h := http.Header{}
for k, v := range requestHeader {
h[k] = v
}
h.Set("Sec-Websocket-Protocol", strings.Join(d.Subprotocols, ", "))
requestHeader = h
}
conn, resp, err := NewClient(netConn, u, requestHeader, d.ReadBufferSize, d.WriteBufferSize)

However, I would have to copy a great deal of the code in your library, and would not get the benefit of any fixes that might arrive in the future.

An alternative would be to extend the gorilla Dial method so that if a Host header is specified via the requestHeader parameter, it modifies the host of the URL u that is passed to NewClient (after the TCP dial has already happened), and gets deleted from the set of headers (so that it doesn't end up specified twice).

Would the latter fix be accepted as a PR, or can you think of an alternative method of achieving my goal? Thanks!

Tries to do a DNS lookup for `user@host` if basic auth specified

I'm passing secret tokens via foo@host, and when I do that I get:

Fatal: dial tcp: lookup foo@host: no such host

So did gorilla just leak my secret token via DNS? :)

websocket/client.go

Lines 102 to 134 in 6fd0f86

// parseURL parses the URL. The url.Parse function is not used here because
// url.Parse mangles the path.
func parseURL(s string) (*url.URL, error) {
// From the RFC:
//
// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
//
// We don't use the net/url parser here because the dialer interface does
// not provide a way for applications to work around percent deocding in
// the net/url parser.
var u url.URL
switch {
case strings.HasPrefix(s, "ws://"):
u.Scheme = "ws"
s = s[len("ws://"):]
case strings.HasPrefix(s, "wss://"):
u.Scheme = "wss"
s = s[len("wss://"):]
default:
return nil, errMalformedURL
}
u.Host = s
u.Opaque = "/"
if i := strings.Index(s, "/"); i >= 0 {
u.Host = s[:i]
u.Opaque = s[i:]
}
return &u, nil
}

Is it reasonable to grow support for basic auth?

Performance bottleneck in function maskBytes

I have investigated the performance of the websocket communication. With the kernel "perf" utility I saw that the function maskBytes consumes a lot of CPU cycles. Therefore I have optimized this function. Now I get twice the data throughout than before (900MB/s instead of 440MB/s). At the moment it is optimized for 64-bit machines. I'm also not sure if the optimization works on big endian machines. The trick is to apply the mask on 64-bit chunks instead of bytes. Here it is:

import "unsafe"

 func maskBytes(key [4]byte, pos int, b []byte) int {
        // Construct 64 bit mask
        k32 := uint32(key[0]) | uint32(key[1]) << 8 | uint32(key[2]) << 16 | uint32(key[3]) << 24
        k64 := uint64(k32)
        k64 = k64<<32 | k64
        // Correct mask by pos offset
        k64 <<= uint(pos) << 3
        k64 |= uint64(k32 >> ((4 - uint(pos)) << 3))
        // Apply 64 bit mask to the data set
        for len(b) >= 8 {
                *(*uint64)(unsafe.Pointer(&b[0])) ^= k64
                b = b[8:]
                pos += 8
        }
        // Mask the last bytes by a slow method
        for i := range b {
                b[i] ^= key[pos&3]
                pos++
        }
        return pos & 3
}

permessage-deflate

Is there any implementation of permessage-deflate extension on gorilla/websocket?

Sec-WebSocket-Protocol mismatch on Chrome 30

Hi,
I'm getting the following error (in the chrome console) while using gorilla/websocket with the latest version of chrome:

WebSocket connection to 'ws://foo/socket' failed: Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch 

Something to do with gorilla/websocket not returning the correct sec-websocket-protocol header:
http://comments.gmane.org/gmane.comp.python.tornado/6185

Im using strophe.js to connect to gorilla/websocket (as a server) for the record.

Connection.NextReader() blocks even after the connection has been closed

I am having the following problem where I have a goroutine that only reads messages and another goroutine that is responsible for writing messages and closing connections. So something like this:

import(
websockets "github.com/gorilla/websocket"
"fmt"
)

func reader(ws websockets.Connection){
a, b, c := ws.Connection.NextReader()
fmt.Println("Done")
// Do some work down there
}

func writer(ws websockets.Connection){
// Some work done here


// Close the connection at the end
ws.Connection.Close()
}

It turns out I never see "Done" printed in my console, which would indicate that the reader is STILL available even after the connection itself has been closed. It would be very useful to handle this more gracefully. I think some sort of error should be returned in those cases.

Or is there an alternative approach for handling this use case?

Possible error in newMaskKey() implementation

In Conn's newMaskKey() function, I noticed the 4th byte uses the random int shifted over by 32, which unless I'm mistaken means that byte is always 0. Did you mean to use 24 instead of 32?

Error on WriteMessage is nil when writing to a closed channel

The server is configured to send data every one second to an opened websocket. I opened a websocket from the Chrome console and received data without a problem from the server. I then closed the websocket by calling s.close() but the server continued to send data anyway. The error value obtained from the WriteMessage() call is nil. Is this the intended behaviour? Also, is there any other method to check if the client closed the connection?

Server:

interval := time.Tick(delay)
for {
    select {
    case <-interval:
        a, err := json.Marshal(b)
        if err = ws.WriteMessage(websocket.TextMessage, a); err != nil {
            fmt.Println(err)
            return
        }
    }
}

Client:

s = new WebSocket("ws://localhost:3000/socket")
// Server starts sending
s.close()
// Server continues sending

Handling of "continuationFrame" messages unclear

The correct way to receive a message which is composed of multiple continous sub frames is not clear. Is the application responsible to call "Read" multiple times or is it handled internally. I wrote a websocket server which sends "continuationFrame" messages. The websocket protocol layer should reassemble the whole message and return it as one packet to the receiver. But I do not get this feature running correclty on the client side.

Fragmentation error on write

I'm using the method .WriteJSON to send an arbitrary amount of data through websocket, but is failing to properly write the fragmentation when the amount of data is between 4096 and 8192. I saw that you have a code like this
if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { // Don't buffer large messages.

If I change the "2*len" for just "len", it works flawlessly for all json sizes.

Upgrade method docs issues

The documentation example with the Upgrade method doesn't compile. The argument list is incorrect.
The responseHeader argument to the Upgrade method is not documented and it's not obvious to me what it does.

unexpected EOF

[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32085, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32085)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32072)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32066, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32066)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32000, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32000)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:31756, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:31756)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32049, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32049)
[11/19/14 14:16:33] [DEBG] register, true%!(EXTRA string=127.0.0.1:32100)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32009, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32009)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32023, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32023)
[11/19/14 14:16:33] [DEBG] register, true%!(EXTRA string=127.0.0.1:32095)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32100, *errors.errorString=unexpected EOF)
[11/19/14 14:16:33] [DEBG] unregister, true%!(EXTRA string=127.0.0.1:32100)
[11/19/14 14:16:33] [EROR] ReadMessage error,%!(EXTRA string=127.0.0.1:32095, *errors.errorString=unexpected EOF)

Returning a different error when client receives CloseNormalClosure

Hi,

We're trying to have our websocket server send informational error messages when it sends a Close control frame (as specified here). Gorilla even supports this in the WriteControl function.

But in the ReadMessage function, the Close frame's message body gets clobbered by an io.EOF error (I guess, strictly speaking, this happens in advanceFrame but the public method that gets the bad behavior is ReadMessage). You can see this code here: https://github.com/gorilla/websocket/blob/master/conn.go#L676-L680

We'd like our websocket client to be able to display the Close frame's message body at least for the type CloseNormalClosure, but we're not sure all the implications of changing this behavior. Maybe the following implementation would work:

        switch closeCode {
        case CloseNormalClosure:
            return noFrame, &closeError{code: closeCode, text: closeText}
                case CloseGoingAway:
                        return noFrame, io.EOF
        default:
            return noFrame, &closeError{code: closeCode, text: closeText}
        }

We're happy to submit a PR if we get a go-ahead from someone, but we figured we'd start with a discussion.

Thanks,
David && Warren

how to detect closed connection when using ReadJSON

ReadJSON returns a EOF error if either JSON is incorrect or the peer closed connection unexpectedly.

if I get an error from this function, how do I know that it is JSON that is incorrect and not that the connection is closed?

Signal receive loop to stop and close the conn

My code looks somewhat like the following:

    // Start reading the messages and pumping them to the channel
    go func(ws *websocket.Conn, in chan Message) {
        defer func() {
            ws.Close()
        }()
        for {
            msg := Message{}
            err := ws.ReadJSON(&msg)
            if err != nil {
                msg.Type = "error"
                msg.Error.Code, msg.Error.Msg = 0, err.Error()
            }
            in <- msg
            if err != nil {
                close(in)
                break
            }
        }
    }(s.ws, in)

What I would like to do is also pass in a stop channel and do a select on both read and stop. If I receive a stop, I just break from the loop. Looking quickly at the code, I could not find an easy way to do so.
Any tips?

Thanks

Set timeout instead of deadline

Set a constant timeout for read and write respectively, for the life time of a connection. The advantage is it needs to be set once only. Currently the deadline needs to be set before each read or write. E.g.,

func (c *Conn) SetWriteTimeout(timeout time.Duration)

The standard package net has

func DialTimeout(network, address string, timeout time.Duration) (Conn, error)

stream version + performance

Hey guys! I'm investigating switching from the go.net websockets package to gorilla websockets because I don't trust the way it frames. As I understand the go.net source, if I try to receive a JSON message (either with the io.Reader or ws.JSON.Receive methods), it will just try to read one frame. This would be problematic if either the JSON message is large or it was split up by a router in between.

The README.md for gorilla/websocket indicates that gorilla does not do this, which is nice and I can be more secure in knowing that no matter what kinds of frame splits happen, everything will work.

Now I've got 2 questions:

  1. Have you guys done any kind of performance benchmarking? How does it compare to the go.net package? For binary, text and when encoded using JSON?
  2. As for JSON, the most efficient way to use go's JSON capabilties is with the Decoder/Encoder pair. However, it seems that the gorilla/websocket API mandates the creation of a new encoder for every message. This seems wasteful and I don't see how it could do better (indeed, even worse) than using Marshal/Unmarshal. Yet since my server will be serving hundreds of clients at the same time, I'd like to minimize the "churn". And just basically follow good design principles. I guess my question is: why can't we use websockets as a sort of stream? Is there something that prohibits it? Note that the go.net package does provider a regular io.Reader and io.Writer, but I didn't feel safe with their framing.

So, these doubts is why I currently can't decide between gorilla and go.net.

Upgrade returns concrete type *websocket.Conn instead of an interface

I'd like to mock out a connection within our websocket server for unit testing. I'm finding it difficult in the current implementation because the server explicitly returns a *Conn type during Upgrade. Any interest in a PR to switch out these return values of *Conn with a connection interface? Or any suggestions for workarounds?

Testing the examples

I've just started playing around with gorilla/websocket and more specifically started off with the chat example as the channels seemed like the best choice for ws.
Everything is working just fine, but I can't figure out how to go about testing this.

I'm fairly new to golang and testing something like this just feels weird.
Would it be possible to get a sample test suite for the chat example, or maybe some pointers at to where I should start from?

Thank you very much in advance! :)

Add Dialer type for creating client connections

Add Dialer type for creating client connections:

type Dialer struct {
    // Dial specifies the dial function for creating TCP
    // connections. If Dial is nil, net.Dial is used.
    Dial func(network, addr string) (net.Conn, error)

    // TLSClientConfig specifies the TLS configuration to use with
    // tls.Client. If nil, the default configuration is used.
    TLSClientConfig *tls.Config

    // HandshakeTimeout specifies the duration for the handshake
    // to complete.
    HandshakeTimeout time.Duration

    // Input and output buffer sizes. If the buffer size is zero, then a default value
    // of 4096 is used.
    ReadBufferSize, WriteBufferSize int
]

func (d *Dialer) Dial(u *url.URL, requestHeader http.Header) (c *Conn, response *http.Response, err error)

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
    }
    

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!

Expand the chat example slightly to represent real world chatrooms

The chat example has been a big help in getting running. However, it assumes only a single room which isn't realistic in most chat apps.

I do understand that a working app isn't as much the goal as a good demo of the communication, but I was wondering if we could add a multiroom demo because the read/write pumps don't seem to work on a large scale.

I have modified the server slightly by changing the system to create an map of "hubs" so that you can have multiple "chat rooms".

sss

first I created a HubMap.go

// The HubMap maintains a list of all Hubs/Rooms in the chat
type HubMap struct {
    sync.RWMutex
    hubs    map[int]*Hub
}

// Get by key
func (hm *HubMap) Get(key int) *Hub {
    hm.RLock()
    defer hm.RUnlock()

    // Does this hub exist yet
    hub, ok := hm.hubs[key]

    if !ok {
        // Create a new hub
        hub = newHub(key)
        hm.hubs[key] = hub
    }

    return hub
}

then changed hub.go

func newHub(id int) (hub *Hub) {
    hub = &Hub{
        id: id,
        broadcast:   make(chan []byte),
        register:    make(chan *connection),
        unregister:  make(chan *connection),
        connections: make(map[*connection]bool),
    }

    // Start listening for events!
    go hub.run()

    return hub
}

then change

func serveWs(w http.ResponseWriter, r *http.Request) {

....

// get hub
hub := hubs.Get(meetingIdFromURLParam)

c := &connection{
    send: make(chan []byte, 256),
    ws: ws,
    hub: hub,
}

which also means the connection struct looks like this now:

// connection is an middleman between the websocket connection and the hub.
type connection struct {
    // The websocket connection.
    ws *websocket.Conn

    // Pointer to the Hub object for this connection
    hub *Hub

    // The remote address without the port
    remoteAddr string

    // Buffered channel of outbound messages.
    send chan []byte
}

websocket.HandshakeError=websocket: upgrade != websocket

36.68.88.123 - - - 127.0.0.1:7766 - [28/Apr/2015:06:13:44 +0000] "GET /ws?img_id=149046&uid=11485&sid=30206f5d-f94e-4ef1-7d63-2c6f23ee458b HTTP/1.1" 400 12 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" www.xxx.com [0.000] - [0.000]

upgrader.Upgrade%!(websocket.HandshakeError=websocket: upgrade != websocket)

losts of 400 requests in Nginx error.log

Example chat code not working

Not sure if I am doing something wrong, but the example code seems to be broken. Multiple issues:

In the HTML file:

  1. The jquery lib url is no longer valid.

  2. At the point of websocket creation, I get the following error
    WebSocket connection to 'ws://%7B%7B%24%7D%7D/ws' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED

  3. When I fix the address as ws://localhost:8080/ws, I get:
    WebSocket connection to 'ws://localhost:8080/ws' failed: Error during WebSocket handshake: Unexpected response code: 403
    Server side I get websocket: origin not allowed, which seems to be coming coz the protocol is not set to http.

  4. If I set the protocol to http, I get
    Uncaught SyntaxError: Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.

Would appreciate any help on this. I am also trying to use gorilla on server side and have a mobile app communicate with the server. Is there a way to connect to the server without upgrading an http connection? Can I directly connect through ws://? I can't seem to find any help online on this.

Add Upgrader

A sketch of the API is:

type Upgrader struct {
    // HandshakeTimeout specifies the duration for the handshake to complete.
    HandshakeTimeout time.Duration

    // Input and output buffer sizes. If the buffer size is zero, then a
    // default value of 4096 is used.
    ReadBufferSize, WriteBufferSize int

    // Subprotocols specifies the server's supported protocols. If Subprotocols
    // is nil, then Upgrade does not negotiate a subprotocol.
    Subprotocols []string

    // Error specifies the function for generating HTTP error responses. If Error
    // is nill, then http.Error is used to generate the HTTP response.
    Error func(w http.ResponseWriter, r *http.Request, status int, reason error)

    // CheckOrigin returns true if the request Origin header is acceptable.
    // If CheckOrigin is nil, then no origin check is done.
    CheckOrigin func(r *http.Request) bool
}

func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { ... }

Lots of static buffer allocation

Do I understand correctly that for every established connection there is a read buffer and write buffer persistently allocated for the size specified in the Upgrade call? If using large numbers of mostly idle connections and large max message size this can amount to a lot. Wouldn't it be nice for the buffering to happen using dynamic allocation of fragment-sized buffers with a final copy to merge the fragments when the end of the message has been received?

can't connect to ws server from different host.

hello , i started chat example application and then try to connect to it throught different application , different port i mean. so it is not working and giving response with 403 error and unexpected error during handshake , please give me appropriate solution as ap. thanks.

Does Conn.NextReader handle Fragmentation

If I send a large message, and it is fragmented, can I receive the same size from NextReader?
I have a message in an encrypted format, if I can't receive the complete message, the decryption will fail.

timeout errors are unrecoverable

Once websocket.nextReader returns a timeout error it will always do so. That makes it impossible to poll a websocket and periodically check whether the socket should be closing or something like that. Basically what I wanted to do is to have the sender set a flag when it sends a close message and have the reader continue reading until a one minute timeout is reached. What I tried is below, but perhaps there's a much more elegant way to do this?

closing := false
for {
  // check whether the writer has closed
  if !closing {
    select {
    case code := <-ch:
        closing = true
    default:
    }
  }
  // set a deadline on the NextReader so we periodically go around the loop
  // and check the closing channel (see code above)
  ws.SetReadDeadline(time.Now().Add(time.Minute))
  // read a message from the websocket
  t, r, err := ws.NextReader()
  if err != nil {
    // if we get a timeout and we're told to close then it's time to give up
    netErr, ok := err.(net.Error)
    if ok && netErr.Timeout() && !closing {
      continue // just a timeout, that's OK
    }
    break
  }
  // continue reading message
}

Verifying open connections

How does one verify whether websocket connection is open ? Is there any way to check the connectivity ?

using the 5000 coroutine , from the beginning to receive a response from the server side, the average interval was 200 ms,

( https://github.com/yxw2014/screenshot_annotation) This is my first project on the production
environment, it is a websocket-based user comments system , it works fine, but I use a client
program(Client and server-side run on the same machine) to test the 5000 connection, and send
message to the server using the 5000 coroutine at the same time , from the beginning to receive a
response from the server side, the average interval was 200 ms, and I think some parts of the program
(especially the use of channel may have a place blocking) may need to beoptimized to improve,
someone can help me to do code review about it?

Binding events

Hello is it possible to bind events like onlogin onplay?

Concurrent WebSocket connections

Wondering whether Gorilla WebSocket can have more than 600,000 concurrent connections on an M3.xlarge EC2 instance as compared to the implementation in http://www.jayway.com/2015/04/13/600k-concurrent-websocket-connections-on-aws-using-node-js.

Is a pool of WebSocket connections advisable as suggested in the answer of http://stackoverflow.com/questions/31134420/design-architecture-web-socket-one-connection-vs-multiple-connections, or multiple WebSocket connections advisable as suggested in the answer of http://stackoverflow.com/questions/4852702/do-html-websockets-maintain-an-open-connection-for-each-client-does-this-scale?

Warmest Regards,
Joel

use of closed network connection

*errors.errorString=use of closed network connection)

    _, message, err := c.ws.ReadMessage()
    if err != nil {
        log4e("ReadMessage error,", err)
        break
    }

why? no error on client side!

temporary net.Error treated as permanent

temporary read errors like timeouts will be set to Conn.readErr and returned forever.
this makes it impossible to continue reading from a conn with a new deadline after a previous one triggered.

Creating chat 'rooms'

Hi, I was wondering how I'd go about making 'rooms' of connections using gorilla websocket.
I've set up a simple chat server that broadcasts out to all, but was wondering how I'd go implementing rooms.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.