neffos: github.com/kataras/neffos Index | Examples | Files | Directories

package neffos

import "github.com/kataras/neffos"

Index

Examples

Package Files

broadcaster.go client.go conn.go conn_handler.go conn_namespace.go conn_room.go debug.go doc.go event.go message.go process.go reflect.go server.go stackexchange.go waiter_once.go

Constants

const URLParamAsHeaderPrefix = "X-Websocket-Header-"

URLParamAsHeaderPrefix is the prefix that server parses the url parameters as request headers. The client's `URLParamAsHeaderPrefix` must match. Note that this is mostly useful for javascript browser-side clients, nodejs and go client support custom headers by default. No action required from end-developer, exported only for chance to a custom parsing.

Variables

var (
    // EventPrefixMatcher matches methods to events based on the "prefix".
    EventPrefixMatcher = func(prefix string) EventMatcherFunc {
        return func(methodName string) (string, bool) {
            if strings.HasPrefix(methodName, prefix) {
                return methodName, true
            }

            return "", false
        }
    }

    // EventTrimPrefixMatcher matches methods based on the "prefixToTrim"
    // and events are registered without this prefix.
    EventTrimPrefixMatcher = func(prefixToTrim string) EventMatcherFunc {
        return func(methodName string) (string, bool) {
            if strings.HasPrefix(methodName, prefixToTrim) {
                return methodName[len(prefixToTrim):], true
            }

            return "", false
        }
    }
)
var (
    // OnNamespaceConnect is the event name which its callback is fired right before namespace connect,
    // if non-nil error then the remote connection's `Conn.Connect` will fail and send that error text.
    // Connection is not ready to emit data to the namespace.
    OnNamespaceConnect = "_OnNamespaceConnect"
    // OnNamespaceConnected is the event name which its callback is fired after namespace successfully connected.
    // Connection is ready to emit data back to the namespace.
    OnNamespaceConnected = "_OnNamespaceConnected"
    // OnNamespaceDisconnect is the event name which its callback is fired when
    // remote namespace disconnection or local namespace disconnection is happening.
    // For server-side connections the reply matters, so if error returned then the client-side cannot disconnect yet,
    // for client-side the return value does not matter.
    OnNamespaceDisconnect = "_OnNamespaceDisconnect" // if allowed to connect then it's allowed to disconnect as well.
    // OnRoomJoin is the event name which its callback is fired right before room join.
    OnRoomJoin = "_OnRoomJoin" // able to check if allowed to join.
    // OnRoomJoined is the event name which its callback is fired after the connection has successfully joined to a room.
    OnRoomJoined = "_OnRoomJoined" // able to broadcast messages to room.
    // OnRoomLeave is the event name which its callback is fired right before room leave.
    OnRoomLeave = "_OnRoomLeave" // able to broadcast bye-bye messages to room.
    // OnRoomLeft is the event name which its callback is fired after the connection has successfully left from a room.
    OnRoomLeft = "_OnRoomLeft" // if allowed to join to a room, then its allowed to leave from it.
    // OnAnyEvent is the event name which its callback is fired when incoming message's event is not declared to the ConnHandler(`Events` or `Namespaces`).
    OnAnyEvent = "_OnAnyEvent" // when event no match.
    // OnNativeMessage is fired on incoming native/raw websocket messages.
    // If this event defined then an incoming message can pass the check (it's an invalid message format)
    // with just the Message's Body filled, the Event is "OnNativeMessage" and IsNative always true.
    // This event should be defined under an empty namespace in order this to work.
    OnNativeMessage = "_OnNativeMessage"
)
var (
    // DefaultMarshaler is a global, package-level alternative for `MessageObjectMarshaler`.
    // It's used when the `Marshal.v` parameter is not a `MessageObjectMarshaler`.
    DefaultMarshaler = json.Marshal
    // DefaultUnmarshaler is a global, package-level alternative for `MessageObjectMarshaler`.
    // It's used when the `Message.Unmarshal.outPtr` parameter is not a `MessageObjectUnmarshaler`.
    DefaultUnmarshaler = json.Unmarshal
)
var (
    // ErrBadNamespace may return from a `Conn#Connect` method when the remote side does not declare the given namespace.
    ErrBadNamespace = errors.New("bad namespace")
    // ErrBadRoom may return from a `Room#Leave` method when trying to leave from a not joined room.
    ErrBadRoom = errors.New("bad room")
    // ErrWrite may return from any connection's method when the underline connection is closed (unexpectedly).
    ErrWrite = errors.New("write closed")
)
var ErrInvalidPayload = errors.New("invalid payload")

ErrInvalidPayload can be returned by the internal `handleMessage`. In the future it may be exposed by an error listener.

func DebugEach Uses

func DebugEach(mapOrSlice interface{}, onDebugVisitor interface{})

DebugEach prints debug messages for each of "mapOrSlice" elements to the printer defined on `EnableDebug`. Runs only on debug mode. Usage: DebugEach(staticFields, func(idx int, f reflect.Value) {

fval := f.Interface()
Debugf("field [%s.%s] will be automatically re-filled with [%T(%s)]", typ.Name(), typ.Field(idx).Name, fval, fval)

})

