signalr

package module
v2.0.0-beta-3 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2020 License: MIT Imports: 15 Imported by: 6

README

PkgGoDev

Overview

This is my personal attempt at implementating the client side of the WebSocket portion of the SignalR protocol. I use it for various virtual currency trading platforms that use SignalR.

Examples

Simple example:

package main

import (
	"log"

	"github.com/rainhq/signalr/v2"
)

func main() {
	ctx := context.Background()

	// Prepare a SignalR client.
	c, err := signalr.Dial(
		ctx,
		"https://fake-server.definitely-not-real/signalr",
		`[{"name":"awesomehub"}]`,
	)
	if err != nil {
		log.Fatal(err)
	}

	var msg signalr.Message
	for {
		if err := c.ReadMessage(ctx, &msg); err != nil {
			log.Fatal(err)
		}

		log.Println(msg)
	}
}

Generic usage:

Cryptocurrency examples:

Proxy examples:

Documentation

Contribute

If anything is unclear or could be improved, please open an issue or submit a pull request. Thanks!

Documentation

Overview

Package signalr provides the client side implementation of the WebSocket portion of the SignalR protocol.

First things first: this was almost entirely written using https://blog.3d-logic.com/2015/03/29/signalr-on-the-wire-an-informal-description-of-the-signalr-protocol/ as a reference guide. It is an excellent technical write-up. Many thanks to Pawel Kadluczka for writing that and sharing it with the public. If you want deep-dive technical details of how this all works, read that blog. I won't try to replicate it here.

At a high level, the WebSocket portion of SignalR goes through the following steps:

  • negotiate: use HTTP/HTTPS to get connection info for how to connect to the websocket endpoint
  • connect: attempt to connect to the websocket endpoint
  • start: make the WebSocket connection usable by SignalR connections

See the provided examples for how to use this library.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsCloseError added in v2.3.0

func IsCloseError(err error, codes ...int) bool

Types

type Client

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

Client represents a SignlR client. It manages connections so that the caller doesn't have to.

func Dial

func Dial(ctx context.Context, endpoint, cdata string, opts ...Opt) (*Client, error)

Dial connects to Signalr endpoint

func (*Client) Close

func (c *Client) Close() error

Close closes underlying websocket connection

func (*Client) ReadMessage

func (c *Client) ReadMessage(ctx context.Context, msg *Message) error

ReadMessage reads single message from websocket

func (*Client) State

func (c *Client) State() *State

func (*Client) WriteMessage

func (c *Client) WriteMessage(ctx context.Context, msg ClientMsg) error

Send sends a message to the websocket connection.

type ClientMsg

type ClientMsg struct {
	// invocation identifier – allows to match up responses with requests
	I int

	// the name of the hub
	H string

	// the name of the method
	M string

	// arguments (an array, can be empty if the method does not have any
	// parameters)
	A []json.RawMessage

	// state – a dictionary containing additional custom data (optional)
	S *json.RawMessage `json:",omitempty"`
}

ClientMsg represents a message sent to the Hubs API from the client.

type CloseError added in v2.3.0

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

func (*CloseError) Error added in v2.3.0

func (e *CloseError) Error() string

type ConnectError

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

func (*ConnectError) Error

func (e *ConnectError) Error() string

func (*ConnectError) Unwrap

func (e *ConnectError) Unwrap() error

type DialError

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

func (*DialError) Error

func (e *DialError) Error() string

func (*DialError) Unwrap

func (e *DialError) Unwrap() error

type InvalidInitMessageError

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

func (*InvalidInitMessageError) Error

func (e *InvalidInitMessageError) Error() string

type InvalidStartResponseError

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

func (*InvalidStartResponseError) Error

func (e *InvalidStartResponseError) Error() string

type Message

