socket

package module
v0.0.0-...-1fe5563 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2019 License: MIT Imports: 6 Imported by: 0

README

go-socket

TCP Socket.io-like library

Go Report Card

Quick start

This library allows you to organize work with sockets through the convenient mechanism of "events". Here are some examples of use:

package main

import (
	"fmt"
	"github.com/kanopeld/socket"
	"time"
)

func main() {
	// create new socket  server
    s, err := socket.NewServer(":6500")
    if err != nil {
        panic(err)
    }

    // When connecting a new client, the connection event will be raised, therefore for this to work, such a handler must be defined
    // ConnectionName=="connection"
    s.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
        fmt.Println("connected", c.ID())

        // All other handlers we assign to the newly created socket
        c.On("test", func(c socket.Client, data []byte) error {
            fmt.Println("server got test event")
            fmt.Printf("Test (%s) message\n", string(data))
            _ = c.Emit("test", nil)
            return nil
        })

        _ = c.Broadcast("test1", nil)

        // DisconnectionName=="disconnection"
        c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
            fmt.Println("Server disc")
            return nil
        })
        return nil
    })

    // this is a blocking method so we will spawn a goroutine for it. Use s.Stop() to stop the server
    go s.Start()

    // Thus, we establish a connection to the  At the time of opening, the server receives a message and a connection event is called on it
    d1, err := socket.NewDial("localhost:6500")
    if err != nil {
        panic(err)
    }
    d1.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
        fmt.Println("d1 Connect!")
        c.On("test", func(c socket.Client, data []byte) error {
            go func() {
                fmt.Println("d1 got test event")
            }()
            return nil
        })
        _ = c.Emit("test", []byte("hello"))

        c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
            fmt.Println("d1 disc")
            return nil
        })

        c.On("test1", func(c socket.Client, data []byte) error {
            fmt.Println("d1 got dial broadcast")
            return nil
        })
        return nil
    })

    d2, err := socket.NewDial("localhost:6500")
    if err != nil {
        panic(err)
    }
    d2.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
        c.On("test", func(c socket.Client, data []byte) error {
            go func() {
                fmt.Println("d2 got test event")
            }()
            return nil
        })
        _ = c.Emit("test", []byte("hello"))

        c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
            fmt.Println("d2 disc")
            return nil
        })

        c.On("test1", func(c socket.Client, data []byte) error {
            fmt.Println("d2 got dial 1 broadcast")
            return nil
        })
        return nil
    })

    // for make sure what dial code finished
    time.Sleep(10 * time.Second)

    // stop the server wait & close tcp connect
    s.Stop()
}

In this example, we start listening and accepting connections on port 6500. As soon as a client connects to our server, the 'connection' event is triggered on both ends. Inside of our 'connection' event we define the remaining events on the received client object. We also use a predefined 'disconnection' event that gets triggered upon disconnection.
In the example above, we considered the SClient interface that is used on the server side. There is also a DClient interface used on the client side. Their difference in the absence of broadcast sending at the client

For a more thorough documentation see godoc

The project uses a standard MIT license. See more in LICENSE

Documentation

Overview

package socket is a Golang implementation of TCP sockets: https://github.com/kanopeld/go-socket

See README.md for more info

Example (Quickstart)
package main

import (
	"fmt"
	"github.com/kanopeld/socket"
	"time"
)

func main() {
	// create new socket  server
	s, err := socket.NewServer(":6500")
	if err != nil {
		panic(err)
	}

	// When connecting a new client, the connection event will be raised, therefore for this to work, such a handler must be defined
	// ConnectionName=="connection"
	s.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
		fmt.Println("connected", c.ID())

		// All other handlers we assign to the newly created socket
		c.On("test", func(c socket.Client, data []byte) error {
			fmt.Println("server got test event")
			fmt.Printf("Test (%s) message\n", string(data))
			_ = c.Emit("test", nil)
			return nil
		})

		_ = c.Broadcast("test1", nil)

		// DisconnectionName=="disconnection"
		c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
			fmt.Println("Server disc")
			return nil
		})
		return nil
	})

	// this is a blocking method so we will spawn a goroutine for it. Use s.Stop() to stop the server
	go s.Start()

	// Thus, we establish a connection to the  At the time of opening, the server receives a message and a connection event is called on it
	d1, err := socket.NewDial("localhost:6500")
	if err != nil {
		panic(err)
	}
	d1.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
		fmt.Println("d1 Connect!")
		c.On("test", func(c socket.Client, data []byte) error {
			go func() {
				fmt.Println("d1 got test event")
			}()
			return nil
		})
		_ = c.Emit("test", []byte("hello"))

		c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
			fmt.Println("d1 disc")
			return nil
		})

		c.On("test1", func(c socket.Client, data []byte) error {
			fmt.Println("d1 got dial broadcast")
			return nil
		})
		return nil
	})

	d2, err := socket.NewDial("localhost:6500")
	if err != nil {
		panic(err)
	}
	d2.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
		c.On("test", func(c socket.Client, data []byte) error {
			go func() {
				fmt.Println("d2 got test event")
			}()
			return nil
		})
		_ = c.Emit("test", []byte("hello"))

		c.On(socket.DisconnectionName, func(c socket.Client, data []byte) error {
			fmt.Println("d2 disc")
			return nil
		})

		c.On("test1", func(c socket.Client, data []byte) error {
			fmt.Println("d2 got dial 1 broadcast")
			return nil
		})
		return nil
	})

	// for make sure what dial code finished
	time.Sleep(10 * time.Second)

	// stop the server wait & close tcp connect
	s.Stop()
}
Output:

Index

Examples

Constants

View Source
const (
	// ConnectionName is the name of an event that is called when new client has connected (server side) or when client connected to the server (client side)
	ConnectionName = "connection"
	// DisconnectionName is the name of an event that is called when client has disconnected
	DisconnectionName = "disconnection"
)
View Source
const (
	// DefaultBroadcastRoomName name of default room in broadcast cluster. All new connections will be stored in room by this name
	DefaultBroadcastRoomName = "defaultBroadcast"
)

Variables

View Source
var (
	// ErrClientNotInRoom informs the client is not in the room
	ErrClientNotInRoom = errors.New("client is not in this room")
	// ErrClientAlreadyInRoom informs the client is already in a room
	ErrClientAlreadyInRoom = errors.New("client is in the room already")
	// ErrRoomNotExist informs that the room does not exist
	ErrRoomNotExist = errors.New("room does not exist")
)
View Source
var (
	// ErrEventNotExist is returned if the emited event does not exist
	ErrEventNotExist = errors.New("event does not exist")
)

Functions

func NewServer

func NewServer(port string) (*server, error)

NewServer starts a tcp listener on a specified port and returns an initialized Server struct

Example (Creation)
package main

import (
	"github.com/kanopeld/socket"
)

func main() {
	s, err := socket.NewServer(":6500")
	if err != nil {
		panic(err)
	}

	s.On(socket.ConnectionName, func(c socket.Client, data []byte) error {
		// ...
		return nil
	})

	go s.Start()
}
Output:

Types

type Broadcaster

type Broadcaster interface {
	//Join add called client into room by given name, if there is no room it will be created
	Join(room string) error
	//Leave remove called client from room by given name, if after deleting the user in the room no one is left she will be deleted too
	Leave(room string) error
	// BroadcastTo sends an event to everyone else in the room by given name
	BroadcastTo(room, event string, msg []byte) error
	// Broadcast sends an event to everyone else in the room default("defaultBroadcast") room
	Broadcast(event string, arg []byte) error
}

Broadcaster now available only for server-side clients, for dial client it is stub now

type Client

type Client interface {
	Emitter
	Ider
	// Connection returns net.Conn with which the socket was created
	Connection() net.Conn
	// Disconnect drops current connection. Sends the appropriate message to the other side
	Disconnect()
	EventHandler
	Broadcaster
}

Client includes all basic functions for a client

func NewDial

func NewDial(addr string) (Client, error)

NewDial connects to a server and initializes a client

Example (Dialling)
package main

import (
	"fmt"
	"github.com/kanopeld/socket"
)

func main() {
	c, err := socket.NewDial("localhost:6500")
	if err != nil {
		panic(err)
	}

	fmt.Println(c.Connection())
}
Output:

type Emitter

type Emitter interface {
	// Emit sends an event to the other side
	Emit(event string, arg []byte) error
	// contains filtered or unexported methods
}

Emitter organizes sending events to the other side

type EventHandler

type EventHandler interface {
	// On registers an event handler under the given name
	On(event string, c HandlerCallback)
	// Off deletes an event handler. Return true if event existed
	Off(event string) bool
}

type HandlerCallback

type HandlerCallback func(c Client, data []byte) error

HandlerCallback is function that gets called on a certain event

type Ider

type Ider interface {
	// ID returns the socket id
	ID() string
}

type PackageType

type PackageType byte

PackageType the special type for marking packages

const (
	// PackTypeConnect serves for connection messages
	PackTypeConnect PackageType = iota
	// PackTypeDisconnect serves for disconnection messages
	PackTypeDisconnect
	// PackTypeEvent serves for event messages
	PackTypeEvent
	// PackTypeConnectAccept serves for connection accepted messages
	PackTypeConnectAccept
)

func (PackageType) Byte

func (pt PackageType) Byte() byte

Byte serializes a PackageType into byte

type Server

type Server interface {
	Start()
	Stop()
	EventHandler
}

Jump to

Keyboard shortcuts

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