func Debugf Uses

func Debugf(format string, args ...interface{})

Debugf prints debug messages to the printer defined on `EnableDebug`. Runs only on debug mode.

func EnableDebug Uses

func EnableDebug(printer interface{})

EnableDebug enables debug and optionally sets a custom printer to print out debug messages. The "printer" can be any compatible printer such as the standard `log.Logger` or a custom one like the `kataras/golog`.

A "printer" is compatible when it contains AT LEAST ONE of the following methods: Debugf(string, ...interface{}) or Logf(string, ...interface{}) or Printf(string, ...interface{})

If EnableDebug is called but the "printer" value is nil then neffos will print debug messages through a new log.Logger prefixed with "| neffos |".

Note that neffos, currently, uses debug mode only on the build state of the events. Therefore enabling the debugger has zero performance cost on up-and-running servers and clients.

There is no way to disable the debug mode on serve-time.

func Exclude Uses

func Exclude(connID string) fmt.Stringer

Exclude can be passed on `Server#Broadcast` when caller does not have access to the `Conn`, `NSConn` or a `Room` value but has access to a string variable which is a connection's ID instead.

Example Code: nsConn.Conn.Server().Broadcast(

	neffos.Exclude("connection_id_here"),
 neffos.Message{Namespace: "default", Room: "roomName or empty", Event: "chat", Body: [...]})

func IsCloseError Uses

func IsCloseError(err error) bool

IsCloseError reports whether the "err" is a "closed by the remote host" network connection error.

func IsDisconnectError Uses

func IsDisconnectError(err error) bool

IsDisconnectError reports whether the "err" is a timeout or a closed connection error.

func IsSystemEvent Uses

func IsSystemEvent(event string) bool

IsSystemEvent reports whether the "event" is a system event, OnNamespaceConnect, OnNamespaceConnected, OnNamespaceDisconnect, OnRoomJoin, OnRoomJoined, OnRoomLeave and OnRoomLeft.

func IsTimeoutError Uses

func IsTimeoutError(err error) bool

IsTimeoutError reports whether the "err" is caused by a defined timeout.

func IsTryingToReconnect Uses

func IsTryingToReconnect(err error) (ok bool)

IsTryingToReconnect reports whether the returning "err" from the `Server#Upgrade` is from a client that was trying to reconnect to the websocket server.

Look the `Conn#WasReconnected` and `Conn#ReconnectTries` too.

func Marshal Uses

func Marshal(v interface{}) []byte

Marshal marshals the "v" value and returns a Message's Body. If the "v" value is `MessageObjectMarshaler` then it returns the result of its `Marshal` method, otherwise the DefaultMarshaler will be used instead. Errors are pushed to the result, use the object's Marshal method to catch those when necessary.

func RegisterKnownError Uses

func RegisterKnownError(err error)

RegisterKnownError registers an error that it's "known" to both server and client sides. This simply adds an error to a list which, if its static text matches an incoming error text then its value is set to the `Message.Error` field on the events callbacks.

For dynamic text error, there is a special case which if the error "err" contains a `ResolveError(errorText string) bool` method then, it is used to report whether this "err" is match to the incoming error text.

func Reply Uses

func Reply(body []byte) error

Reply is a special type of custom error which sends a message back to the other side with the exact same incoming Message's Namespace (and Room if specified) except its body which would be the given "body".

type Client Uses

type Client struct {

    // ID comes from server, local changes are not reflected,
    // use the `Server#IDGenerator` if you want to set a custom logic for ID set.
    ID  string

    // NotifyClose can be optionally registered to notify about the client's disconnect.
    // This callback is for the entire client side connection,
    // the channel is notified after namespace disconnected and any room left events.
    // Don't confuse it with the `OnNamespaceDisconnect` event.
    // Usage:
    // <- client.NotifyClose // blocks until local `Close` or remote close of connection.
    NotifyClose <-chan struct{}
    // contains filtered or unexported fields
}

Client is the neffos client. Contains the neffos client-side connection and the ID came from server on acknowledgement process of the `Dial` function. Use its `Connect` to connect to a namespace or `WaitServerConnect` to wait for server to force-connect this client to a namespace.

func Dial Uses

func Dial(ctx context.Context, dial Dialer, url string, connHandler ConnHandler) (*Client, error)

Dial establishes a new neffos client connection. Context "ctx" is used for handshake timeout. Dialer "dial" can be either `gobwas.Dialer/DefaultDialer` or `gorilla.Dialer/DefaultDialer`, custom dialers can be used as well when complete the `Socket` and `Dialer` interfaces for valid client. URL "url" is the endpoint of the neffos server, i.e "ws://localhost:8080/echo". The last parameter, and the most important one is the "connHandler", it can be filled as `Namespaces`, `Events` or `WithTimeout`, same namespaces and events can be used on the server-side as well.

See examples for more.

