websocket

package module
v1.4.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 30, 2023 License: MIT Imports: 13 Imported by: 0

README

Go WebSocket

donation link

An easy way to get started with websockets in golang.

This module tracks user sessions, can recover temporarily lost connections, and compresses data through gzip if supported by the client.

Installation

Go (server)
go get github.com/AspieSoft/go-websocket
JavaScript (client)
<script src="https://cdn.jsdelivr.net/gh/AspieSoft/go-websocket@1.4.8/client.min.js" defer></script>

Usage

Go (server)

import (
  "net/http"

  "github.com/AspieSoft/go-websocket"
)

func main(){
  // setup a new websocket server
  server := websocket.NewServer("https://www.example.com")
  http.Handle("/ws", server.Handler())

  // optional: set a timeout for when disconnected clients can no longer reconnect with the same data
  server := websocket.NewServer("https://www.example.com", 30 * time.Second)

  // by default, data is compressed with gzip before being send between the server and client
  // this behavior can opptonally be disabled
  server.Gzip = false

  // by default, the server only reads requests up to 1 megabyte
  // this value can opptionally be changed
  server.ReqSize = 1024 // KB


  static := http.FileServer(http.Dir("./public/"))
  http.Handle("/", static)

  server.Connect(func(client *websocket.Client){
    // client connected

    // localstorage that stays with the client, and verifies their session
    // map[string]interface{}
    client.Store["key"] = "value"

    server.Broadcast("notify", "a new user connected to the server")
    server.Broadcast("user", client.ClientID)

    client.On("message", func(msg interface{}) {
      // client sent a message

      // optional: enforce a specific message type
      str := websocket.ToType[string](msg)
      b := websocket.ToType[[]byte](msg)
      i := websocket.ToType[int](msg)
      bool := websocket.ToType[bool](msg)
      json := websocket.ToType[map[string]interface{}](msg)
      array := websocket.ToType[[]interface{}](msg)
    })

    // send data to client
    client.Send("message", "my message to the client")

    client.Send("json", map[string]interface{}{
      "jsondata": "my json data",
      "key": "value",
      "a": 1,
    })

    client.on("send-to-friend", func(msg interface{}){
      json := websocket.ToType[map[string]interface{}](msg)

      // send a message to a different client
      server.send(json["friendsClientID"], json["msg"])

      // do other stuff...
      client.send("send-from-friend", map[string]interface{
        "ClientID": client.ClientID,
        "msg": "General Kenobi!",
      })
    })

    client.Disconnect(func(code int) {
      // when client disconnects
      server.Broadcast("disconnected", client.ClientID)
    })
  })

  server.On("kick", func(client *websocket.Client, msg interface{}) {
    friendsClientID := websocket.ToType[string](msg)

    // force a client to leave the server
    server.Kick(friendsClientID, 1000)

    server.Broadcast("kicked", friendsClientID+" was kicked by "+client.ClientID)
  })

  server.On("kick-all", func(client *Client, msg interface{}) {
    // kick every client from the server
    server.KickAll()
  })

  log.Fatal(http.ListenAndServe(":3000", nil))
}

JavaScript (client)

const socket = new ServerIO(); // will default to current origin
// or
const socket = new ServerIO('https://www.example.com'); // optional: specify a different origin

socket.connect(function(initial){
  // connected to server

  socket.send('message', "my message to the server");

  if(initial){
    // very first time connecting to the server
  }else{
    // reconnecting after a previous disconnect
  }
});

socket.on('message', function(msg){
  console.log('I got a new message:', msg);

  socket.send('json', {
    jsondata: 'my json data',
    key: 'value',
    a: 1,
  });
});

socket.on('json', function(msg){
  console.log('pre-parsed json:', msg.jsondata);
});

socket.on('notify', function(msg){
  console.log(msg);
});

let myNewFriend = null;
socket.on('user', function(msg){
  myNewFriend = msg;

  socket.send('send-to-friend', {
    friendsClientID: myNewFriend,
    msg: 'Hello, There!',
  })
});

socket.on('send-from-friend', function(msg){
  socket.send('kick', myNewFriend);
});

socket.on('kicked', function(msg){
  socket.send('kick-all');

  // run disconnect
  socket.disconnect();

  // run reconnect
  socket.connect();
});

