# Websocket

[WebSocket](https://wikipedia.org/wiki/WebSocket) is a protocol that enables two-way persistent communication channels over TCP connections. It is used for applications such as chat, stock tickers, games, anywhere you want real-time functionality in a web application.

[View or download sample code](https://github.com/kataras/iris/tree/master/_examples/websocket).

## When to use it

Use WebSockets when you need to work directly with a socket connection. For example, you might need the best possible performance for a real-time game.

## How to use it

* import the `"github.com/kataras/iris/websocket"`
* Configure the websocket package.
* Accept WebSocket requests.
* Send and receive messages.

### Import the websocket package

```go
import "github.com/kataras/iris/websocket"
```

### Configure the websocket package

```go
import "github.com/kataras/iris/websocket"

func main() {
    ws := websocket.New(websocket.Config{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    })
}
```

#### Complete configuration

```go
// Config the websocket server configuration
// all of these are optional.
type Config struct {
    // IDGenerator used to create (and later on, set)
    // an ID for each incoming websocket connections (clients).
    // The request is an argument which you can use to generate the ID (from headers for example).
    // If empty then the ID is generated by DefaultIDGenerator: randomString(64)
    IDGenerator func(ctx context.Context) string
    // Error is the function that will be fired if any client couldn't upgrade the HTTP connection
    // to a websocket connection, a handshake error.
    Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
    // CheckOrigin a function that is called right before the handshake,
    // if returns false then that client is not allowed to connect with the websocket server.
    CheckOrigin func(r *http.Request) bool
    // HandshakeTimeout specifies the duration for the handshake to complete.
    HandshakeTimeout time.Duration
    // WriteTimeout time allowed to write a message to the connection.
    // 0 means no timeout.
    // Default value is 0
    WriteTimeout time.Duration
    // ReadTimeout time allowed to read a message from the connection.
    // 0 means no timeout.
    // Default value is 0
    ReadTimeout time.Duration
    // PongTimeout allowed to read the next pong message from the connection.
    // Default value is 60 * time.Second
    PongTimeout time.Duration
    // PingPeriod send ping messages to the connection with this period. Must be less than PongTimeout.
    // Default value is 60 *time.Second
    PingPeriod time.Duration
    // MaxMessageSize max message size allowed from connection.
    // Default value is 1024
    MaxMessageSize int64
    // BinaryMessages set it to true in order to denotes binary data messages instead of utf-8 text
    // compatible if you wanna use the Connection's EmitMessage to send a custom binary data to the client, like a native server-client communication.
    // defaults to false
    BinaryMessages bool
    // ReadBufferSize is the buffer size for the underline reader
    // Default value is 4096
    ReadBufferSize int
    // WriteBufferSize is the buffer size for the underline writer
    // Default value is 4096
    WriteBufferSize int
    // EnableCompression specify if the server should attempt to negotiate per
    // message compression (RFC 7692). Setting this value to true does not
    // guarantee that compression will be supported. Currently only "no context
    // takeover" modes are supported.
    EnableCompression bool

    // Subprotocols specifies the server's supported protocols in order of
    // preference. If this field is set, then the Upgrade method negotiates a
    // subprotocol by selecting the first match in this list with a protocol
    // requested by the client.
    Subprotocols []string
}
```

### Accept WebSocket requests & send & receive messages

```go
import (
    "github.com/kataras/iris"
    "github.com/kataras/iris/websocket"
)

func main() {
    ws := websocket.New(websocket.Config{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    })

    ws.OnConnection(handleConnection)

    app := iris.New()
    // register the server on an endpoint.
    // see the inline javascript code in the websockets.html, this endpoint is used to connect to the server.
    app.Get("/echo", ws.Handler())

    // serve the javascript built'n client-side library,
    // see weboskcets.html script tags, this path is used.
    app.Any("/iris-ws.js", func(ctx iris.Context) {
        ctx.Write(websocket.ClientSource)
    })
}

func handleConnection(c websocket.Connection) {
    // Read events from browser
    c.On("chat", func(msg string) {
        // Print the message to the console, c.Context() is the iris's http context.
        fmt.Printf("%s sent: %s\n", c.Context().RemoteAddr(), msg)
        // Write message back to the client message owner:
        // c.Emit("chat", msg)
        c.To(websocket.Broadcast).Emit("chat", msg)
    })
}
```