func (*Client) Close Uses

func (c *Client) Close()

Close method terminates the client-side connection. Forces the client to disconnect from all connected namespaces and leave from all joined rooms, server gets notified.

func (*Client) Connect Uses

func (c *Client) Connect(ctx context.Context, namespace string) (*NSConn, error)

Connect method returns a new connected to the specific "namespace" `NSConn` value. The "namespace" should be declared in the `connHandler` of both server and client sides. Returns error if server-side's `OnNamespaceConnect` event callback returns an error.

See `Conn#Connect` for more details.

func (*Client) WaitServerConnect Uses

func (c *Client) WaitServerConnect(ctx context.Context, namespace string) (*NSConn, error)

WaitServerConnect method blocks until server manually calls the connection's `Connect` on the `Server#OnConnected` event.

See `Conn#WaitConnect` for more details.

type CloseError Uses

type CloseError struct {
    Code int
    // contains filtered or unexported fields
}

CloseError can be used to send and close a remote connection in the event callback's return statement.

func (CloseError) Error Uses

func (err CloseError) Error() string

type Conn Uses

type Conn struct {

    // ReconnectTries, if > 0 then this connection is a result of a client-side reconnection,
    // see `WasReconnected() bool`.
    ReconnectTries int
    // contains filtered or unexported fields
}

Conn contains the websocket connection and the neffos communication functionality. Its `Connection` will return a new `NSConn` instance. Each connection can connect to one or more declared namespaces. Each `NSConn` can join to multiple rooms.

func (*Conn) Ask Uses

func (c *Conn) Ask(ctx context.Context, msg Message) (Message, error)

Ask method sends a message to the remote side and blocks until a response or an error received from the specific `Message.Event`.

func (*Conn) Close Uses

func (c *Conn) Close()

Close method will force-disconnect from all connected namespaces and force-leave from all joined rooms and finally will terminate the underline websocket connection. After this method call the `Conn` is not usable anymore, a new `Dial` call is required.

func (*Conn) Connect Uses

func (c *Conn) Connect(ctx context.Context, namespace string) (*NSConn, error)

Connect method returns a new connected to the specific "namespace" `NSConn` value. The "namespace" should be declared in the `connHandler` of both server and client sides. If this is a client-side connection then the server-side namespace's `OnNamespaceConnect` event callback MUST return null in order to allow this client-side connection to connect, otherwise a non-nil error is returned instead.

func (*Conn) Decrement Uses

func (c *Conn) Decrement(key string) int

Decrement works like `Set` method. It's just a helper for decrementing integer values. If value does exist, and it's an integer then it decrements it by 1, otherwise the value is overridden to value -1. If value does not exist, then it assumes the default value is 0 and it decrements it by one, the result will be -1.

Calling it twice for example it will set the value to -2, even if doesn't exist before.

Returns the decremented value.

func (*Conn) DeserializeMessage Uses

func (c *Conn) DeserializeMessage(payload []byte) Message

DeserializeMessage returns a Message from the "payload".

func (*Conn) DisconnectAll Uses

func (c *Conn) DisconnectAll(ctx context.Context) error

DisconnectAll method disconnects from all namespaces, `OnNamespaceDisconnect` even will be fired and its `Message.IsLocal` will be true. The remote side gets notified.

func (*Conn) Get Uses

func (c *Conn) Get(key string) interface{}

Get retruns a value based on the given "key" from this connection's store.

func (*Conn) HandlePayload Uses

func (c *Conn) HandlePayload(payload []byte) error

HandlePayload fires manually a local event based on the "payload".

func (*Conn) ID Uses

func (c *Conn) ID() string

ID method returns the unique identifier of the connection. If this is a server-side connection then this value is the generated one by the `Server#IDGenerator`. If this is a client-side connection then this value is filled on the acknowledgment process which is done on the `Client#Dial`.

func (*Conn) Increment Uses

func (c *Conn) Increment(key string) int

Increment works like `Set` method. It's just a helper for incrementing integer values. If value does exist, and it's an integer then it increments it by 1, otherwise the value is overridden to value 1. If value does not exist, then it assumes the default value is 0 and it increments it by one, the result will be 1.

Returns the incremented value.

func (*Conn) Is Uses

func (c *Conn) Is(connID string) bool

Is reports whether the "connID" is part of this server's connections and their IDs are equal.

func (*Conn) IsClient Uses

func (c *Conn) IsClient() bool

IsClient method reports whether this connections is a client-side connetion.

func (*Conn) IsClosed Uses

func (c *Conn) IsClosed() bool

IsClosed method reports whether this connection is remotely or manually terminated.

func (*Conn) Namespace Uses

func (c *Conn) Namespace(namespace string) *NSConn

Namespace method returns an already-connected `NSConn` value based on the given "namespace".

func (*Conn) Server Uses

func (c *Conn) Server() *Server

Server method returns the backend server, it returns null on client-side connections.

func (*Conn) Set Uses

func (c *Conn) Set(key string, value interface{})

Set sets a value to this connection's store.

