eddwise

package module
v0.6.6 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2022 License: MIT Imports: 15 Imported by: 4

README

Edd WiSe

Release Test Security Linter

Edd WiSe

Edd WiSe - Event driven design over Web Socket
A tool to design uni or bi-directional event driven web applications.


Design First

You provide a simple description of your service within a yaml file, and you are able to generate documented code of both server (Golang) and client (Javascript). A dummy server/client implementations will be generated too, so you can fill them with business logic.

Behavioural Second

Speaking about events, it is natural to think how an event would influence the state of your application and of your remote clients.

Also, with the server code, the generation tool provides you with a "behave" interface that let you to naturally implement BDD scenarios thanks to a leveraging of goconvey around your defined events.

Install

Download the latest version for your OS from releases or install it from go:

go install github.com/exelr/eddwise/cmd/edd

Minimal design

Define your design:

# design/pingpong.edd.yml
namespace: pingpong
structs:
  ping:
    id: uint
  pong:
    id: uint

channels:
  pingpong:
    client:
      - ping 
    server:
      - pong
View details
# design/pingpong.edd.yml
namespace: pingpong # the namespace of your generated code (packages for go)
structs:
  ping: # ping is emitted from client
    id: uint # the id of the ping
  pong: # pong is sent from server after a ping
    id: uint # the id of the pong, same as the id of the received ping

channels:
  pingpong: # create a channel named pingpong
    client: # define the events that can pass through the channel pingpong generated from client
      - ping # set ping to be originated only from client 
    server: # define events generated from server
      - pong # set pong to be originated only from server
#    dual: # optional, you can define the events that are generated in both client and server
#      - ping
#      - pong

Generate the code:

edd design gen

Simple library

Server:

// cmd/pingpong/main.go
package main

import (
    "log"

    "github.com/exelr/eddwise"
    "pingpong/gen/pingpong"
)

type PingPongChannel struct {
    pingpong.PingPong
}

func (ch *PingPongChannel) OnPing(ctx eddwise.Context, ping *pingpong.Ping) error {
    return ch.SendPong(ctx.GetClient(), &pingpong.Pong{Id: ping.Id})
}

func main(){
    var server = eddwise.NewServer()
    var ch = &NewPingPongChannel{}
    if err := server.Register(ch); err != nil {
        log.Fatalln("unable to register service PingPong: ", err)
    }
    log.Fatalln(server.StartWS("/pingpong", 3000))
}

Client:

// web/pingpong/app.html
<script type="module">
    import {EddClient} from '/pingpong/edd.js'
    import {pingpongChannel} from '../../gen/pingpong/channel.js'
    let client = new EddClient("ws://localhost:3000/pingpong")
    let pingpong = new pingpongChannel()
    client.register(pingpong)
    
    pingpong.onpong((pong) => {
        console.log("received pong with id", pong.id)
    });
    
    let pinginterval;
    pingpong.connected(() => {
        let id = 1;
        pinginterval = setInterval(function () {
            pingpong.sendping({id: id++})
        }, 1000)
    })
    pinginterval.disconnected = function(){
        clearInterval(pinginterval)
    }
</script>

You can also generate skeleton code for client and server directly:

edd design skeleton
Want to see more?

See Examples repo.

A full demo of a simple web game is available, see Filotto.

Alternatives

  • GRPC over websocket
  • AsyncAPI with websocket extension
  • WAMP (for the ws not for the design)
  • Flogo

Logo from gopherize.me

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Broadcast added in v0.1.4

func Broadcast(channel string, event Event, clients []Client) error

func ChannelAuthMethods added in v0.6.0

func ChannelAuthMethods(ch ImplChannel) []string

func ClientJS added in v0.6.3

func ClientJS() []byte

func ErrMissingServerHandler

func ErrMissingServerHandler(chName, eventName string) error

Types

type Auth added in v0.6.0

type Auth struct {
	Id   string      `json:"id"`
	Data interface{} `json:"data"`
}

type AuthChallenge added in v0.6.0

type AuthChallenge struct {
	Methods []string `json:"methods"`
}

func (*AuthChallenge) GetEventName added in v0.6.0

func (*AuthChallenge) GetEventName() string

func (*AuthChallenge) ProtocolAlias added in v0.6.0

func (*AuthChallenge) ProtocolAlias() string

