gows

package module
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2025 License: CC-BY-4.0 Imports: 17 Imported by: 0

README ΒΆ

Go-WS: A High-Level WebSocket Library for Go

Go-WS is a wrapper built around Gorilla WebSocket, designed to simplify and accelerate WebSocket communication for both server and client implementations in Go.
It introduces high-level event emitters, request-response abstractions, and message parsing logic, making it ideal for building scalable real-time applications.

Features

  • Easy WebSocket server and client setup
  • Event-driven architecture (connection, disconnection, errors, messages)
  • Request-response pattern built-in
  • Custom message parsing and typed handler registration
  • Graceful connection handling with ID assignment
  • Thread-safe message sending
  • TLS certificate support (generate/load/save)
  • Reconnectable clients

Installation

go get github.com/GTedZ/gows

Getting Started

1. Setting Up a WebSocket Server
server := gows.NewServer("0.0.0.0", "/ws")
err := server.ListenAndServe(3000)
if err != nil {
    fmt.Println("ListenAndServe error", err.Error())
}

2. Configuring Origin Check (optional)
server.SetCheckOrigin(
    func(r *http.Request) bool {
        return true // Allow all origins
    },
)
Or just allow all (default):
server.SetCheckOrigin(nil)

3. Handling Events
server.OnConnect = func(conn *gows.Connection) {
    fmt.Println("New client connected")
}

server.OnClose = func(conn *gows.Connection, code int, reason string) {
    fmt.Println("Client disconnected:", reason)
}

4. Connection-Level Metadata (Custom Key-Value Store)

Each connection holds a thread-safe key-value store:

conn.SetString("username", "alice")
user, exists := conn.GetString("username")

5. Sending Text or JSON Messages
conn.SendText("Hello Client!")

conn.SendJSON(struct {
    Event string
    Data  string
}{
    Event: "greeting",
    Data:  "Hello!",
})

Websocket Client

1. Connecting to a Server
client, err := gows.NewClient("ws://localhost:3000/ws")
if err != nil {
    panic(err)
}

2. Receiving Messages
client.OnMessage = func(messageType int, msg []byte) {
    fmt.Println("Received:", string(msg))
}

3. πŸ”„ Request-Response Pattern
// Client
req := map[string]interface{}{"method": "ping"}
resp, timedOut, err := client.SendPrivateMessage(req)
// Server
conn.OnRequest = func(msg []byte, req *gows.ResponseHandler) {
    res := map[string]interface{}{"reply": "pong"}
    req.Reply(res)
}
  • Both client and server can initiate requests.
  • Uses a private field like "id" to match requests/responses.
  • Customize this field name using SetRequestIdPropertyName().

4. 🧠 Message Parsers (Core Feature)

Typed dispatching of messages using JSON structure matching:

Example Type
type Candlestick struct {
    Timestamp int64
    Open      float64
    High      float64
    Low       float64
    Close     float64
    Volume    float64
}
Registering a Parser on Client or Server
gows.RegisterMessageParserCallback(
    client.GetParserRegistry(),

    func(b []byte) (bool, *Candlestick) {   // Parser function, make sure to be overly explicit, a <nil> error from Unmarshal isn't enough
        var c Candlestick
        err := json.Unmarshal(b, &c)
        return err == nil && c.Timestamp > 0, &c
    },

    func(c *Candlestick) {                  // Callback
        fmt.Println("Parsed candlestick:", c)
    },
)
Parser Function Format
func(b []byte) (bool, *YourType)
  • bool: whether this message matches
  • *YourType: parsed struct to forward to the callback

Alternatively, pass nil for the parser to use default json.Unmarshal.


5. πŸ” TLS Support
Generate Self-Signed Certificate
cert, certPEM, keyPEM, _ := gows.Certificates.GenerateSelfSignedCert("localhost")
gows.Certificates.SaveCertToFiles(certPEM, keyPEM, "cert.pem", "key.pem")
Start TLS Server
server.ListenAndServeTLS(443, cert)

Or load certs from files:

server.ListenAndServeTLSWithFiles(443, "cert.pem", "key.pem")
Event Triggered When
OnConnect A new client connects
OnClose A client disconnects
OnMessage Any message received
OnRequest A private message (request) arrives
OnReconnect Client successfully reconnects
OnError Any socket-level error occurs

Example: Echo Server and Client

Server
server := gows.NewServer("0.0.0.0", "/ws")
server.OnConnect = func(conn *gows.Connection) {
    conn.OnMessage = func(_ int, msg []byte) {
        conn.SendText("Echo: " + string(msg))
    }
}
server.ListenAndServe(9000)
Client
client, _ := gows.NewClient("ws://localhost:9000/ws")
client.OnMessage = func(_ int, msg []byte) {
    fmt.Println("Reply:", string(msg))
}
client.SendText("Hello!")

Contributions

Feel free to submit issues and pull requests. Feedback and improvements are welcome.

Support

If you would like to support my projects, you can donate to the following addresses:

BTC: 19XC9b9gkbNVTB9eTPzjByijmx8gNd2qVR

ETH (ERC20): 0x7e5db6e135da1f4d5de26f7f7d4ed10dada20478