func (*Conn) Socket Uses

func (c *Conn) Socket() Socket

Socket method returns the underline socket implementation.

func (*Conn) String Uses

func (c *Conn) String() string

String method simply returns the ID(). Useful for fmt usage and to a connection to be passed on `Server#Broadcast` method to exclude itself from the broadcasted message's receivers.

func (*Conn) WaitConnect Uses

func (c *Conn) WaitConnect(ctx context.Context, namespace string) (ns *NSConn, err error)

WaitConnect method can be used instead of the `Connect` if the other side force-calls `Connect` to this connection and this side wants to "waits" for that signal.

Nil context means try without timeout, wait until it connects to the specific namespace. Note that, this function will not return an `ErrBadNamespace` if namespace does not exist in the server-side or it's not defined in the client-side, it waits until deadline (if any, or loop forever, so a context with deadline is highly recommended).

func (*Conn) WasReconnected Uses

func (c *Conn) WasReconnected() bool

WasReconnected reports whether the current connection is a result of a client-side reconnection. To get the numbers of total retries see the `ReconnectTries` field.

func (*Conn) Write Uses

func (c *Conn) Write(msg Message) bool

Write method sends a message to the remote side, reports whether the connection is still available or when this message is not allowed to be sent to the remote side.

type ConnHandler Uses

type ConnHandler interface {
    GetNamespaces() Namespaces
}

ConnHandler is the interface which namespaces and events can be retrieved through. Built-in ConnHandlers are the`Events`, `Namespaces`, `WithTimeout` and `NewStruct`. Users of this are the `Dial`(client) and `New` (server) functions.

func JoinConnHandlers Uses

func JoinConnHandlers(connHandlers ...ConnHandler) ConnHandler

JoinConnHandlers combines two or more "connHandlers" and returns a result of a single `ConnHandler` that can be passed on the `New` and `Dial` functions.

type Dialer Uses

type Dialer func(ctx context.Context, url string) (Socket, error)

Dialer is the definition type of a dialer, gorilla or gobwas or custom. It is the second parameter of the `Dial` function.

type EventMatcherFunc Uses

type EventMatcherFunc = func(methodName string) (string, bool)

EventMatcherFunc is a type of which a Struct matches the methods with neffos events.

type Events Uses

type Events map[string]MessageHandlerFunc

Events completes the `ConnHandler` interface. It is a map which its key is the event name and its value the event's callback.

Events type completes the `ConnHandler` itself therefore, can be used as standalone value on the `New` and `Dial` functions to register events on empty namespace as well.

See `Namespaces`, `New` and `Dial` too.

func (Events) GetNamespaces Uses

func (e Events) GetNamespaces() Namespaces

GetNamespaces returns an empty namespace with the "e" Events.

func (Events) On Uses

func (e Events) On(eventName string, msgHandler MessageHandlerFunc)

On is a shortcut of Events { eventName: msgHandler }. It registers a callback "msgHandler" for an event "eventName".

Code:

events := make(Events)
events.On(OnNamespaceConnected, nil)
events.On("chat", nil)

fmt.Println(len(events)) // we can't loop them and expect the same order ofc.

Output:

2

type IDGenerator Uses

type IDGenerator func(w http.ResponseWriter, r *http.Request) string

IDGenerator is the type of function that it is used to generate unique identifiers for new connections.

See `Server.IDGenerator`.

var DefaultIDGenerator IDGenerator = func(http.ResponseWriter, *http.Request) string {
    id, err := uuid.NewV4()
    if err != nil {
        return strconv.FormatInt(time.Now().Unix(), 10)
    }
    return id.String()
}

DefaultIDGenerator returns a universal unique identifier for a new connection. It's the default `IDGenerator` for `Server`.

type Message Uses

type Message struct {

    // The Namespace that this message sent to/received from.
    Namespace string
    // The Room that this message sent to/received from.
    Room string
    // The Event that this message sent to/received from.
    Event string
    // The actual body of the incoming/outcoming data.
    Body []byte
    // The Err contains any message's error, if any.
    // Note that server-side and client-side connections can return an error instead of a message from each event callbacks,
    // except the clients's force Disconnect which its local event doesn't matter when disconnected manually.
    Err error

    // When sent by the same connection of the current running server instance.
    // This field is serialized/deserialized but it's clean on sending or receiving from a client
    // and it's only used on StackExchange feature.
    // It's serialized as the first parameter, instead of wait signal, if incoming starts with 0x.
    FromExplicit string // the exact Conn's pointer in this server instance.
    // Reports whether this message is coming from a stackexchange.
    // This field is not exposed and it's not serialized at all, ~local-use only~.
    //
    // The "wait" field can determinate if this message is coming from a stackexchange using its second char,
    // This value set based on "wait" on deserialization when coming from remote side.
    // Only server-side can actually set it.
    FromStackExchange bool

    // To is the connection ID of the receiver, used only when `Server#Broadcast` is called, indeed when we only need to send a message to a single connection.
    // The Namespace, Room are still respected at all.
    //
    // However, sending messages to a group of connections is done by the `Room` field for groups inside a namespace or just `Namespace` field as usual.
    // This field is not filled on sending/receiving.
    To  string

    // True when event came from local (i.e client if running client) on force disconnection,
    // i.e OnNamespaceDisconnect and OnRoomLeave when closing a conn.
    // This field is not filled on sending/receiving.
    // Err does not matter and never sent to the other side.
    IsForced bool
    // True when asking the other side and fire the respond's event (which matches the sent for connect/disconnect/join/leave),
    // i.e if a client (or server) onnection want to connect
    // to a namespace or join to a room.
    // Should be used rarely, state can be checked by `Conn#IsClient() bool`.
    // This field is not filled on sending/receiving.
    IsLocal bool

    // True when user define it for writing, only its body is written as raw native websocket message, namespace, event and all other fields are empty.
    // The receiver should accept it on the `OnNativeMessage` event.
    // This field is not filled on sending/receiving.
    IsNative bool

    // if server or client should write using Binary message.
    // This field is not filled on sending/receiving.
    SetBinary bool
    // contains filtered or unexported fields
}