type AuthPass added in v0.6.0

type AuthPass struct {
	Id string `json:"id"`
}

func (*AuthPass) GetEventName added in v0.6.0

func (*AuthPass) GetEventName() string

func (*AuthPass) ProtocolAlias added in v0.6.0

func (*AuthPass) ProtocolAlias() string

type BasicAuth added in v0.6.0

type BasicAuth struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

func (*BasicAuth) GetEventName added in v0.6.0

func (*BasicAuth) GetEventName() string

func (*BasicAuth) ProtocolAlias added in v0.6.0

func (*BasicAuth) ProtocolAlias() string

type ChannelBroadcastUserJoinLeft added in v0.6.0

type ChannelBroadcastUserJoinLeft struct{}

type Client

type Client interface {
	ClientContext
	GetId() uint64
	Send(channel string, event Event) error
	SendJSON(interface{}) error
	Close() error
	Closed() bool
}

type ClientContext added in v0.6.0

type ClientContext interface {
	Has(string) bool
	Get(string) interface{}
	Set(string, interface{})

	GetRawAuth() *Auth

	GetState() interface{}
	GetRooms() []*Room
	// contains filtered or unexported methods
}

type ClientContextMap added in v0.6.0

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

func (*ClientContextMap) Get added in v0.6.0

func (cc *ClientContextMap) Get(key string) interface{}

func (*ClientContextMap) GetRawAuth added in v0.6.0

func (cc *ClientContextMap) GetRawAuth() *Auth

func (*ClientContextMap) GetRooms added in v0.6.5

func (cc *ClientContextMap) GetRooms() []*Room

func (*ClientContextMap) GetState added in v0.6.0

func (cc *ClientContextMap) GetState() interface{}

func (*ClientContextMap) Has added in v0.6.0

func (cc *ClientContextMap) Has(key string) bool

func (*ClientContextMap) Set added in v0.6.0

func (cc *ClientContextMap) Set(key string, value interface{})

type ClientRoomEvent added in v0.6.5

type ClientRoomEvent interface {
	Event
	ClientRoomEvent()
}

type ClientSocket added in v0.1.4

type ClientSocket struct {
	ClientContextMap

	Server  *ServerSocket
	Conn    *websocket.Conn
	WriteMx sync.Mutex
	// contains filtered or unexported fields
}

func (*ClientSocket) Close added in v0.1.4

func (c *ClientSocket) Close() error

func (*ClientSocket) Closed added in v0.1.4

func (c *ClientSocket) Closed() bool

func (*ClientSocket) GetId added in v0.1.4

func (c *ClientSocket) GetId() uint64

func (*ClientSocket) Send added in v0.1.4

func (c *ClientSocket) Send(channel string, event Event) error

func (*ClientSocket) SendJSON added in v0.1.4

func (c *ClientSocket) SendJSON(v interface{}) error

type CodecSerializer added in v0.3.0

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

func NewCodecSerializer added in v0.3.0

func NewCodecSerializer(handle codec.Handle) *CodecSerializer

func (*CodecSerializer) Decode added in v0.3.0

func (cs *CodecSerializer) Decode(data []byte, v interface{}) error

func (*CodecSerializer) Encode added in v0.3.0

func (cs *CodecSerializer) Encode(v interface{}) ([]byte, error)

type ConnManager added in v0.6.0

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

func (*ConnManager) GetAuthorizedClients added in v0.6.0

func (cm *ConnManager) GetAuthorizedClients(exceptClientIds ...uint64) []Client

func (*ConnManager) GetAuthorizedUserClients added in v0.6.0

func (cm *ConnManager) GetAuthorizedUserClients(exceptUserIds ...string) []Client

func (*ConnManager) GetAuthorizedUserIds added in v0.6.0

func (cm *ConnManager) GetAuthorizedUserIds(exceptIds ...string) []string

func (*ConnManager) IsUserConnected added in v0.6.0

func (cm *ConnManager) IsUserConnected(id string) bool

type Context

type Context interface {
	context.Context
	GetServer() Server
	GetClient() Client
}

type DefaultContext

type DefaultContext struct {
	context.Context
	// contains filtered or unexported fields
}

func NewDefaultContext

func NewDefaultContext(ctx context.Context, server Server, client Client) *DefaultContext

func NewDefaultContextFromBackground added in v0.1.4