USDT (TRC20): TLHo8zxBpFSTdyuvvCTG4DzXFfDfv49EMu

SOL: B3ZKvA3yCm5gKLb7vucU7nu8RTnp6MEAPpfeySMSMoDc

Thank you for your support!


Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var Certificates certificateHandler

Functions ΒΆ

This section is empty.

Types ΒΆ

type Client ΒΆ

type Client struct {
	OnMessage func(messageType int, msg []byte)

	// Called on any error that originates from the current established connection.
	//
	// Do not treat this as a disconnection as it can be triggerred multiple times for the same connection and is not a sign of disconnection
	//
	// Use 'OnDisconnect' instead in that case
	OnError func(err error)

	// Called once the connection unexpectedly drops, expect to be reconnected shortly after
	OnDisconnect func(code int, reason string)

	OnReconnectError func(err error)
	// Called once a new connection is established after disconnection
	OnReconnect func()
	// contains filtered or unexported fields
}

func NewClient ΒΆ

func NewClient(URL string, opt_params ...Client_params) (*Client, error)

func (*Client) Close ΒΆ

func (socket *Client) Close()

func (*Client) GetParserRegistry ΒΆ

func (socket *Client) GetParserRegistry() *parser.MessageParsers_Registry

func (*Client) SendJSON ΒΆ

func (socket *Client) SendJSON(v interface{}) error

func (*Client) SendPreparedMessage ΒΆ

func (socket *Client) SendPreparedMessage(preparedMessage *ws.PreparedMessage) error

func (*Client) SendPrivateMessage ΒΆ

func (socket *Client) SendPrivateMessage(message map[string]interface{}, timeout_sec ...int) (response []byte, hasTimedOut bool, err error)

func (*Client) SendText ΒΆ

func (socket *Client) SendText(text string) error

func (*Client) SetHTTPHeader ΒΆ

func (socket *Client) SetHTTPHeader(httpHeader http.Header)

func (*Client) SetURL ΒΆ

func (socket *Client) SetURL(URL string)

type Client_params ΒΆ

type Client_params struct {

	// Default is "id"
	PrivateRequestPropertyName string
	// contains filtered or unexported fields
}

type Connection ΒΆ

type Connection struct {
	Request *http.Request

	Data connectionData

	OnRequest func(msg []byte, request *ResponseHandler)
	OnMessage func(messageType int, msg []byte)
	OnError   func(err error)
	OnClose   func(code int, reason string)
	// contains filtered or unexported fields
}

func (*Connection) Close ΒΆ

func (connection *Connection) Close()

func (*Connection) GetId ΒΆ

func (connection *Connection) GetId() int

func (*Connection) GetParserRegistry ΒΆ

func (connection *Connection) GetParserRegistry() *parser.MessageParsers_Registry

func (*Connection) SendJSON ΒΆ

func (connection *Connection) SendJSON(v interface{}) error

func (*Connection) SendPreparedMessage ΒΆ

func (connection *Connection) SendPreparedMessage(message *ws.PreparedMessage) error

func (*Connection) SendText ΒΆ

func (connection *Connection) SendText(text string) error

type ResponseHandler ΒΆ

type ResponseHandler struct {
	Body []byte
	// contains filtered or unexported fields
}

func (*ResponseHandler) Reply ΒΆ

func (request *ResponseHandler) Reply(reply map[string]interface{}) error

func (*ResponseHandler) Unmarshal ΒΆ

func (request *ResponseHandler) Unmarshal(v interface{}) error

type Server ΒΆ

type Server struct {
	OnConnect func(*Connection)
	OnClose   func(connection *Connection, code int, reason string)

	Connections struct {
		Mu  sync.Mutex
		Map map[int]*Connection
	}
	// contains filtered or unexported fields
}

func NewServer ΒΆ

func NewServer(addr string, path string, opt_params ...Server_Params) *Server

func (*Server) Broadcast ΒΆ

func (server *Server) Broadcast(v interface{}) (failCount int, err error)

Broadcasts a message to all active connections to the server

'err' is returned only when preparing the message for broadcast goes wrong, meaning no connection was sent the message

Otherwise 'failCount' keeps track of how many connections failed to be sent the message

func (*Server) ListenAndServe ΒΆ

func (server *Server) ListenAndServe(port int) error

This method WILL block until the server is terminated or an error occurs

func (*Server) ListenAndServeTLS ΒΆ

func (server *Server) ListenAndServeTLS(port int, certificate tls.Certificate) error

This method WILL block until the server is terminated or an error occurs

func (*Server) ListenAndServeTLSWithFiles ΒΆ

func (server *Server) ListenAndServeTLSWithFiles(port int, certFile, keyFile string) error

This method WILL block until the server is terminated or an error occurs

func (*Server) SetCheckOrigin ΒΆ

func (server *Server) SetCheckOrigin(checkOrigin func(r *http.Request) bool)

CheckOrigin returns true if the request Origin header is acceptable. If CheckOrigin is nil, then a safe default is used: return false if the Origin request header is present and the origin host is not equal to request Host header.

A CheckOrigin function should carefully validate the request origin to prevent cross-site request forgery.

type Server_Params ΒΆ

type Server_Params struct {
	PrivateMessagePropertyName string
}

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

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