The Message is the structure which describes the incoming and outcoming data. Emitter's "body" argument is the `Message.Body` field. Emitter's return non-nil error is the `Message.Err` field. If native message sent then the `Message.Body` is filled with the body and when incoming native message then the `Message.Event` is the `OnNativeMessage`, native messages are allowed only when an empty namespace("") and its `OnNativeMessage` callback are present.

The the raw data received/sent structured following this order: <wait()>; <namespace>; <room>; <event>; <isError(0-1)>; <isNoOp(0-1)>; <body||error_message>

Internal `serializeMessage` and exported `DeserializeMessage` functions do the job on `Conn#Write`, `NSConn#Emit` and `Room#Emit` calls.

func DeserializeMessage Uses

func DeserializeMessage(decrypt MessageDecrypt, b []byte, allowNativeMessages, shouldHandleOnlyNativeMessages bool) Message

DeserializeMessage accepts a serialized message []byte and returns a neffos Message. When allowNativeMessages only Body is filled and check about message format is skipped.

func (*Message) ClearWait Uses

func (m *Message) ClearWait() bool

ClearWait clears the wait token, rarely used.

func (*Message) IsWait Uses

func (m *Message) IsWait(isClientConn bool) bool

IsWait reports whether this message waits for a response back.

func (Message) Serialize Uses

func (m Message) Serialize() []byte

Serialize returns this message's transport format.

func (*Message) Unmarshal Uses

func (m *Message) Unmarshal(outPtr interface{}) error

Unmarshal unmarshals this Message's body to the "outPtr". The "outPtr" must be a pointer to a value that can customize its decoded value by implementing the `MessageObjectUnmarshaler`, otherwise the `DefaultUnmarshaler` will be used instead.

type MessageDecrypt Uses

type MessageDecrypt func(in []byte) []byte

MessageDecrypt type kept for future use when deserializing a message.

type MessageEncrypt Uses

type MessageEncrypt func(out []byte) []byte

MessageEncrypt type kept for future use when serializing a message.

type MessageHandlerFunc Uses

type MessageHandlerFunc func(*NSConn, Message) error

MessageHandlerFunc is the definition type of the events' callback. Its error can be written to the other side on specific events, i.e on `OnNamespaceConnect` it will abort a remote namespace connection. See examples for more.

type MessageObjectMarshaler Uses

type MessageObjectMarshaler interface {
    Marshal() ([]byte, error)
}

MessageObjectMarshaler is an optional interface that "objects" can implement to customize their byte representation, see `Object` package-level function.

type MessageObjectUnmarshaler Uses

type MessageObjectUnmarshaler interface {
    Unmarshal(body []byte) error
}

MessageObjectUnmarshaler is an optional interface that "objects" can implement to customize their structure, see `Message.Object` method.

type NSConn Uses

type NSConn struct {
    Conn *Conn
    // contains filtered or unexported fields
}

NSConn describes a connection connected to a specific namespace, it emits with the `Message.Namespace` filled and it can join to multiple rooms. A single `Conn` can be connected to one or more namespaces, each connected namespace is described by this structure.

func (*NSConn) Ask Uses

func (ns *NSConn) Ask(ctx context.Context, event string, body []byte) (Message, error)

Ask method writes a message to the remote side and blocks until a response or an error received.

func (*NSConn) Disconnect Uses

func (ns *NSConn) Disconnect(ctx context.Context) error

Disconnect method sends a disconnect signal to the remote side and fires the local `OnNamespaceDisconnect` event.

func (*NSConn) Emit Uses

func (ns *NSConn) Emit(event string, body []byte) bool

Emit method sends a message to the remote side with its `Message.Namespace` filled to this specific namespace.

func (*NSConn) JoinRoom Uses

func (ns *NSConn) JoinRoom(ctx context.Context, roomName string) (*Room, error)

JoinRoom method can be used to join a connection to a specific room, rooms are dynamic. Returns the joined `Room`.