func NewDefaultContextFromBackground(server Server, client Client) *DefaultContext

func (*DefaultContext) GetClient

func (ctx *DefaultContext) GetClient() Client

func (*DefaultContext) GetServer

func (ctx *DefaultContext) GetServer() Server

type Event

type Event interface {
	GetEventName() string
	ProtocolAlias() string
}

type EventCheckReceivedFields added in v0.2.1

type EventCheckReceivedFields interface {
	Event
	CheckReceivedFields() error
}

type EventCheckSendFields added in v0.2.1

type EventCheckSendFields interface {
	Event
	CheckSendFields() error
}

type EventHandler

type EventHandler func(Context, *EventMessage) error

type EventMessage added in v0.1.4

type EventMessage struct {
	Channel string    `json:"channel"`
	Name    string    `json:"name"`
	Body    codec.Raw `json:"body"`
}

type EventMessageToSend added in v0.6.0

type EventMessageToSend struct {
	Channel string      `json:"channel"`
	Name    string      `json:"name"`
	Body    interface{} `json:"body"`
}

type ImplChannel

type ImplChannel interface {
	Name() string
	Alias() string
	Bind(Server) error
	Route(Context, *EventMessage) error
	GetServer() Server
	SetReceiver(ImplChannel) error
}

type ImplChannelBasicAuth added in v0.6.0

type ImplChannelBasicAuth interface {
	OnBasicAuth(Context, *BasicAuth) (*Auth, error)
}

type ImplChannelConnected

type ImplChannelConnected interface {
	Connected(Client) error
}

type ImplChannelDisconnected

type ImplChannelDisconnected interface {
	Disconnected(Client) error
}

type ImplChannelWithUserJoin added in v0.6.0

type ImplChannelWithUserJoin interface {
	// contains filtered or unexported methods
}

type ImplChannelWithUserLeft added in v0.6.0

type ImplChannelWithUserLeft interface {
	// contains filtered or unexported methods
}

type ImplConnManager added in v0.6.0

type ImplConnManager interface {
	GetAuthorizedUserClients(...string) []Client
	GetAuthorizedClients(...uint64) []Client
	GetAuthorizedUserIds(...string) []string
	// contains filtered or unexported methods
}

type ImplRoomManager added in v0.6.5

type ImplRoomManager interface {
	OnRoomEvent(Client, ClientRoomEvent) error
	SendRoomEvent(Client, ServerRoomEvent) error
	BroadcastRoomEvent([]Client, ServerRoomEvent) error
	SendPublicRooms(Client) error
	RoomClientQuit(Client) error
	// contains filtered or unexported methods
}

type JsonSerializer

type JsonSerializer struct{}

func (*JsonSerializer) Deserialize

func (s *JsonSerializer) Deserialize(data []byte, v interface{}) error

func (*JsonSerializer) Serialize

func (s *JsonSerializer) Serialize(v interface{}) ([]byte, error)

type MsgPackSerializer added in v0.3.0

type MsgPackSerializer struct{}

func (*MsgPackSerializer) Deserialize added in v0.3.0

func (s *MsgPackSerializer) Deserialize(data []byte, v interface{}) error

func (*MsgPackSerializer) Serialize added in v0.3.0

func (s *MsgPackSerializer) Serialize(v interface{}) ([]byte, error)

type Room added in v0.6.5

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

func (*Room) Clients added in v0.6.5

func (r *Room) Clients() []Client

func (*Room) Has added in v0.6.5

func (r *Room) Has(client Client) bool

func (*Room) Join added in v0.6.5

func (r *Room) Join(client Client) error

func (*Room) Left added in v0.6.5

func (r *Room) Left(client Client) error

type RoomCreate added in v0.6.5

type RoomCreate struct {
	Room string `json:"room"`
}

func (*RoomCreate) GetEventName added in v0.6.5

func (*RoomCreate) GetEventName() string

func (*RoomCreate) ProtocolAlias added in v0.6.5

func (*RoomCreate) ProtocolAlias() string

func (*RoomCreate) ServerRoomEvent added in v0.6.5

func (*RoomCreate) ServerRoomEvent()

type RoomCreateRequest added in v0.6.5

type RoomCreateRequest struct {
	Room   string `json:"room"`
	Public bool   `json:"public"`
}

