package
0.0.0-20241028021611-85c26eb2e2be
Repository: https://github.com/seedlings-calm/prst.git
Documentation: pkg.go.dev

# README

WebSocket

ws is based on the github.com/gorilla/websocket library.


Example of use

1. default setting

Server side code example:

package main

import (
    "context"
    "log"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
	
    r.GET("/ws", func(c *gin.Context) {
        s := ws.NewServer(c.Writer, c.Request, loopReceiveMessage) // default setting
        err := s.Run(context.Background())
        if err != nil {
            log.Println("webSocket server error:", err)
        }
    })
	
    err := r.Run(":8080")
    if err != nil {
        panic(err)
    }
}

func loopReceiveMessage(ctx context.Context, conn *ws.Conn) {
    for {
        messageType, message, err := conn.ReadMessage()
        // handle message
        log.Println(messageType, message, err)
    }
}

Client side code example:

package main

import (
    "strconv"
    "log"
    "time"
    "github.com/seedlings-calm/prst/pkg/ws"
    "github.com/gorilla/websocket"
)

var wsURL = "ws://localhost:8080/ws"

func main() {
    c, err := ws.NewClient(wsURL)
    if err != nil {
        log.Println("connect error:", err)
        return
    }
    defer c.Close()

    go func() {
        for {
            _, message, err := c.GetConn().ReadMessage()
            if err != nil {
                log.Println("client read error:", err)
                return
            }
            log.Printf("client received: %s", message)
        }
    }()
    
    for i := 0; i < 5; i++ {
        data := "Hello, World " + strconv.Itoa(i)
        err = c.GetConn().WriteMessage(websocket.TextMessage, []byte(data))
        if err != nil {
            log.Println("write error:", err)
        }
        time.Sleep(100 * time.Millisecond)
    }
}

2. custom setting

Server side custom setting, options such as ws.Upgrader ws.WithMaxMessageWaitPeriod can be set.

package main

import (
    "context"
    "log"
    "time"
    "http"
    "github.com/seedlings-calm/prst/pkg/ws"
    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"
)

func main() {
    r := gin.Default()
    ug := &websocket.Upgrader{
        CheckOrigin: func(r *http.Request) bool {
            return true
        },
    }    
    r.GET("/ws", func(c *gin.Context) {
        s := ws.NewServer(c.Writer, c.Request, loopReceiveMessage,
            ws.WithUpgrader(ug),
            ws.WithMaxMessageWaitPeriod(time.Minute),
        )
        err := s.Run(context.Background())
        if err != nil {
            log.Println("webSocket server error:", err)
        }
    })
    
    err := r.Run(":8080")
    if err != nil {
        panic(err)
    }
}

func loopReceiveMessage(ctx context.Context, conn *ws.Conn) {
    for {
        messageType, message, err := conn.ReadMessage()
        // handle message
        log.Println(messageType, message, err)
    }
}

Client side custom setting, options such as ws.Dialer ws.WithPingInterval can be set.

package main

import (
    "strconv"
    "log"
    "time"
    "github.com/seedlings-calm/prst/pkg/ws"
    "github.com/gorilla/websocket"
)

var wsURL = "ws://localhost:8080/ws"

func main() {
    c, err := NewClient(wsURL,
        WithDialer(websocket.DefaultDialer),
        WithPing(time.Second*10),
    )
    if err != nil {
        log.Println("connect error:", err)
        return
    }
    defer c.Close()

    go func() {
        for {
            _, message, err := c.GetConn().ReadMessage()
            if err != nil {
                log.Println("client read error:", err)
                return
            }
            log.Printf("client received: %s", message)
        }
    }()

    for i := 5; i < 10; i++ {
        data := "Hello, World " + strconv.Itoa(i)
        err = c.GetConn().WriteMessage(websocket.TextMessage, []byte(data))
        if err != nil {
            log.Println("write error:", err)
        }
        time.Sleep(100 * time.Millisecond)
    }

    <-time.After(time.Minute)
}

# Functions

IsClientClose returns true if the error is caused by client close.
IsServerClose returns true if the error is caused by server close.
NewClient creates a new client.
NewServer creates a new WebSocket server.
WithDialer sets the dialer for the client.
WithMaxMessageWaitPeriod sets the maximum waiting period for a message before closing the connection.
WithPing sets the interval for sending ping message to the server.
WithRequestHeader sets the request header for the client.
WithResponseHeader sets the response header for the WebSocket upgrade response.
WithUpgrader sets the WebSocket upgrader for the server.

# Structs

Client is a wrapper of gorilla/websocket.
Server is a WebSocket server.

# Type aliases

ClientOption is a functional option for the client.
Conn is a WebSocket connection.
LoopFn is the function that is called for each WebSocket connection.
ServerOption is a functional option for the Server.