func (*NSConn) LeaveAll Uses

func (ns *NSConn) LeaveAll(ctx context.Context) error

LeaveAll method sends a remote and local leave room signal `OnRoomLeave` to and for all rooms and fires the `OnRoomLeft` event if succeed.

func (*NSConn) Room Uses

func (ns *NSConn) Room(roomName string) *Room

Room method returns a joined `Room`.

func (*NSConn) Rooms Uses

func (ns *NSConn) Rooms() []*Room

Rooms returns a slice copy of the joined rooms.

func (*NSConn) String Uses

func (ns *NSConn) String() string

String method simply returns the Conn's ID(). Useful method to this connected to a namespace connection to be passed on `Server#Broadcast` method to exclude itself from the broadcasted message's receivers.

type Namespaces Uses

type Namespaces map[string]Events

Namespaces completes the `ConnHandler` interface. Can be used to register one or more namespaces on the `New` and `Dial` functions. The key is the namespace literal and the value is the `Events`, a map with event names and their callbacks.

See `WithTimeout`, `New` and `Dial` too.

func (Namespaces) GetNamespaces Uses

func (nss Namespaces) GetNamespaces() Namespaces

GetNamespaces just returns the "nss" namespaces.

func (Namespaces) On Uses

func (nss Namespaces) On(namespace, eventName string, msgHandler MessageHandlerFunc) Events

On is a shortcut of Namespaces { namespace: Events: { eventName: msgHandler } }. It registers a callback "msgHandler" for an event "eventName" of the particular "namespace".

Code:

nss := make(Namespaces)
nss.On("default", OnNamespaceConnected, nil).
    On("chat", nil) // registers on "default"

nss.On("other", "chat", nil)
nss.On("other", "event", nil)

fmt.Println(len(nss))

Output:

2

type Room Uses

type Room struct {
    NSConn *NSConn

    Name string
}

Room describes a connected connection to a room, emits messages with the `Message.Room` filled to the specific room and `Message.Namespace` to the underline `NSConn`'s namespace.

func (*Room) Emit Uses

func (r *Room) Emit(event string, body []byte) bool

Emit method sends a message to the remote side with its `Message.Room` filled to this specific room and `Message.Namespace` to the underline `NSConn`'s namespace.

func (*Room) Leave Uses

func (r *Room) Leave(ctx context.Context) error

Leave method sends a remote and local leave room signal `OnRoomLeave` to this specific room and fires the `OnRoomLeft` event if succeed.

func (*Room) String Uses

func (r *Room) String() string

String method simply returns the Conn's ID(). To get the room's name simply use the `Room.Name` struct field instead. Useful method to this room to be passed on `Server#Broadcast` method to exclude itself from the broadcasted message's receivers.

type Server Uses

type Server struct {
    IDGenerator   IDGenerator
    StackExchange StackExchange

    // If `StackExchange` is set then this field is ignored.
    //
    // It overrides the default behavior(when no StackExchange is not used)
    // which publishes a message independently.
    // In short the default behavior doesn't wait for a message to be published to all clients
    // before any next broadcast call.
    //
    // Therefore, if set to true,
    // each broadcast call will publish its own message(s) by order.
    SyncBroadcaster bool

    // OnUpgradeError can be optionally registered to catch upgrade errors.
    OnUpgradeError func(err error)
    // OnConnect can be optionally registered to be notified for any new neffos client connection,
    // it can be used to force-connect a client to a specific namespace(s) or to send data immediately or
    // even to cancel a client connection and dissalow its connection when its return error value is not nil.
    // Don't confuse it with the `OnNamespaceConnect`, this callback is for the entire client side connection.
    OnConnect func(c *Conn) error
    // OnDisconnect can be optionally registered to notify about a connection's disconnect.
    // Don't confuse it with the `OnNamespaceDisconnect`, this callback is for the entire client side connection.
    OnDisconnect func(c *Conn)
    // contains filtered or unexported fields
}

Server is the neffos server. Keeps the `IDGenerator` which can be customized, by default it's the `DefaultIDGenerator` which generates connections unique identifiers using the uuid/v4.

Callers can optionally register callbacks for connection, disconnection and errored. Its most important methods are `ServeHTTP` which is used to register the server on a specific endpoint and `Broadcast` and `Close`. Use the `New` function to create a new server, server starts automatically, no further action is required.

func New Uses

func New(upgrader Upgrader, connHandler ConnHandler) *Server

New constructs and returns a new neffos server. Listens to incoming connections automatically, no further action is required from the caller. The second parameter is the "connHandler", it can be filled as `Namespaces`, `Events` or `WithTimeout`, same namespaces and events can be used on the client-side as well, Use the `Conn#IsClient` on any event callback to determinate if it's a client-side connection or a server-side one.

See examples for more.

func (*Server) Ask Uses

func (s *Server) Ask(ctx context.Context, msg Message) (Message, error)

Ask is like `Broadcast` but it blocks until a response from a specific connection if "msg.To" is filled otherwise from the first connection which will reply to this "msg".