func (*RoomCreateRequest) ClientRoomEvent added in v0.6.5

func (*RoomCreateRequest) ClientRoomEvent()

func (*RoomCreateRequest) GetEventName added in v0.6.5

func (*RoomCreateRequest) GetEventName() string

func (*RoomCreateRequest) ProtocolAlias added in v0.6.5

func (*RoomCreateRequest) ProtocolAlias() string

type RoomJoin added in v0.6.5

type RoomJoin struct {
	Id   string `json:"id"`
	Room string `json:"room"`
}

func (*RoomJoin) GetEventName added in v0.6.5

func (*RoomJoin) GetEventName() string

func (*RoomJoin) ProtocolAlias added in v0.6.5

func (*RoomJoin) ProtocolAlias() string

func (*RoomJoin) ServerRoomEvent added in v0.6.5

func (*RoomJoin) ServerRoomEvent()

type RoomJoinRequest added in v0.6.5

type RoomJoinRequest struct {
	Room string `json:"room"`
}

func (*RoomJoinRequest) ClientRoomEvent added in v0.6.5

func (*RoomJoinRequest) ClientRoomEvent()

func (*RoomJoinRequest) GetEventName added in v0.6.5

func (*RoomJoinRequest) GetEventName() string

func (*RoomJoinRequest) ProtocolAlias added in v0.6.5

func (*RoomJoinRequest) ProtocolAlias() string

type RoomLeft added in v0.6.5

type RoomLeft struct {
	Id   string `json:"id"`
	Room string `json:"room"`
}

func (*RoomLeft) GetEventName added in v0.6.5

func (*RoomLeft) GetEventName() string

func (*RoomLeft) ProtocolAlias added in v0.6.5

func (*RoomLeft) ProtocolAlias() string

func (*RoomLeft) ServerRoomEvent added in v0.6.5

func (*RoomLeft) ServerRoomEvent()

type RoomLeftRequest added in v0.6.5

type RoomLeftRequest struct {
	Room string `json:"room"`
}

func (*RoomLeftRequest) ClientRoomEvent added in v0.6.5

func (*RoomLeftRequest) ClientRoomEvent()

func (*RoomLeftRequest) GetEventName added in v0.6.5

func (*RoomLeftRequest) GetEventName() string

func (*RoomLeftRequest) ProtocolAlias added in v0.6.5

func (*RoomLeftRequest) ProtocolAlias() string

type RoomManager added in v0.6.5

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

func (*RoomManager) BroadcastRoomEvent added in v0.6.5

func (rm *RoomManager) BroadcastRoomEvent(clients []Client, event ServerRoomEvent) error

func (*RoomManager) Create added in v0.6.5

func (rm *RoomManager) Create(id string, public bool) (*Room, error)

func (*RoomManager) MultiRoomMode added in v0.6.5

func (rm *RoomManager) MultiRoomMode(b bool)

func (*RoomManager) OnRoomEvent added in v0.6.5

func (rm *RoomManager) OnRoomEvent(client Client, event ClientRoomEvent) error

func (*RoomManager) Room added in v0.6.5

func (rm *RoomManager) Room(id string) *Room

func (*RoomManager) RoomClientQuit added in v0.6.5

func (rm *RoomManager) RoomClientQuit(client Client) error

func (*RoomManager) SendPublicRooms added in v0.6.5

func (rm *RoomManager) SendPublicRooms(client Client) error

func (*RoomManager) SendRoomEvent added in v0.6.5

func (rm *RoomManager) SendRoomEvent(client Client, event ServerRoomEvent) error

func (*RoomManager) SetRoomsPerUserLimit added in v0.6.5

func (rm *RoomManager) SetRoomsPerUserLimit(n int)

type Serializer

type Serializer interface {
	Serialize(interface{}) ([]byte, error)
	Deserialize([]byte, interface{}) error
}

type Server

type Server interface {
	AddClient(Client)
	GetClients(...uint64) []Client
	GetClient(uint64) Client
	RemoveClient(Client)
	Codec() *CodecSerializer
}

type ServerRoomEvent added in v0.6.5

type ServerRoomEvent interface {
	Event
	ServerRoomEvent()
}

type ServerSocket added in v0.1.4

