README

Websocket
=========

Websocket is a http handler for Go, which initiates websocket_
connections.

.. _websocket: https://en.wikipedia.org/wiki/WebSocket

Copyright (C) 2019  Jochen Voss

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Installation
------------

This package can be installed using the ``go get`` command::

  go get seehuhn.de/go/websocket

Usage
-----

Documentation is available via the package's online help, either on
godoc.org_ or on the command line::

  go doc -all seehuhn.de/go/websocket

For demonstation, here is a simple echo server.  To install the handler
at a given URL, use a ``websocket.Handler`` object::

  func main() {
	  websocketHandler := &websocket.Handler{
		  Handle: echo,
	  }
	  http.Handle("/", websocketHandler)
	  log.Fatal(http.ListenAndServe(":8080", nil))
  }

The function ``echo()`` will be called every time a client makes a
connection::

  func echo(conn *websocket.Conn) {
	  defer conn.Close(websocket.StatusOK, "")

	  for {
		  tp, r, err := conn.ReceiveMessage()
		  if err != nil {
			  break
		  }

		  w, err := conn.SendMessage(tp)
		  if err != nil {
			  // We still need to read the complete message, so that the
			  // next read doesn't block.
			  io.Copy(ioutil.Discard, r)
			  break
		  }

		  _, err = io.Copy(w, r)
		  if err != nil {
			  io.Copy(ioutil.Discard, r)
		  }

		  w.Close()
	  }
  }

.. _godoc.org: https://godoc.org/seehuhn.de/go/websocket
Expand ▾ Collapse ▴

Documentation