socket.disconnect(function(status){
  // on disconnect
  if(status === 1000){
    console.log('disconnected successfully');
  }else if(status === 1006){
    console.warn('error: disconnected by accident, auto reconnecting...');
  }else{
    console.error('error:', status);
  }
});


socket.on('notifications', function(){
  console.log('my notification');
})

// stop listining to a message, and remove all client listeners of that type
socket.off('notifications');

// stop the server from sending messages, but keep the listener on the client
socket.off('notifications', false);

// request the server to send messages again
socket.on('notifications');


socket.error(function(type){
  // handle errors
  // Note: disconnection errors will Not trigger this method

  if(type === 'migrate'){
    // the client reconnected to the server, but the server failed to migrate the clients old data to the new connection
    // client listeners should still automatically be restored
  }
});

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrLog []error = []error{}

ErrLog contains a list of client errors which you can handle any way you would like

View Source
var GzipEnabled = true

GzipEnabled defines whether or not gzip compression is enabled be default for new websocket servers

Deprecated: please use `Server.Gzip` instead

Functions

func LogErrors

func LogErrors()

LogErrors can be used if you would like client errors to be logged with fmt.Println

By default, these errors will not be logged

func MsgType deprecated

func MsgType[T goutil.SupportedType](msg interface{}) interface{}

MsgType attempts to converts any interface{} from the many possible json outputs, to a specific type of your choice

if it fails to convert, it will return a nil/zero value for the appropriate type

recommended: add .(string|[]byte|int|etc) to the end of the function to get that type output in place of interface{}

Deprecated: Please use 'websocket.ToType' instead

func ToType added in v1.3.0

func ToType[T goutil.SupportedType](msg interface{}) T

ToType attempts to converts any interface{} from the many possible json outputs, to a specific type of your choice

if it fails to convert, it will return a nil/zero value for the appropriate type

Unlike 'websocket.MsgType' This method now returns the actual type, in place of returning an interface{} with that type

Types

type Client

type Client struct {
	ClientID string

	Store map[string]interface{}
	// contains filtered or unexported fields
}

Client of a websocket

func (*Client) Disconnect

func (c *Client) Disconnect(cb func(code int))

Disconnect runs your callback when the client disconnects from the websocket

func (*Client) Kick

func (c *Client) Kick(code int)

ExitAll will force the client to disconnect from the websocket

func (*Client) On

func (c *Client) On(name string, cb func(msg interface{}))

On runs your callback when the client sends a message of the same name

func (*Client) Send

func (c *Client) Send(name string, msg interface{})

Send sends a message to the client

type Server

type Server struct {

	// ReqSize defines number of kilobytes (KB) that can be sent by a client at a time
	//
	// default: 1024 (1MB)
	ReqSize uint32

	// Gzip defines whether or not gzip compression is enabled for the websocket server
	Gzip bool
	// contains filtered or unexported fields
}

Server for a websocket

func NewServer

func NewServer(origin string, reconnectTimeout ...time.Duration) *Server

NewServer creates a new server

@origin enforces a specific http/https host to be accepted, and rejects connections from other hosts

func (*Server) Broadcast

func (s *Server) Broadcast(name string, msg interface{})

Broadcast sends a message to every client

func (*Server) Connect

func (s *Server) Connect(cb func(client *Client))

Connect runs your callback when a new client connects to the websocket

func (*Server) Disconnect

func (s *Server) Disconnect(cb func(client *Client, code int))

Disconnect runs your callback when any client disconnects from the websocket

func (*Server) Handler

func (s *Server) Handler() websocket.Handler

Handler should be passed into your http handler

http.Handle("/ws", server.Handler())

func (*Server) Kick

func (s *Server) Kick(clientID string, code int)

Exit will force a specific client to disconnect from the websocket

func (*Server) KickAll

func (s *Server) KickAll(code int)

ExitAll will force every client to disconnect from the websocket

func (*Server) On

func (s *Server) On(name string, cb func(client *Client, msg interface{}))

On runs your callback when any client a message of the same name

func (*Server) Send

func (s *Server) Send(clientID string, name string, msg interface{})

Send sends a message to a specific client

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL