Categorygithub.com/kpeu3i/wspubsub
modulepackage
1.0.0
Repository: https://github.com/kpeu3i/wspubsub.git
Documentation: pkg.go.dev

# README

WSPubSub

CircleCI Build Status Coverage Status GoDoc MIT Licensed

WSPubSub library is a Go implementation of channels based pub/sub pattern over WebSocket protocol.

This library completely hides interaction with the transport layer like: connection upgrading, disconnecting, ping/pong etc. Thanks to this, you can focus only on your tasks.

Client interaction with the library mainly occurs through the hub API. The only two steps to publish messages are required:

  • Register receive handler using hub.OnReceive
  • Subscribe clients using hub.Subscribe

Now you are ready to publish messages to different channels using hub.Publish. Users who have been subscribed to those channels will receive the messages!

Install

Use go get to install the latest version of the library:

go get github.com/kpeu3i/wspubsub

Next, include wspubsub in your application:

import "github.com/kpeu3i/wspubsub"

Usage

A minimal working example is listed below:

package main

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/kpeu3i/wspubsub"
	"github.com/pkg/errors"
)

type Message struct {
	Command  string   `json:"command"`
	Channels []string `json:"channels"`
}

func main() {
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	channels := []string{"general", "public", "private"}
	messageFormat := `{"now": %d}`

	hub := wspubsub.NewDefaultHub()
	defer hub.Close()

	publishTicker := time.NewTicker(1 * time.Second)
	defer publishTicker.Stop()

	hub.OnReceive(func(clientID wspubsub.UUID, message wspubsub.Message) {
		m := Message{}
		err := json.Unmarshal(message.Payload, &m)
		if err != nil {
			hub.LogError(errors.Wrap(err, "hub.on_receive.unmarshal"))
			return
		}

		switch m.Command {
		case "SUBSCRIBE":
			err := hub.Subscribe(clientID, m.Channels...)
			if err != nil {
				hub.LogError(errors.Wrap(err, "hub.on_receive.subscribe"))
			}
		case "UNSUBSCRIBE":
			err := hub.Unsubscribe(clientID, m.Channels...)
			if err != nil {
				hub.LogError(errors.Wrap(err, "hub.on_receive.unsubscribe"))
			}
		}
	})

	go func() {
		err := hub.ListenAndServe("localhost:8080", "/")
		if err != nil {
			hub.LogPanic(err)
		}
	}()

	go func() {
		for range publishTicker.C {
			// Pick a random channel
			channel := channels[rand.Intn(len(channels))]
			message := wspubsub.NewTextMessageFromString(fmt.Sprintf(messageFormat, time.Now().Unix()))
			_, err := hub.Publish(message, channel)
			if err != nil {
				hub.LogPanic(err)
			}

			hub.LogInfof("Published: channel=%s, message=%s\n", channel, string(message.Payload))
		}
	}()

	<-quit
}

More examples you can find in examples directory.

Lint and test

First, you need to install project dependencies (golangci, mockgen, etc):

$ make deps-install

Now, you are able to run:

$ make lint
$ make test

If it required to update mocks use the following command:

$ make mocks-generate

Contributing

Please don't hesitate to fork the project and send a pull request me to ask questions and share ideas.

  1. Fork it
  2. Download the fork (git clone https://github.com/kpeu3i/wspubsub.git && cd wspubsub)
  3. Create your feature branch (git checkout -b my-new-feature)
  4. Make changes and add them (git add .)
  5. Commit your changes (git commit -m 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new pull request

License

This library is released under the MIT license. See the LICENSE file for details.

# Packages

No description provided by the author
Package mock is a generated GoMock package.

# Functions

IsClientConnectError checks if error type is ClientConnectError.
IsClientNotFoundError checks if error type is ClientNotFoundError.
IsClientPingError checks if error type is ClientPingError.
IsClientReceiveError checks if error type is ClientReceiveError.
IsClientRepeatConnectError checks if error type is ClientRepeatConnectError.
IsClientSendBufferOverflowError checks if error type is ClientSendBufferOverflowError.
IsClientSendError checks if error type is ClientSendError.
IsConnectionClosedError checks if error type is ConnectionClosedError.
IsHubSubscriptionChannelRequiredError checks if error type is HubSubscriptionChannelRequired.
NewBinaryMessage initializes a new binary Message from bytes.
NewBinaryMessageFromString initializes a new binary Message from string.
NewClient initializes a new Client.
NewClientConnectError initializes a new ClientConnectError.
NewClientFactory initializes a new ClientFactory.
NewClientNotFoundError initializes a new ClientNotFoundError.
NewClientOptions initializes a new ClientOptions.
NewClientPingError initializes a new ClientPingError.
NewClientReceiveError initializes a new ClientReceiveError.
NewClientRepeatConnectError initializes a new ClientRepeatConnectError.
NewClientSendBufferOverflowError initializes a new ClientSendBufferOverflowError.
NewClientSendError initializes a new ClientSendError.
NewClientStore initializes a new ClientStore.
NewClientStoreOptions initializes a new ClientStoreOptions.
NewConnectionClosedError initializes a new ConnectionClosedError.
NewDefaultHub uses default dependencies to initializes a new hub.
NewGobwasConnectionUpgrader initializes a new GobwasConnectionUpgrader.
NewGobwasUpgraderOptions initializes a new GobwasConnectionUpgraderOptions.
NewGorillaConnectionUpgrader initializes a new GorillaConnectionUpgrader.
NewGorillaConnectionUpgraderOptions initializes a new GorillaConnectionUpgraderOptions.
NewHub initializes a new Hub.
NewHubOptions initializes a new HubOptions.
NewHubSubscriptionChannelRequiredError initializes a new HubSubscriptionChannelRequired.
NewLogrusLogger initializes a new LogrusLogger.
NewLogrusLoggerOptions initializes a new LogrusLoggerOptions.
NewPingMessage initializes a new ping Message.
NewTextMessage initializes a new text Message from bytes.
NewTextMessage initializes a new text Message from string.

# Constants

LogrusFormatterJSON formats logs into parsable JSON.
LogrusFormatterText formats logs into text.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

Client represents a connection to the WebSocket server.
ClientConnectError returned when HTTP connection can't be upgraded to WebSocket connection.
ClientFactory is responsible for creating a client.
ClientNotFoundError returned when client is not present in a storage.
ClientOptions represents configuration of the client.
ClientPingError returned when ping message can't be written to a WebSocket connection.
ClientReceiveError returned when message can't be read from a WebSocket connection.
ClientRepeatConnectError returned when trying to connect an already connected client.
ClientSendBufferOverflowError returned when client send buffer is full.
ClientSendError returned when a message (text or binary) can't be written to a WebSocket connection.
ClientStore represents the storage of clients.
ClientStoreOptions represents configuration of the storage.
ConnectionClosedError returned when trying to read or write to closed WebSocket connection.
GobwasConnection is an implementation of WebsocketConnection.
GobwasConnectionUpgrader is an implementation of WebsocketConnectionUpgrader.
GobwasConnectionUpgraderOptions represents configuration of the GobwasConnectionUpgrader.
GorillaConnection is an implementation of WebsocketConnection.
GorillaConnectionUpgrader is an implementation of WebsocketConnectionUpgrader.
GorillaConnectionUpgraderOptions represents configuration of the GorillaConnectionUpgrader.
Hub manages client connections.
HubOptions represents configuration of the hub.
HubSubscriptionChannelRequired returned when trying to subscribe with an empty channels list.
LogrusLogger is an implementation of Logger.
LogrusLoggerOptions represents configuration of the LogrusLogger.
Message represents a data type to send over a WebSocket connection.
SatoriUUIDGenerator is an implementation of UUIDGenerator.

# Interfaces

Logger is an interface representing the ability to log messages.
UUIDGenerator generates UUID v4.
WebsocketClient is an interface representing the ability to interact with WebSocket connection.
WebsocketClientStore is an interface responsible for creating a client.
WebsocketClientStore is an interface responsible for storing and finding the users.
WebsocketConnection represents a WebSocket connection.
WebsocketConnectionUpgrader upgrades HTTP connection to the WebSocket connection.

# Type aliases

No description provided by the author
No description provided by the author
No description provided by the author
IterateFunc is the type of the function called for each client visited by Find.
LogrusFormatter enumerates possible formatters.
LogrusLevel enumerates possible logging levels.
MessageType enumerates possible message types.
No description provided by the author
UUID represents a type compliant with specification described in RFC 4122.