type ServerSocket struct {
	Conn net.Conn

	RegisteredChannels map[string]ImplChannel

	ClientAutoInc uint64
	Clients       map[uint64]Client
	ClientsMx     sync.RWMutex
	App           *fiber.App
	// contains filtered or unexported fields
}

func NewServer

func NewServer() *ServerSocket

func NewServerWithCustomCodec added in v0.6.0

func NewServerWithCustomCodec(codec codec.Handle) *ServerSocket

func (*ServerSocket) AddClient added in v0.1.4

func (s *ServerSocket) AddClient(c Client)

func (*ServerSocket) CheckAuth added in v0.6.0

func (s *ServerSocket) CheckAuth(ctx Context, client *ClientSocket) error

func (*ServerSocket) Close added in v0.1.4

func (s *ServerSocket) Close(timeout time.Duration) error

func (*ServerSocket) Codec added in v0.3.0

func (s *ServerSocket) Codec() *CodecSerializer

func (*ServerSocket) CustomFiberApp added in v0.5.0

func (s *ServerSocket) CustomFiberApp(app *fiber.App)

func (*ServerSocket) GetClient added in v0.1.4

func (s *ServerSocket) GetClient(id uint64) Client

func (*ServerSocket) GetClients added in v0.1.4

func (s *ServerSocket) GetClients(exclude ...uint64) []Client

func (*ServerSocket) ProcessEvent added in v0.1.4

func (s *ServerSocket) ProcessEvent(ctx Context, rawEvent []byte) error

func (*ServerSocket) ProcessEventAuth added in v0.6.0

func (s *ServerSocket) ProcessEventAuth(ctx Context, chAuth ImplChannel, rawEvent []byte) error

func (*ServerSocket) Register added in v0.1.4

func (s *ServerSocket) Register(ch ImplChannel) error

func (*ServerSocket) RegisterStatic added in v0.3.0

func (s *ServerSocket) RegisterStatic(path, dir string)

func (*ServerSocket) RemoveClient added in v0.1.4

func (s *ServerSocket) RemoveClient(c Client)

func (*ServerSocket) RevokeAuth added in v0.6.0

func (s *ServerSocket) RevokeAuth(ctx Context, client *ClientSocket) error

func (*ServerSocket) StartWS added in v0.1.4

func (s *ServerSocket) StartWS(wsPath string, port int) error

func (*ServerSocket) StartWSS added in v0.5.0

func (s *ServerSocket) StartWSS(wsPath string, port int, certFile, keyFile string) error

type StateManager added in v0.6.0

type StateManager[T any] struct{}

func (*StateManager[T]) ClientState added in v0.6.0

func (sm *StateManager[T]) ClientState(c Client) *UserState[T]

func (*StateManager[T]) SetClientState added in v0.6.0

func (sm *StateManager[T]) SetClientState(c Client, state T)

type TestableChannel added in v0.1.4

type TestableChannel interface {
	ImplChannel
	Given(ImplChannel)
	Expect(TestableChannel)
}

type UserEvent added in v0.6.0

type UserEvent interface {
	Event
	SetId(string)
	SetUint64Id(uint64)
}

type UserJoin added in v0.6.0

type UserJoin struct {
	Id string `json:"id"`
}

func (*UserJoin) GetEventName added in v0.6.0

func (*UserJoin) GetEventName() string

func (*UserJoin) ProtocolAlias added in v0.6.0

func (*UserJoin) ProtocolAlias() string

func (*UserJoin) SetId added in v0.6.0

func (u *UserJoin) SetId(id string)

func (*UserJoin) SetUint64Id added in v0.6.0

func (u *UserJoin) SetUint64Id(id uint64)

type UserLeft added in v0.6.0

type UserLeft struct {
	Id string `json:"id"`
}

func (*UserLeft) GetEventName added in v0.6.0

func (*UserLeft) GetEventName() string

func (*UserLeft) ProtocolAlias added in v0.6.0

func (*UserLeft) ProtocolAlias() string

func (*UserLeft) SetId added in v0.6.0

func (u *UserLeft) SetId(id string)

func (*UserLeft) SetUint64Id added in v0.6.0

func (u *UserLeft) SetUint64Id(id uint64)

type UserState added in v0.6.0

type UserState[T any] struct {
	sync.RWMutex
	State T
}

Directories

Path Synopsis
cmd
edd
internal

Jump to

Keyboard shortcuts

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