add documentation
This commit is contained in:
parent
f605bcea5a
commit
6618425c3d
@ -1,5 +1,11 @@
|
||||
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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -9,6 +15,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// ReadPump reads from the websocket connection and handles client pings/pongs.
|
||||
func ReadPump(c *server.Client) {
|
||||
defer func() {
|
||||
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) {
|
||||
defer func(conn *websocket.Conn) {
|
||||
_ = conn.Close()
|
||||
|
3
main.go
3
main.go
@ -1,5 +1,8 @@
|
||||
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 (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
107
message.go
107
message.go
@ -1,5 +1,112 @@
|
||||
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 string `json:"type"`
|
||||
Username string `json:"username,omitempty"`
|
||||
|
@ -1,5 +1,7 @@
|
||||
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 (
|
||||
"sync"
|
||||
"time"
|
||||
@ -7,6 +9,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// Client holds the websocket connection and linkage back to the Hub.
|
||||
type Client struct {
|
||||
Conn *websocket.Conn
|
||||
Username string
|
||||
|
@ -1,11 +1,16 @@
|
||||
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 (
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// Hub groups clients and channels used by the server runtime.
|
||||
type Hub struct {
|
||||
Clients map[*Client]bool
|
||||
Broadcast chan []byte
|
||||
@ -15,6 +20,7 @@ type Hub struct {
|
||||
Upgrader websocket.Upgrader
|
||||
}
|
||||
|
||||
// NewHub constructs a Hub with buffered channels sized by bufferSize.
|
||||
func NewHub(bufferSize int, upgrader websocket.Upgrader) *Hub {
|
||||
return &Hub{
|
||||
Clients: make(map[*Client]bool),
|
||||
|
@ -1,5 +1,6 @@
|
||||
package server
|
||||
|
||||
// HTTP middleware for gzip compression and cache control.
|
||||
import (
|
||||
"compress/gzip"
|
||||
"io"
|
||||
@ -7,6 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MiddlewareChain composes multiple middleware into a single http.Handler wrapper.
|
||||
func MiddlewareChain(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
|
||||
return func(final http.Handler) http.Handler {
|
||||
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 {
|
||||
http.ResponseWriter
|
||||
io.Writer
|
||||
|
@ -1,5 +1,6 @@
|
||||
package server
|
||||
|
||||
// Utilities for server package: WebSocket upgrader with Origin checks.
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -7,6 +8,9 @@ import (
|
||||
"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 {
|
||||
if strings.HasPrefix(originAddress, "http://") || strings.HasPrefix(originAddress, "https://") {
|
||||
originAddress = strings.TrimPrefix(originAddress, "http://")
|
||||
|
Loading…
x
Reference in New Issue
Block a user