socket

package module
v0.0.0-...-9bd1c32 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2020 License: MIT Imports: 11 Imported by: 0

README

Stalync Socket

High-performance Standalone WebSocket, built for powering Stalync WS cluster based on ws

This project not done yet, and we still working to improving this. If you have any thought how to improve this, feel free to create pull request.

Features

  • Simple API (but still low level)
  • Send message to other client (Sync)
  • Close connection
  • Graceful shutdown
  • Data encrypt
  • Data response information (Ack, etc)
  • Send with worker pool (Async)
  • Non-blocking IO (Adapter for various TCP Framework)
  • Rate limiting
  • Container instant WebSocket
  • Resource pooling
  • Clustering/Scaling
  • Authentication
    • JWT Token
    • Host Whitelist
    • Cookie parser
  • Alerting
    • Logger

Usage

The example below still terrible but you can customize by yourself

package main

import (
	"fmt"
	"testing"

	"github.com/Stalync/socket"
)

func main() {
	server := socket.CreateWebSocket()

	server.Callback(func(c *socket.Context) (err error) {

		// since TypeDisconnect can only detect disconnect event
		// just when the user intentionally want to do it
		// not because external problem like application crash
		// network connection not stable or even forcely disconnected
		// this function will detect if the connection still present
		// i recommended use this function and typePingTimeout but with delay
		// than only typedisconnected
		socket.HandlePingPong(server, c, time.Second, time.Second*3, nil)

		switch c.Event().Type() {

		case socket.TypeConnected:
			fmt.Println(fmt.Sprintf("Master %v is connected", c.Sender().ID()))
			err = c.Sender().SendText("Hellow Master")
			break

		case socket.TypeText:

			message := c.Message().String()
			if message == "exit" {
				return server.CloseNormalClosure(c.Sender(), "Byeeee Master")
			}

			if message == "broadcast" {

				server.IterateEachActor(func(actor *socket.Actor) {

					if actor.ID() == c.Sender().ID() {
						return
					}

					err := actor.SendText(fmt.Sprintf("Hellow from %v", c.Sender().ID()))

					if err != nil {
						fmt.Println(fmt.Sprintf("Send from %v to %v failed with message: %v",
							c.Sender().ID(),
							actor.ID(),
							err,
						))
					}

				})
				return
			}
			err = c.Sender().SendText(message)
			break

		case socket.TypeDisconnected:
			fmt.Println(fmt.Sprintf("Master %v is disconnected", c.Sender().ID()))
			break
		case socket.TypePingTimeout:
			fmt.Println(fmt.Sprintf("Master %v is timeout", c.Sender().ID()))
			break
		}

		return
	})

	fmt.Println(server.Listen(8080))
}

using wscat to test connection

wscat -c ws://localhost:8000

Need to know

List of known access event type
  • TypeContinuation
  • TypeConnected
  • TypeDisconnected
  • TypePing
  • TypePong
List of known data type
  • TypeText
  • TypeBinary

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	PING  = []byte("PING")
	PONG  = []byte("PONG")
	CLOSE = []byte("CLOSE")
)

this variable used to check actor connection wheter still connected or not

View Source
var DefaultConfig = Config{
	Timeout: time.Second * 4,

	UIDLength:    16,
	WorkerPool:   100,
	BufferedTask: 1024,
	// contains filtered or unexported fields
}

DefaultConfig setting up for default connection config

Functions

func HandlePingPong

func HandlePingPong(s *Socket, c *Context, interval, timeout time.Duration, message []byte)

HandlePingPong utility function to handle pingpong when timeout or error

Types

type Actor

type Actor struct {
	// contains filtered or unexported fields
}

Actor struct containing information of actor Actor can be said as an connected client

func (*Actor) ID

func (actor *Actor) ID() string

ID return id information

func (*Actor) PING

func (actor *Actor) PING(message []byte) error

PING function to send Ping message

func (*Actor) PONG

func (actor *Actor) PONG()

PONG function to signaling channel to ping back to the client

func (*Actor) SendBytes

func (actor *Actor) SendBytes(data []byte) error

SendBytes write byte of data to this actor

func (*Actor) SendText

func (actor *Actor) SendText(message string) error

SendText write message to this actor

type ActorMap

type ActorMap struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ActorMap this map only storing actor and actor id but with more safety

func CreateActorMap

func CreateActorMap() *ActorMap

CreateActorMap ActorMap Constructor

func (*ActorMap) Delete

func (m *ActorMap) Delete(id string)

Delete actor from map

func (*ActorMap) Insert

func (m *ActorMap) Insert(id string, a *Actor)

Insert actor to map

func (*ActorMap) Read

func (m *ActorMap) Read(id string) (*Actor, bool)

Read function that read actor from map

type Config

type Config struct {
	Timeout time.Duration

	UIDLength    int
	WorkerPool   int
	BufferedTask int
	// contains filtered or unexported fields
}

Config storing config for incoming message callback

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context stored info from client

func (*Context) Ctx

func (c *Context) Ctx() context.Context

Ctx return parrent Context

func (*Context) Event

func (c *Context) Event() *Event

Event return event context