Accepts a context for deadline as its first input argument. The second argument is the request message which should be sent to a specific namespace:event like the `Conn.Ask`.

func (*Server) Broadcast Uses

func (s *Server) Broadcast(exceptSender fmt.Stringer, msgs ...Message)

Broadcast method is fast and does not block any new incoming connection by-default, it can be used as frequently as needed. Use the "msg"'s Namespace, or/and Event or/and Room to broadcast to a specific type of connection collectives.

If first "exceptSender" parameter is not nil then the message "msg" will be broadcasted to all connected clients except the given connection's ID, any value that completes the `fmt.Stringer` interface is valid. Keep note that `Conn`, `NSConn`, `Room` and `Exclude(connID) global function` are valid values.

Example Code: nsConn.Conn.Server().Broadcast(

	nsConn OR nil,
 neffos.Message{Namespace: "default", Room: "roomName or empty", Event: "chat", Body: [...]})

Note that it if `StackExchange` is nil then its default behavior doesn't wait for a publish to complete to all clients before any next broadcast call. To change that behavior set the `Server.SyncBroadcaster` to true before server start.

func (*Server) Close Uses

func (s *Server) Close()

Close terminates the server and all of its connections, client connections are getting notified.

func (*Server) Do Uses

func (s *Server) Do(fn func(*Conn), async bool)

Do loops through all connected connections and fires the "fn", with this method callers can do whatever they want on a connection outside of a event's callback, but make sure that these operations are not taking long time to complete because it delays the new incoming connections. If "async" is true then this method does not block the flow of the program.

func (*Server) GetConnections Uses

func (s *Server) GetConnections() map[string]*Conn

GetConnections can be used as an alternative way to retrieve all connected connections to the server on a specific time point. Do not use this function frequently, it is not designed to be fast or cheap, use it for debugging or logging every 'x' time.

Not thread safe.

func (*Server) GetConnectionsByNamespace Uses

func (s *Server) GetConnectionsByNamespace(namespace string) map[string]*NSConn

GetConnectionsByNamespace can be used as an alternative way to retrieve all connected connections to a specific "namespace" on a specific time point. Do not use this function frequently, it is not designed to be fast or cheap, use it for debugging or logging every 'x' time. Users should work with the event's callbacks alone, the usability is enough for all type of operations. See `Do` too.

Not thread safe.

func (*Server) GetTotalConnections Uses

func (s *Server) GetTotalConnections() uint64

GetTotalConnections returns the total amount of the connected connections to the server, it's fast and can be used as frequently as needed.

func (*Server) ServeHTTP Uses

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP completes the `http.Handler` interface, it should be passed on a http server's router to serve this neffos server on a specific endpoint.

func (*Server) Upgrade Uses

func (s *Server) Upgrade(
    w http.ResponseWriter,
    r *http.Request,
    socketWrapper func(Socket) Socket,
    customIDGen IDGenerator,
) (*Conn, error)

Upgrade handles the connection, same as `ServeHTTP` but it can accept a socket wrapper and a "customIDGen" that overrides the server's IDGenerator and it does return the connection or any errors.

func (*Server) UseStackExchange Uses

func (s *Server) UseStackExchange(exc StackExchange) error

UseStackExchange can be used to add one or more StackExchange to the server. Returns a non-nil error when "exc" completes the `StackExchangeInitializer` interface and its `Init` failed.

Read more at the `StackExchange` type's docs.

type Socket Uses

type Socket interface {
    // NetConn returns the underline net connection.
    NetConn() net.Conn
    // Request returns the http request value.
    Request() *http.Request
    // ReadData reads binary or text messages from the remote connection.
    ReadData(timeout time.Duration) (body []byte, err error)
    // WriteBinary sends a binary message to the remote connection.
    WriteBinary(body []byte, timeout time.Duration) error
    // WriteText sends a text message to the remote connection.
    WriteText(body []byte, timeout time.Duration) error
}

Socket is the interface that an underline protocol implementation should implement.

type StackExchange Uses

type StackExchange interface {
    // OnConnect should prepare the connection's subscriber.
    // It's called automatically after the neffos server's OnConnect (if any)
    // on incoming client connections.
    OnConnect(c *Conn) error
    // OnDisconnect should close the connection's subscriber that
    // created on the `OnConnect` method.
    // It's called automatically when a connection goes offline,
    // manually by server or client or by network failure.
    OnDisconnect(c *Conn)

    // Publish should publish messages through a stackexchange.
    // It's called automatically on neffos broadcasting.
    Publish(msgs []Message) bool
    // Subscribe should subscribe to a specific namespace,
    // it's called automatically on neffos namespace connected.
    Subscribe(c *Conn, namespace string)
    // Unsubscribe should unsubscribe from a specific namespace,
    // it's called automatically on neffos namespace disconnect.
    Unsubscribe(c *Conn, namespace string) // should close the subscriber.
    // Ask should be able to perform a server Ask to a specific client or to all clients
    // It blocks until response from a specific client if msg.To is filled,
    // otherwise will return on the first responder's reply.
    Ask(ctx context.Context, msg Message, token string) (Message, error)
    // NotifyAsk should notify and unblock a subscribed connection for this
    // specific message, "token" is the neffos wait signal for this message.
    NotifyAsk(msg Message, token string) error
}