Overview

    Package websocket implements an HTTP server to accept websocket connections.

    To accept websocket connections from clients, use a websocket.Handler object:

    websocketHandler := &websocket.Handler{
    	Handle: myHandler,
    }
    http.Handle("/api/ws", websocketHandler)
    

    The function myHandler is called every time a client requests a new websocket. The websocket.Conn object passed to handler can be used to send and receive messages. The handler must close the connection when finished with it:

    func myHandler(conn *websocket.Conn) {
    	defer conn.Close(websocket.StatusOK, "")
    
    	// use conn to send and receive messages.
    }
    

    Index

    Constants

    View Source
    const (
    	// ErrConnClosed indicates that the websocket connection has been
    	// closed (either by the server or the client).
    	ErrConnClosed = webSocketError("connection closed")
    
    	// ErrMessageType indicates that an invalid message type has been
    	// encountered.  Valid message types are Text and Binary.
    	ErrMessageType = webSocketError("wrong message type")
    
    	// ErrStatusCode indicates that an invalid status code has been
    	// supplied.  Valid status codes are in the range from 1000 to
    	// 4999.
    	ErrStatusCode = webSocketError("invalid status code")
    
    	// ErrTooLarge is used by ReceiveBinary and ReceiveText to
    	// indicate that the client send a too large message.
    	ErrTooLarge = webSocketError("message too large")
    )

    Variables

    This section is empty.

    Functions

    This section is empty.

    Types

    type Conn

    type Conn struct {
    	ResourceName *url.URL
    	Origin       *url.URL
    	RemoteAddr   string
    	Protocol     string
    	// contains filtered or unexported fields
    }

      Conn represents a websocket connection initiated by a client. All fields are read-only. It is ok to access a Conn from different goroutines concurrently. The connection must be closed using the Close() method after use, to free all allocated resources.

      Use a Handler to obtain Conn objects.

      func (*Conn) Close

      func (conn *Conn) Close(code Status, message string) error

        Close terminates a websocket connection and frees all associated resources. The connection cannot be used any more after Close() has been called.

        The status code indicates whether the connection completed successfully, or due to an error. Use StatusOK for normal termination, and one of the other status codes in case of errors. Use StatusNotSent to not send a status code.

        The message can be used to provide additional information for debugging. The utf-8 representation of the string can be at most 123 bytes long, otherwise ErrTooLarge is returned.

        func (*Conn) GetStatus

        func (conn *Conn) GetStatus() (Status, string)

          GetStatus returns the status and message the client sent when closing the connection. This function blocks until the connection is closed. The returned status has the following meaning:

          - StatusDropped indicates that the client dropped the connection
            without sending a close frame.
          - StatusNotSent indicates that the client sent a close frame,
            but did not include a valid status code.
          - Any other value is the status code sent by the client.
          

          func (*Conn) ReceiveBinary

          func (conn *Conn) ReceiveBinary(buf []byte) (n int, err error)

            ReceiveBinary reads a binary message from the connection. If the next received message is not binary, ErrMessageType is returned and the received message is discarded. If the received message is longer than buf, buf contains the start of the message and ErrTooLarge is returned.

            func (*Conn) ReceiveMessage

            func (conn *Conn) ReceiveMessage() (MessageType, io.Reader, error)

              ReceiveMessage returns an io.Reader which can be used to read the next message from the connection. The first return value gives the message type received (Text or Binary).

              No more messages can be received until the returned io.Reader has been read till the end. In order to avoid deadlocks, the reader must always be completely drained.

              func (*Conn) ReceiveText

              func (conn *Conn) ReceiveText(maxLength int) (string, error)

                ReceiveText reads a text message from the connection. If the next received message is not a text message, ErrMessageType is returned and the received message is discarded. If the length of the utf-8 representation of the text exceeds maxLength, the text is truncated and ErrTooLarge is returned.

                func (*Conn) SendBinary

                func (conn *Conn) SendBinary(msg []byte) error

                  SendBinary sends a binary message to the client.

                  func (*Conn) SendMessage

                  func (conn *Conn) SendMessage(tp MessageType) (io.WriteCloser, error)

                    SendMessage starts a new message and returns an io.WriteCloser which can be used to send the message body. The argument tp gives the message type (Text or Binary). Text messages must be sent in utf-8 encoded form.

                    func (*Conn) SendText

                    func (conn *Conn) SendText(msg string) error

                      SendText sends a text message to the client.

                      type Handler

                      type Handler struct {
                      	// AccessOK, if non-nil, is called during the opening handshake to
                      	// decide whether the client is allowed to access the service.  At
                      	// the time this function is called, the connection is not yet
                      	// functional, but the fields ResourceName (describing the URL the
                      	// client used to access the server) and Origin (as reported by
                      	// the web browser) are already initialised.
                      	//
                      	// If the client sends a list of supported sub-protocols, these
                      	// will be available in protocols.  In this case, AccessOk must
                      	// assign one of the supported sub-protocols to the Protocol field
                      	// of conn.  Otherwise the connection setup will fail.
                      	// See: https://tools.ietf.org/html/rfc6455#section-1.9
                      	//
                      	// The function must return true, if the client is allowed to
                      	// access the service, and false otherwise.
                      	AccessOk func(conn *Conn, protocols []string) bool
                      
                      	// Handle is called after the websocket handshake has completed
                      	// successfully, and the object conn can be used to send and
                      	// receive messages on the connection.
                      	//
                      	// The connection object conn can be passed to other parts of the
                      	// programm, and will stay functional even after the call to
                      	// Handle is complete.  Use conn.Close() to close the connection
                      	// after use.
                      	Handle func(conn *Conn)
                      
                      	// If non-empty, this string is sent in the "Server" HTTP header
                      	// during handshake.
                      	ServerName string
                      }

                        Handler implements the http.Handler interface. The handler responds to requests by opening a websocket connection.

                        func (*Handler) ServeHTTP

                        func (handler *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request)

                        type MessageType

                        type MessageType byte

                          MessageType encodes the type of a websocket message.

                          const (
                          	Text   MessageType = 1
                          	Binary MessageType = 2
                          )

                            Websocket message types as define in RFC 6455. See: https://tools.ietf.org/html/rfc6455#section-5.6

                            func (MessageType) String

                            func (tp MessageType) String() string

                            type Status

                            type Status uint16

                              Status describes the reason for the closure of a websocket connection.

                              const (
                              	StatusOK                  Status = 1000
                              	StatusGoingAway           Status = 1001
                              	StatusProtocolError       Status = 1002
                              	StatusUnsupportedType     Status = 1003
                              	StatusNotSent             Status = 1005
                              	StatusDropped             Status = 1006
                              	StatusInvalidData         Status = 1007
                              	StatusPolicyViolation     Status = 1008
                              	StatusTooLarge            Status = 1009
                              	StatusInternalServerError Status = 1011
                              )

                                Websocket status codes as defined in RFC 6455, for use in the Conn.Close() method. See: https://tools.ietf.org/html/rfc6455#section-7.4.1

                                Directories

                                Path Synopsis
                                examples