func (*Context) Message

func (c *Context) Message() *Message

Message return message context

func (*Context) Sender

func (c *Context) Sender() *Actor

Sender return Actor from this context

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event describe of incoming event type

func (*Event) Type

func (e *Event) Type() TypeCode

Type return event type

type Message

type Message struct {
	// contains filtered or unexported fields
}

Message stored data of incoming signal from client

func (*Message) Bytes

func (msg *Message) Bytes() []byte

Bytes return array of bytes incoming data

func (*Message) Length

func (msg *Message) Length() int

Length return length of incoming data

func (*Message) String

func (msg *Message) String() string

String return string of array bytes message

type Socket

type Socket struct {
	// contains filtered or unexported fields
}

Socket struct for storing connection information

func CreateWebSocket

func CreateWebSocket() *Socket

CreateWebSocket constructor to create socket connection

func (*Socket) Callback

func (s *Socket) Callback(cb func(c *Context) error)

Callback used to set handler of incoming message

func (*Socket) Close

func (s *Socket) Close(a *Actor) (err error)

Close no meaning close function

func (*Socket) CloseGoingAway

func (s *Socket) CloseGoingAway(a *Actor, message string) (err error)

CloseGoingAway is used to close actor connection with defined status

func (*Socket) CloseInternalServerError

func (s *Socket) CloseInternalServerError(a *Actor, message string) (err error)

CloseInternalServerError is used to close actor connection with defined status

func (*Socket) CloseInvalidFramePayloadData

func (s *Socket) CloseInvalidFramePayloadData(a *Actor, message string) (err error)

CloseInvalidFramePayloadData is used to close actor connection with defined status

func (*Socket) CloseMandatoryExt

func (s *Socket) CloseMandatoryExt(a *Actor, message string) (err error)

CloseMandatoryExt is used to close actor connection with defined status

func (*Socket) CloseMessageTooBig

func (s *Socket) CloseMessageTooBig(a *Actor, message string) (err error)

CloseMessageTooBig is used to close actor connection with defined status

func (*Socket) CloseNoMeaningYet

func (s *Socket) CloseNoMeaningYet(a *Actor, message string) (err error)

CloseNoMeaningYet is used to close actor connection with defined status

func (*Socket) CloseNormalClosure

func (s *Socket) CloseNormalClosure(a *Actor, message string) (err error)

CloseNormalClosure is used to close actor connection with defined status

func (*Socket) ClosePolicyViolation

func (s *Socket) ClosePolicyViolation(a *Actor, message string) (err error)

ClosePolicyViolation is used to close actor connection with defined status

func (*Socket) CloseProtocolError

func (s *Socket) CloseProtocolError(a *Actor, message string) (err error)

CloseProtocolError is used to close actor connection with defined status

func (*Socket) CloseTLSHandshake

func (s *Socket) CloseTLSHandshake(a *Actor, message string) (err error)

CloseTLSHandshake is used to close actor connection with defined status

func (*Socket) CloseUnsupportedData

func (s *Socket) CloseUnsupportedData(a *Actor, message string) (err error)

CloseUnsupportedData is used to close actor connection with defined status

func (*Socket) IterateEachActor

func (s *Socket) IterateEachActor(cb func(*Actor))

IterateEachActor this function enable you to send text to every client but by criteria, return true if then this client will receive the message

func (*Socket) Listen

func (s *Socket) Listen(port int) error

Listen function that loop every time to catch new connection

func (*Socket) SendByteTo

func (s *Socket) SendByteTo(id string, data []byte) error

SendByteTo function that can enable to send message to other connected client

func (*Socket) SendTextTo

func (s *Socket) SendTextTo(id, message string) error

SendTextTo function that can enable to send message to other connected client

type TypeCode

type TypeCode byte

TypeCode type alias for byte enum

const (
	// Event code
	TypeContinuation TypeCode = 0x0
	TypeConnected    TypeCode = 0x7
	TypeDisconnected TypeCode = 0x8
	TypePing         TypeCode = 0x9
	TypePong         TypeCode = 0xa
	TypePingTimeout  TypeCode = 0xb

	// Message code
	TypeText   TypeCode = 0x1
	TypeBinary TypeCode = 0x2
)

List of every known code

func (*TypeCode) Eq

func (t *TypeCode) Eq(code interface{}) (bool, error)

Eq supposed to compare code from this pkg to ws.OpCode

type Worker

type Worker interface {

	// Callback can only be called when initializing the worker
	// and should not be nil
	// this function will responsible to what you want to do
	// with passed data from worker pool
	Callback(func(interface{}))

	// CallbackOnError same as Callback but with purpose to
	// this function set what you want to do when data/task
	// is not submited or not running properly
	CallbackOnError(func(interface{}))

	// Submit this function supposed to handle submit data
	// parameter can be list
	Submit(...interface{})
}

Worker this interface defined Worker behaviour so, we can use many backend workers API

func CreateWorkerPond

func CreateWorkerPond(c *Config) Worker

CreateWorkerPond constructor with default config pond worker pool

Directories

Path Synopsis
workers

Jump to

Keyboard shortcuts

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