package
0.0.0-20190810165348-6465c3567dc7
Repository: https://github.com/yt-tech/lib.git
Documentation: pkg.go.dev

# README

RMNP - Realtime Multiplayer Networking Protocol

RMNP aims to combine all the advantages of TCP and the speed of UDP in order to be fast enough to support modern realtime games like first person shooters. It is basically an extension for UDP.

Features

  • Connections (with timeouts and ping calculation)
  • Error detection
  • Small overhead (max 15 bytes for header)
  • Simple congestion control (avoids flooding nodes between sender/receiver)
  • Optional reliable and ordered packet delivery

How it works

The bad thing about TCP is that once a packet is dropped it stops sending all other packets until the missing one is delivered. This can be a huge problem for games that are time sensitive because it is not uncommon for devices to encounter packet-loss. Therefore RMNP facilitates UDP to guarantee fast delivery without any restrictions. Because UDP is stateless RMNP implements an easy way to handle connection and to distinguish between "connected" clients. Every packet contains a small header mainly containing a CRC32 hash to ensure that all received packets were transmitted correctly.

To guarantee reliability the receiver sends acknowledgment packets back to tell the sender which packets it received. The sender resends each packet until it received an acknowledgment or the maximum timeout is reached. Because of that RMNP is not 100% reliable but it can be assumed that a packet will be delivered unless a client has a packet-loss of about 100% for a couple seconds.

Getting started

Installation

go get github.com/obsilp/rmnp

Basic Server

Example Pong Server

package main

import "github.com/obsilp/rmnp"

func main() {
	server := rmnp.NewServer(":10001")
	server.Start() // non-blocking

	// other code ...
}

Basic Client

Example Ping Client

package main

import "github.com/obsilp/rmnp"

func main() {
	client := rmnp.NewClient("127.0.0.1:10001")
	client.Connect() // non-blocking

	// other code ...
}

Callbacks

Events and received packets can be received by setting callbacks. Look at the respective classes for more information.

Client callbacks | Server callbacks

Send types

  • Unreliable - Fast delivery without any guarantee on arrival or order
  • Unreliable Ordered - Same as unreliable but only the most recent packet is accepted
  • Reliable - Packets are guaranteed to arrive but not in order
  • Reliable Ordered - Packets are guaranteed to arrive in order

Ports

License

This project is licensed under the MIT License - see the LICENSE file for details

Acknowledgments

# Functions

NewClient creates and returns a new Client instance that will try to connect to the given server address.
NewSerializer is a new serializer with an empty buffer.
NewSerializerFor creates a serializer based on the contents of the buffer.
NewServer creates and returns a new Server instance that will listen on the specified address and port.

# Constants

ChannelReliable guarantees packets to arrive but not in order.
ChannelReliableOrdered guarantees packets to arrive in order (mimics TCP).
ChannelUnreliable is fast delivery without any guarantee on arrival or order.
ChannelUnreliableOrdered is the same as ChannelUnreliable but only the most recent packet is accepted.

# Variables

CfgAutoPingInterval defines the interval for sending a ping packet.
CfgBadModeMultiplier is the multiplier for variables in bad mode.
CfgBadRTTPunishTimeout the time after how many seconds a bad connection is punished.
CfgChainSkipTimeout is the time after which a missing packet for a complete sequence is ignored and skipped.
CfgCongestionPacketReduction is the amount of unreliable packets that get dropped in bad mode.
CfgCongestionThreshold is the max RTT before the connection enters bad mode.
CfgDefaultCongestionRequiredTime the initial time it should take to switch back from bad to good mode.
CfgGoodRTTRewardInterval the time after how many seconds a good connection is rewarded.
CfgMaxCongestionRequiredTime the max time it should take to switch between modes.
CfgMaxPacketChainLength is the max length of packets that are chained when waiting for missing sequence.
CfgMaxPacketResends is the default max amount of packets to resend during one update.
CfgMaxPing is the max ping before a connection times out.
CfgMaxSendReceiveQueueSize is the max size of packets that can be queued up before they are processed.
CfgMaxSkippedPackets is the max amount of that are allowed to be skipped during packet loss (should be less than 32).
CfgMTU is the maximum byte size of a packet (header included).
CfgParallelListenerCount is the amount of goroutines that will be spawned to listen on incoming requests.
CfgProtocolID is the identification number send with every rmnp packet to filter out unwanted traffic.
CfgReackTimeout is the default timeout before a manual ack packet gets send.
CfgResendTimeout is the default timeout for packets before resend.
CfgRTTSmoothFactor is the factor used to slowly adjust the RTT.
CfgSendRemoveTimeout is the time after which packets that have not being acked yet stop to be resend.
CfgSequenceBufferSize is the size of the buffer that store the last received packets in order to ack them.
CfgTimeoutThreshold is the time after which a connection times out if no packets have being send for the specified amount of time.
CfgUpdateLoopTimeout is the max wait duration for the connection update loop (should be less than other timeout variables).
StatConnects (atomic) counts all successful connects.
StatDeniedConnects (atomic) counts all denied connection attempts.
StatDisconnects (atomic) counts all disconnects.
StatGoRoutinePanics (atomic) counts the amount of caught goroutine panics.
StatProcessedBytes (atomic) counts the total size of all processed packets.
StatReceivedBytes (atomic) counts the total amount of bytes received.
StatRunningGoRoutines (atomic) counts all currently active goroutines spawned by rmnp.
StatSendBytes (atomic) counts the total amount of bytes send.
StatTimeouts (atomic) counts all timeouts.

# Structs

Client is used to connect to a rmnp server.
Connection is a udp connection and handles sending of packets.
Serializer reads and writes binary data.
Server listens for incoming rmnp packets and manages client connections.

# Type aliases

Channel is the method of sending packets.
ConnectionCallback is the function called when connections change.
PacketCallback is the function called when a packet is received.
ReadFunc is the function called to write information to a udp connection.
ValidationCallback is the function called to validate a connnection.
WriteFunc is the function called to read information from a udp connection.