Documentation
¶
Index ¶
- Constants
- type Client
- func (c *Client) Context() context.Context
- func (c *Client) Credentials(ctx context.Context) (*nethernet.Credentials, error)
- func (c *Client) DisableTrickleICE() bool
- func (c *Client) NetworkID() string
- func (c *Client) Notify(n nethernet.Notifier) (stop func())
- func (c *Client) PingContext(ctx context.Context, address string) ([]byte, error)
- func (c *Client) PongData([]byte)
- func (c *Client) Signal(ctx context.Context, signal *nethernet.Signal) error
- func (c *Client) Status(ctx context.Context, address string) (Status, error)
- type ClientConfig
- type Handler
- func (h *Handler) Addr() net.Addr
- func (h *Handler) Close() error
- func (h *Handler) Context() context.Context
- func (h *Handler) Credentials(ctx context.Context) (*nethernet.Credentials, error)
- func (h *Handler) DisableTrickleICE() bool
- func (h *Handler) NetworkID() string
- func (h *Handler) Notify(n nethernet.Notifier) (stop func())
- func (h *Handler) PongData(data []byte)
- func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request)
- func (h *Handler) Signal(ctx context.Context, signal *nethernet.Signal) error
- func (h *Handler) Status(status Status)
- type HandlerConfig
- type Status
Examples ¶
Constants ¶
const ( GameTypeSurvival = iota GameTypeCreative GameTypeAdventure )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client implements nethernet.Signaling using the HTTP endpoints exposed by a NetherNet server.
Example ¶
ExampleClient demonstrates how to connect to a NetherNet server using HTTP signaling.
// Create a signaling client.
// This client is responsible for exchanging WebRTC connection details with the server over HTTP.
client := NewClient()
// Establish a NetherNet connection using the client for the signaling.
var d nethernet.Dialer
conn, err := d.DialContext(context.TODO(), "https://localhost:19132", client)
if err != nil {
panic(fmt.Sprintf("error connecting to server: %s", err))
}
defer conn.Close()
fmt.Printf("connected, latency: %s", conn.Latency())
func NewClient ¶
func NewClient() *Client
NewClient creates a new Client with the default ClientConfig. It is equivalent to calling ClientConfig{}.New().
func (*Client) Context ¶
Context always returns context.Background.
func (*Client) Credentials ¶
Credentials returns a nethernet.Credentials using the ClientConfig.Credentials if possible. Otherwise, it returns an empty nethernet.Credentials. It is optimal for the caller to provide ClientConfig.Credentials containing STUN/TURN servers in order to stabilize WebRTC peer negotiations.
func (*Client) DisableTrickleICE ¶
DisableTrickleICE always returns true as it is not supported because the HTTP request-response model requires the full SDP exchange to complete within a single round trip. A peer connection should wait for all local ICE candidates to be gathered and include them as SDP attributes in the initial offer.
func (*Client) NetworkID ¶
NetworkID returns a network ID assigned for this Client. It is included to the URL path of requests sent to servers. Callers can specify this value from ClientConfig.NetworkID.
func (*Client) PingContext ¶ added in v1.0.22
PingContext sends a ping request to the given address and returns the pong data in the same format used with RakNet transport. It is useful for older code that still expects that format.
func (*Client) PongData ¶
PongData is unsupported on Client because endpoint clients only dial and do not receive server ping data.
func (*Client) Signal ¶
Signal sends a Signal to the remote endpoint.
Only nethernet.SignalTypeOffer is supported. The returned SDP answer is delivered to the Dialers registered to this Client.
func (*Client) Status ¶ added in v1.0.23
Status sends a ping request to the given address and returns the Status reported by the server. The returned Status can also be converted to RakNet-compatible pong data via Status.RakNet, for use with older code that still expects that format.
Example ¶
ExampleClient_Status demonstrates how to retrieve a status for a NetherNet server.
// Create a client.
client := NewClient()
// Query the server status at the specific address. The address can be an HTTP or HTTPS URL with a port number.
status, err := client.Status(context.TODO(), "http://127.0.0.1:19132")
if err != nil {
panic(err)
}
fmt.Println(strconv.Quote(status.ServerName)) // "Dedicated Server"
type ClientConfig ¶
type ClientConfig struct {
// HTTPClient is the HTTP client used for making HTTP requests to the remote servers.
// If nil, [http.DefaultClient] will be used instead.
HTTPClient *http.Client
// Credentials is an optional function that supplies ICE credentials
// to the ICE gatherer used by the peer connection.
// When nil, [Handler.Credentials] returns an empty [nethernet.Credentials]
// with no STUN/TURN servers, which may reduce NAT traversal reliability.
Credentials func(ctx context.Context) (*nethernet.Credentials, error)
// Logger is used to log messages produced when handling requests.
// If nil, it will be set from [slog.Default].
Logger *slog.Logger
// NetworkID is the identifier assigned to this Handler.
// It is included to the URL path of requests sent to servers.
// If empty, a random uint64 is generated and used.
NetworkID string
}
ClientConfig represents a configuration for creating a Client.
func (ClientConfig) New ¶
func (conf ClientConfig) New() *Client
New returns a new Client from the configuration. The resulting Client can be passed to nethernet.Dialer.DialContext.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is an http.Handler that negotiates incoming NetherNet connections over HTTP. Callers can create a Handler from NewHandler or HandlerConfig.New, then pass it to http.ListenAndServeTLS or assign to http.Server.Handler.
Currently, Handler implements the following endpoints:
- GET /v1/join (ping)
- POST /v1/join/{networkID} (WebRTC negotiation)
On an address join a Bedrock client discovers this endpoint by sending the GET /v1/join ping to each candidate URL in order, stopping at the first that responds: https://host:port, https://host (443), http://host:port, then http://host (80). An explicit port collapses the list to the https/http variants on that port. If none respond the client falls back to RakNet, so a server that serves this Handler is reached over NetherNet in preference to a RakNet listener on the same address.
Example ¶
ExampleHandler demonstrates how to expose a NetherNet listener using HTTP/TLS server for signaling.
handler, err := Serve(":19132")
if err != nil {
panic(fmt.Sprintf("error listening on HTTP: %s", err))
}
defer handler.Close()
// Set up a NetherNet listener.
var cfg nethernet.ListenConfig
l, err := cfg.Listen(handler)
if err != nil {
panic(fmt.Sprintf("error listening on NetherNet: %s", err))
}
defer l.Close()
// Start accepting NetherNet connections.
for {
conn, err := l.Accept()
if err != nil {
return
}
slog.Info("connected",
"remoteAddr", conn.RemoteAddr(),
"localAddr", conn.LocalAddr(),
"latency", conn.(*nethernet.Conn).Latency(),
)
}
func NewHandler ¶
func NewHandler() *Handler
NewHandler creates a new Handler with default HandlerConfig values and returns it. It is equivalent to calling HandlerConfig{}.New().
func Serve ¶ added in v1.0.22
Serve is a utility method that sets up an HTTP server on the specified address. It is equivalent of calling HandlerConfig{}.Serve().
func ServeTLS ¶ added in v1.0.16
ServeTLS is a utility method that sets up an HTTP/TLS server on the specified address using the TLS certificate and key file. It is equivalent of calling HandlerConfig{}.ServeTLS().
func (*Handler) Addr ¶ added in v1.0.24
Addr returns the TCP address used by the underlying HTTP server. It may be nil if the Handler has not been created using HandlerConfig.Serve or HandlerConfig.ServeTLS.
func (*Handler) Close ¶ added in v1.0.16
Close closes the underlying HTTP server, if one is bound. Otherwise, Close is no-op.
func (*Handler) Context ¶
Context returns the background context of the underlying HTTP server, if one is bound to this Handler. Otherwise, Context always returns context.Background.
func (*Handler) Credentials ¶
Credentials returns a nethernet.Credentials using the HandlerConfig.Credentials if possible. Otherwise, it returns an empty nethernet.Credentials. It is optimal for the caller to provide HandlerConfig.Credentials containing STUN/TURN servers in order to stabilize WebRTC peer negotiations.
func (*Handler) DisableTrickleICE ¶
DisableTrickleICE always returns true as it is not supported because the HTTP request-response model requires the full SDP exchange to complete within a single round trip. A peer connection should wait for all local ICE candidates to be gathered and include them as SDP attributes in the initial offer.
func (*Handler) NetworkID ¶
NetworkID returns a network ID assigned for this Handler. This is never transmitted to clients and is currently only used for locally identifying this Handler.
func (*Handler) PongData ¶
PongData is a no-op implementation of nethernet.Signaling.PongData. It may become meaningful in the future if Mojang introduces an HTTP endpoint for serving MOTDs.
func (*Handler) ServeHTTP ¶
func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request)
ServeHTTP implements http.Handler by delegating the given response writer and the request to the internal http.ServeMux.
func (*Handler) Signal ¶
Signal delivers a signal to the pending negotiation identified by the nethernet.Signal.NetworkID and nethernet.Signal.ConnectionID.
func (*Handler) Status ¶ added in v1.0.22
Status sets the server status that the Handler responds with for HTTP requests sent by clients. Note that if the upstream game listener also provides pong data via Handler.PongData, that data will take precedence, since Handler.PongData overwrites the status set here. Callers can set HandlerConfig.DisablePongData to true to disable this behavior.
type HandlerConfig ¶
type HandlerConfig struct {
// Logger is used to log messages produced when handling requests.
// If nil, it will be set from [slog.Default].
Logger *slog.Logger
// NegotiationContext returns the [context.Context] that controls how long
// the Handler waits for the listener to produce an SDP answer.
// The resulting [context.Context] must be derived from the parent context.
// If nil, a context with a 15-second timeout will be returned.
NegotiationContext func(parent context.Context) (context.Context, context.CancelFunc)
// Credentials is an optional function that supplies ICE credentials
// to the ICE gatherer used by the peer connection.
// When nil, [Handler.Credentials] returns an empty [nethernet.Credentials]
// with no STUN/TURN servers, which may reduce NAT traversal reliability.
Credentials func(ctx context.Context) (*nethernet.Credentials, error)
// NetworkID is the identifier assigned to this Handler.
// It is used only for identifying Handler and is never transmitted to clients.
// If empty, a random uint64 is generated and used.
NetworkID string
// DisablePongData specifies whether to disable syncing with the RakNet pong
// data provided by the upstream game protocol. When set to true, [Handler.PongData]
// becomes no-op.
DisablePongData bool
}
HandlerConfig represents a configuration for creating a Handler.
func (HandlerConfig) New ¶
func (conf HandlerConfig) New() *Handler
New returns a new Handler from the configuration. The resulting Handler can be passed directly to http.ListenAndServeTLS or assigned to http.Server.Handler.
type Status ¶ added in v1.0.22
type Status struct {
// ServerName is the name of the server. It is displayed as the MOTD.
ServerName string `json:"name"`
// Protocol is the protocol version used by the upstream game listener.
Protocol int `json:"protocol"`
// Version is the version of the game that the server is currently running.
Version string `json:"version"`
// LevelName is the name of the world. It is never displayed in the server card in Multiplayer tab.
LevelName string `json:"level"`
// PlayerCount is the number of players that is currently connected to the server.
PlayerCount int `json:"players"`
// MaxPlayerCount is the number of players that can be connected to the server.
MaxPlayerCount int `json:"maxPlayers"`
// GameType represents the game mode of the level running in the server in numerical value.
// It is 0 for survival, 1 for creative, and 2 for adventure.
GameType int `json:"gameType"`
}
Status represents a server status of a NetherNet server.
func RakNetPongData ¶ added in v1.0.22
RakNetPongData parses a RakNet-compatible pong data into a Status. It is typically used for maintaining compatibility with older code that still produces the same format used in RakNet servers, e.g. Gophertunnel. It is also used in Handler.PongData to synchronize the status with the upstream game listener.
func (Status) RakNet ¶ added in v1.0.23
RakNet produces a RakNet-compatible pong data from the status. It is typically used for maintaining compatibility with older code that still expects the same format used in RakNet servers. The port included in the resulting data is always 19132.
func (Status) RakNetPongData
deprecated
added in
v1.0.22
RakNetPongData produces a RakNet-compatible pong data from the status. It is typically used for maintaining compatibility with older code that still expects the same format used in RakNet servers. The port included in the resulting data is always 19132.
Deprecated: Use Status.RakNet instead.