type Message struct {
	// message id, present for all non-KeepAlive messages
	C string

	// an array containing actual data
	M []ClientMsg

	// indicates that the transport was initialized (a.k.a. init message)
	S int

	// groups token – an encrypted string representing group membership
	G string

	// other miscellaneous variables that sometimes are sent by the server
	I int `json:"I,string"`
	E string
	R json.RawMessage
	H json.RawMessage // could be bool or string depending on a message type
	D json.RawMessage
	T json.RawMessage
}

Message represents a message sent from the server to the persistent websocket connection.

type NegotiateError

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

func (*NegotiateError) Error

func (e *NegotiateError) Error() string

func (*NegotiateError) Unwrap

func (e *NegotiateError) Unwrap() error

type Opt

type Opt func(*config)

func Dialer

func Dialer(dialer WebsocketDialerFunc) Opt

func HTTPClient

func HTTPClient(client *http.Client) Opt

func Headers

func Headers(headers http.Header) Opt

func MaxConnectRetries

func MaxConnectRetries(retries int) Opt

The maximum number of times to re-attempt a connection.

func MaxNegotiateRetries

func MaxNegotiateRetries(retries int) Opt

The maximum number of times to re-attempt a negotiation.

func MaxReconnectDuration

func MaxReconnectDuration(duration time.Duration) Opt

The maximum amount of time to spend retrying a reconnect attempt.

func MaxReconnectRetries added in v2.3.0

func MaxReconnectRetries(retries int) Opt

func MaxStartRetries

func MaxStartRetries(retries int) Opt

The maximum number of times to re-attempt a start command.

func Params

func Params(params url.Values) Opt

func Protocol

func Protocol(protocol string) Opt

func RetryInterval added in v2.3.0

func RetryInterval(interval time.Duration) Opt

The time to wait before retrying, in the event that an error occurs when contacting the SignalR service.

type ProxyFunc

type ProxyFunc func(req *http.Request) (*url.URL, error)

type ReadError

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

func (*ReadError) Error

func (e *ReadError) Error() string

func (*ReadError) Unwrap

func (e *ReadError) Unwrap() error

type ServerMsg

type ServerMsg struct {
	// invocation Id (always present)
	I int

	// the value returned by the server method (present if the method is not
	// void)
	R *json.RawMessage `json:",omitempty"`

	// error message
	E *string `json:",omitempty"`

	// true if this is a hub error
	H *bool `json:",omitempty"`

	// an object containing additional error data (can only be present for
	// hub errors)
	D *json.RawMessage `json:",omitempty"`

	// stack trace (if detailed error reporting (i.e. the
	// HubConfiguration.EnableDetailedErrors property) is turned on on the
	// server)
	T *json.RawMessage `json:",omitempty"`

	// state – a dictionary containing additional custom data (optional)
	S *json.RawMessage `json:",omitempty"`
}

ServerMsg represents a message sent to the Hubs API from the server.

type StartError

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

func (*StartError) Error

func (e *StartError) Error() string

func (*StartError) Unwrap

func (e *StartError) Unwrap() error

type State

type State struct {
	ConnectionData  string
	ConnectionID    string
	ConnectionToken string
	GroupsToken     string
	MessageID       string
	Protocol        string
}

type WebsocketConn

type WebsocketConn interface {
	ReadMessage(ctx context.Context) (messageType int, p []byte, err error)
	WriteMessage(ctx context.Context, messageType int, p []byte) error
	Close() error
}

WebsocketConn is a combination of MessageReader and JSONWriter. It is used to provide an interface to objects that can read from and write to a websocket connection.

type WebsocketDialer

type WebsocketDialer interface {
	Dial(ctx context.Context, u string, headers http.Header) (conn WebsocketConn, status int, err error)
}

func NewDefaultDialer added in v2.3.0

func NewDefaultDialer(client *http.Client) WebsocketDialer

type WebsocketDialerFunc

type WebsocketDialerFunc func(client *http.Client) WebsocketDialer

type WriteError

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

func (*WriteError) Error

func (e *WriteError) Error() string

func (*WriteError) Unwrap

func (e *WriteError) Unwrap() error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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