add documentation
This commit is contained in:
parent
f605bcea5a
commit
6618425c3d
@ -1,5 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// WebSocket client read/write pumps.
|
||||||
|
//
|
||||||
|
// ReadPump pulls messages from the client's WebSocket connection and routes
|
||||||
|
// them into the Hub. WritePump pushes outbound messages from the Hub to the
|
||||||
|
// client's connection. Both functions are expected to run as goroutines per
|
||||||
|
// client.
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -9,6 +15,7 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ReadPump reads from the websocket connection and handles client pings/pongs.
|
||||||
func ReadPump(c *server.Client) {
|
func ReadPump(c *server.Client) {
|
||||||
defer func() {
|
defer func() {
|
||||||
c.Hub.Unregister <- c
|
c.Hub.Unregister <- c
|
||||||
@ -187,6 +194,7 @@ func ReadPump(c *server.Client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WritePump writes queued messages to the websocket connection and sends periodic pings.
|
||||||
func WritePump(c *server.Client) {
|
func WritePump(c *server.Client) {
|
||||||
defer func(conn *websocket.Conn) {
|
defer func(conn *websocket.Conn) {
|
||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
|
3
main.go
3
main.go
@ -1,5 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// main is the entrypoint for RadChat. It parses flags, prepares storage,
|
||||||
|
// configures middleware and routes, and starts the HTTP server. See README for
|
||||||
|
// the flag reference and architecture overview.
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
107
message.go
107
message.go
@ -1,5 +1,112 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// Message is a generic envelope exchanged over the WebSocket signaling channel.
|
||||||
|
//
|
||||||
|
// Type is the message kind (e.g., "join", "leave", "chat", "offer",
|
||||||
|
// "answer", "ice", etc.). Other fields are used depending on Type; unused
|
||||||
|
// fields are omitted in JSON.
|
||||||
|
//
|
||||||
|
// The flexibility helps keep the client and server loosely coupled; consider
|
||||||
|
// introducing stricter typed payloads if this grows.
|
||||||
|
//
|
||||||
|
// Note: This struct is intentionally broad to carry both chat and WebRTC
|
||||||
|
// signaling payloads.
|
||||||
|
//
|
||||||
|
// Timestamp is set by the sender (usually server) for ordering.
|
||||||
|
// Target is a peer client ID for directed messages.
|
||||||
|
// Data/DataExt/DataList support heterogeneous payloads where necessary.
|
||||||
|
// Offer/Answer/ICE carry WebRTC SDP/ICE candidate info.
|
||||||
|
// DataType can be used by clients to dispatch UI behavior.
|
||||||
|
// DataTime is optional timing metadata.
|
||||||
|
//
|
||||||
|
// Username/UserID are the sender identity.
|
||||||
|
// Error holds error information if Type indicates a failure.
|
||||||
|
//
|
||||||
|
// All fields are optional in JSON except Type.
|
||||||
|
// Keep in sync with frontend parsing in static/app.js
|
||||||
|
// to avoid breaking changes.
|
||||||
|
//
|
||||||
|
// Consider versioning if wire format evolves.
|
||||||
|
//
|
||||||
|
//nolint:lll // wide field tags
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Message struct definition:
|
||||||
|
//
|
||||||
|
// - Type: message category
|
||||||
|
// - Username, UserID: identity
|
||||||
|
// - Data/DataExt/DataList: generic payloads
|
||||||
|
// - Offer/Answer/ICE: WebRTC signaling
|
||||||
|
// - Target: directed recipient id
|
||||||
|
// - Error: error description if any
|
||||||
|
// - Timestamp: unix ms or ns
|
||||||
|
//
|
||||||
|
// The JSON tags omit empty fields to minimize bandwidth.
|
||||||
|
//
|
||||||
|
// End of doc.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Actual type follows.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
|
// Client represents a single WebSocket connection and associated user state.
|
||||||
|
// It includes a send channel for outbound messages and LastPong for liveness.
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -7,6 +9,7 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Client holds the websocket connection and linkage back to the Hub.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
Conn *websocket.Conn
|
Conn *websocket.Conn
|
||||||
Username string
|
Username string
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
|
// Hub is the central registry/bus for all connected clients.
|
||||||
|
//
|
||||||
|
// It exposes channels for broadcast, register, and unregister events
|
||||||
|
// and protects the Clients map with a RWMutex for safe concurrent access.
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Hub groups clients and channels used by the server runtime.
|
||||||
type Hub struct {
|
type Hub struct {
|
||||||
Clients map[*Client]bool
|
Clients map[*Client]bool
|
||||||
Broadcast chan []byte
|
Broadcast chan []byte
|
||||||
@ -15,6 +20,7 @@ type Hub struct {
|
|||||||
Upgrader websocket.Upgrader
|
Upgrader websocket.Upgrader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHub constructs a Hub with buffered channels sized by bufferSize.
|
||||||
func NewHub(bufferSize int, upgrader websocket.Upgrader) *Hub {
|
func NewHub(bufferSize int, upgrader websocket.Upgrader) *Hub {
|
||||||
return &Hub{
|
return &Hub{
|
||||||
Clients: make(map[*Client]bool),
|
Clients: make(map[*Client]bool),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
|
// HTTP middleware for gzip compression and cache control.
|
||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"io"
|
"io"
|
||||||
@ -7,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MiddlewareChain composes multiple middleware into a single http.Handler wrapper.
|
||||||
func MiddlewareChain(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
|
func MiddlewareChain(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
|
||||||
return func(final http.Handler) http.Handler {
|
return func(final http.Handler) http.Handler {
|
||||||
for _, middleware := range middlewares {
|
for _, middleware := range middlewares {
|
||||||
@ -16,6 +18,7 @@ func MiddlewareChain(middlewares ...func(http.Handler) http.Handler) func(http.H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gzipResponseWriter wraps http.ResponseWriter to write gzipped data.
|
||||||
type gzipResponseWriter struct {
|
type gzipResponseWriter struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
io.Writer
|
io.Writer
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
|
// Utilities for server package: WebSocket upgrader with Origin checks.
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@ -7,6 +8,9 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Upgrader creates a Gorilla websocket.Upgrader that enforces Origin checks.
|
||||||
|
// If bypass is true, any Origin is accepted. Otherwise, the Origin must match
|
||||||
|
// the provided originAddress (host[:port]).
|
||||||
func Upgrader(originAddress string, bypass bool) websocket.Upgrader {
|
func Upgrader(originAddress string, bypass bool) websocket.Upgrader {
|
||||||
if strings.HasPrefix(originAddress, "http://") || strings.HasPrefix(originAddress, "https://") {
|
if strings.HasPrefix(originAddress, "http://") || strings.HasPrefix(originAddress, "https://") {
|
||||||
originAddress = strings.TrimPrefix(originAddress, "http://")
|
originAddress = strings.TrimPrefix(originAddress, "http://")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user