StackExchange is an optional interface that can be used to change the way neffos sends messages to its clients, i.e communication between multiple neffos servers.

See the "kataras/neffos/stackexchange" subpackage for more details. Real-World example and usage documentation can be found at: "kataras/neffos/_examples/redis".

type StackExchangeInitializer Uses

type StackExchangeInitializer interface {
    // Init should initialize a stackexchange, it's optional.
    Init(Namespaces) error
}

StackExchangeInitializer is an optional interface for a `StackExchange`. It contains a single `Init` method which accepts the registered server namespaces and returns error. It does not called on manual `Server.StackExchange` field set, use the `Server.UseStackExchange` to make sure that this implementation is respected.

type Struct Uses

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

Struct is a ConnHandler. All fields are unexported, use `NewStruct` instead. It converts any pointer to a struct value to `neffos.Namespaces` using reflection.

func NewStruct Uses

func NewStruct(ptr interface{}) *Struct

NewStruct returns a new Struct value instance type of ConnHandler. The "ptr" should be a pointer to a struct. This function is used when you want to convert a structure to neffos.ConnHandler based on the struct's methods. The methods if "ptr" structure value can be func(msg neffos.Message) error if the structure contains a *neffos.NSConn field, otherwise they should be like any event callback: func(nsConn *neffos.NSConn, msg neffos.Message) error. If contains a field of type *neffos.NSConn then on each new connection to the namespace a new controller is created and static fields(if any) are set on runtime with the NSConn itself. If it's a static controller (does not contain a NSConn field) then it just registers its functions as regular events without performance cost.

Users of this method is `New` and `Dial`.

Note that this method has a tiny performance cost when an event's callback's logic has small footprint.

func (*Struct) Events Uses

func (s *Struct) Events() Events

Events builds and returns the Events. Callers of this method is users that want to add Structs to different namespaces in the same application. When a single namespace is used then this call is unnecessary, the `Struct` is already a fully featured `ConnHandler` by itself.

func (*Struct) GetNamespaces Uses

func (s *Struct) GetNamespaces() Namespaces

GetNamespaces creates and returns Namespaces based on the pointer to struct value provided by the "s".

func (*Struct) SetEventMatcher Uses

func (s *Struct) SetEventMatcher(matcher EventMatcherFunc) *Struct

SetEventMatcher sets an event method matcher which applies to every event except the system events (OnNamespaceConnected, and so on).

func (*Struct) SetInjector Uses

func (s *Struct) SetInjector(fn StructInjector) *Struct

SetInjector sets a custom injector and overrides the neffos default behavior on dynamic structs. The "fn" should handle to fill static fields and the NSConn. This "fn" will only be called when dynamic struct "ptr" is passed on the `NewStruct`. The caller should return a valid type of "ptr" reflect.Value.

func (*Struct) SetNamespace Uses

func (s *Struct) SetNamespace(namespace string) *Struct

SetNamespace sets a namespace that this Struct is responsible for, Alterinatively create a method on the controller named `Namespace() string` to retrieve this namespace at build time.

func (*Struct) SetTimeouts Uses

func (s *Struct) SetTimeouts(read, write time.Duration) *Struct

SetTimeouts sets read and write deadlines on the underlying network connection. After a read or write have timed out, the websocket connection is closed.

Defaults to 0, no timeout except an `Upgrader` or `Dialer` specifies its own values.

type StructInjector Uses

type StructInjector func(structType reflect.Type, nsConn *NSConn) (structValue reflect.Value)

StructInjector is a type which injects a dynamic struct value. See `Struct.SetInjector` for more.

type Upgrader Uses

type Upgrader func(w http.ResponseWriter, r *http.Request) (Socket, error)

Upgrader is the definition type of a protocol upgrader, gorilla or gobwas or custom. It is the first parameter of the `New` function which constructs a neffos server.

type WithTimeout Uses

type WithTimeout struct {
    ReadTimeout  time.Duration
    WriteTimeout time.Duration

    Namespaces Namespaces
    Events     Events
}

WithTimeout completes the `ConnHandler` interface. Can be used to register namespaces and events or just events on an empty namespace with Read and Write timeouts.

See `New` and `Dial`.

func (WithTimeout) GetNamespaces Uses

func (t WithTimeout) GetNamespaces() Namespaces

GetNamespaces returns combined namespaces from "Namespaces" and "Events" fields with read and write timeouts from "ReadTimeout" and "WriteTimeout" fields of "t".

Directories

PathSynopsis
gobwas
gorilla
stackexchange/nats
stackexchange/redis

Package neffos imports 18 packages (graph) and is imported by 8 packages. Updated 2019-10-17. Refresh now. Tools for package owners.