Skip to content

Commit

Permalink
[ntcore] Networking improvements
Browse files Browse the repository at this point in the history
- Utilize TrySend to properly backpressure network traffic
- Split updates into reasonable sized frames using WS fragmentation
- Use WS pings for network aliveness (requires 4.1 protocol revision)
- Measure RTT only at start of connection, rather than periodically
  (this avoids them being affected by other network traffic)
- Refactor network queue
- Refactor network ping, ping from server as well
- Improve meta topic performance

This adds a new protocol version (4.1) due to WS bugs in prior versions.
  • Loading branch information
PeterJohnson committed Sep 18, 2023
1 parent 1887087 commit beccf0e
Show file tree
Hide file tree
Showing 19 changed files with 978 additions and 587 deletions.
16 changes: 10 additions & 6 deletions ntcore/src/main/native/cpp/NetworkClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,30 +369,34 @@ void NetworkClient::TcpConnected(uv::Tcp& tcp) {
wpi::SmallString<128> idBuf;
auto ws = wpi::WebSocket::CreateClient(
tcp, fmt::format("/nt/{}", wpi::EscapeURI(m_id, idBuf)), "",
{{"networktables.first.wpi.edu"}}, options);
{"v4.1.networktables.first.wpi.edu", "networktables.first.wpi.edu"},
options);
ws->SetMaxMessageSize(kMaxMessageSize);
ws->open.connect([this, &tcp, ws = ws.get()](std::string_view) {
ws->open.connect([this, &tcp, ws = ws.get()](std::string_view protocol) {
if (m_connList.IsConnected()) {
ws->Terminate(1006, "no longer needed");
return;
}
WsConnected(*ws, tcp);
WsConnected(*ws, tcp, protocol);
});
}

void NetworkClient::WsConnected(wpi::WebSocket& ws, uv::Tcp& tcp) {
void NetworkClient::WsConnected(wpi::WebSocket& ws, uv::Tcp& tcp,
std::string_view protocol) {
if (m_parallelConnect) {
m_parallelConnect->Succeeded(tcp);
}

ConnectionInfo connInfo;
uv::AddrToName(tcp.GetPeer(), &connInfo.remote_ip, &connInfo.remote_port);
connInfo.protocol_version = 0x0400;
connInfo.protocol_version =
protocol == "v4.1.networktables.first.wpi.edu" ? 0x0401 : 0x0400;

INFO("CONNECTED NT4 to {} port {}", connInfo.remote_ip, connInfo.remote_port);
m_connHandle = m_connList.AddConnection(connInfo);

m_wire = std::make_shared<net::WebSocketConnection>(ws);
m_wire =
std::make_shared<net::WebSocketConnection>(ws, connInfo.protocol_version);
m_clientImpl = std::make_unique<net::ClientImpl>(
m_loop.Now().count(), m_inst, *m_wire, m_logger, m_timeSyncUpdated,
[this](uint32_t repeatMs) {
Expand Down
3 changes: 2 additions & 1 deletion ntcore/src/main/native/cpp/NetworkClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ class NetworkClient final : public NetworkClientBase {
private:
void HandleLocal();
void TcpConnected(wpi::uv::Tcp& tcp) final;
void WsConnected(wpi::WebSocket& ws, wpi::uv::Tcp& tcp);
void WsConnected(wpi::WebSocket& ws, wpi::uv::Tcp& tcp,
std::string_view protocol);
void ForceDisconnect(std::string_view reason) override;
void DoDisconnect(std::string_view reason) override;

Expand Down
12 changes: 9 additions & 3 deletions ntcore/src/main/native/cpp/NetworkServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ class NetworkServer::ServerConnection4 final
std::string_view addr, unsigned int port,
wpi::Logger& logger)
: ServerConnection{server, addr, port, logger},
HttpWebSocketServerConnection(stream, {"networktables.first.wpi.edu"}) {
HttpWebSocketServerConnection(stream,
{"v4.1.networktables.first.wpi.edu",
"networktables.first.wpi.edu"}) {
m_info.protocol_version = 0x0400;
}

Expand Down Expand Up @@ -228,8 +230,12 @@ void NetworkServer::ServerConnection4::ProcessWsUpgrade() {

m_websocket->SetMaxMessageSize(kMaxMessageSize);

m_websocket->open.connect([this, name = std::string{name}](std::string_view) {
m_wire = std::make_shared<net::WebSocketConnection>(*m_websocket);
m_websocket->open.connect([this, name = std::string{name}](
std::string_view protocol) {
m_info.protocol_version =
protocol == "v4.1.networktables.first.wpi.edu" ? 0x0401 : 0x0400;
m_wire = std::make_shared<net::WebSocketConnection>(
*m_websocket, m_info.protocol_version);
// TODO: set local flag appropriately
std::string dedupName;
std::tie(dedupName, m_clientId) = m_server.m_serverImpl.AddClient(
Expand Down
Loading

0 comments on commit beccf0e

Please sign in to comment.