Go NTRIP v2 clients for rovers and correction sources.
The rover client is full-duplex: it reads RTCM corrections while keeping the
same caster connection writable for periodic NMEA GGA updates. This is required
by VRS and nearest-base casters and is the reason the package uses raw HTTP/1.1
over net.Conn/tls.Conn instead of net/http.Client for streaming sessions.
- NTRIP v2 rover
GETstreams with full-duplex GGA writes. - NTRIP v2 source
PUTstreams with chunked transfer encoding by default. - HTTPS/TLS with custom
tls.Configsupport. - Basic authentication.
- Sourcetable fetch and parsing for
CAS,NET, andSTRrecords, including parse warnings, round-tripping, stream lookup, network lookup, and nearest-stream selection. - Managed rover and source stream abstractions with reconnect/backoff.
- Deadline-bound request/header/write operations and read-idle reconnects for autonomous rover links.
- NMEA GGA formatting and checksum validation helpers.
- Standard-library only.
Most existing Go NTRIP packages are useful but incomplete for modern rover integrations:
github.com/go-gnss/ntripprovides a good sourcetable model and warning-oriented parser. Its rover client usesnet/httpand exposes onlyresp.Body, so it cannot send periodic GGA on the same active rover stream.github.com/de-bkg/gognss/pkg/ntriphas a higher-level client API, sourcetable helpers, and caster metadata handling, but its public rover stream shape is read-only.github.com/bezineb5/ntrip-clientexplores registry and nearest-station selection on top ofgo-gnss/ntrip; this package includes nearest-stream helpers directly while keeping the transport full-duplex.github.com/facebook/time/ntriphas a clean source/push client API; this package covers both sourcePUTand roverGETwith GGA.
This package is differentiated by treating NTRIP v2 as an HTTP/1.1-shaped protocol over a bidirectional TCP/TLS stream for rover sessions. The low-level Rover remains an io.Reader for RTCM and exposes WriteGGA for upstream NMEA updates. The managed RoverStream adds reconnect/backoff and periodic GGA resend without hiding the raw bytes.
- Dial timeout: 10 seconds.
- Response header timeout: 10 seconds.
- Write timeout: 5 seconds.
- Rover read-idle timeout: 60 seconds.
- Reconnect backoff: 500 milliseconds to 30 seconds, factor 2.
Managed streams retry transient network and server failures. They stop on invalid local configuration and non-transient status responses such as 401 Unauthorized, so supervisors can surface real operator action items instead of looping forever.
rover, err := ntrip.DialRover(ctx, ntrip.RoverConfig{
URL: "https://corshub.peinser.com/*",
Credentials: ntrip.Credentials{Username: "rover", Password: "secret"},
})
if err != nil {
return err
}
defer rover.Close()
go func() {
_ = rover.WriteGGA("$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47")
}()
_, err = io.Copy(rtcmDestination, rover)stream := ntrip.NewRoverStream(ntrip.StreamConfig{
Rover: ntrip.RoverConfig{
URL: "https://corshub.peinser.com/*",
Credentials: ntrip.Credentials{Username: "rover", Password: "secret"},
},
GGAInterval: 5 * time.Second,
ReconnectOnEOF: true,
})
if err := stream.SetGGA("$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"); err != nil {
return err
}
err := stream.RunToWriter(ctx, rtcmDestination)source, err := ntrip.DialSource(ctx, ntrip.SourceConfig{
URL: "https://corshub.peinser.com/BASE-01",
Credentials: ntrip.Credentials{Username: "base", Password: "secret"},
})
if err != nil {
return err
}
defer source.Close()
_, err = io.Copy(source, rtcmSource)table, err := ntrip.FetchSourcetable(ctx, ntrip.SourcetableConfig{
URL: "https://corshub.peinser.com",
Credentials: ntrip.Credentials{Username: "anonymous", Password: "anonymous"},
})
if err != nil {
return err
}
nearest := table.NearestStreams(50.85034, 4.35171, 50_000)ParseSourcetable is tolerant: it returns parsed records and stores row-level issues in Sourcetable.Warnings instead of discarding the entire table for one malformed field.
See examples/ for buildable programs covering:
- Reliable rover streaming with reconnect and periodic GGA dispatching RTCM to UDP.
- Dispatching RTCM to multiple sinks: UDP, file, stdout, or a raw device path.
- Fetching a sourcetable and selecting the nearest fixed mountpoint.
- Publishing source RTCM to a caster with NTRIP v2
PUT. - Formatting and validating fixed-position GGA sentences.