Improved server performance
This commit is contained in:
parent
b22d0b1367
commit
30c7d3d609
@ -15,7 +15,7 @@ func (ph *Router) Get(code byte, handler Handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle deals with an incoming packet.
|
// handle deals with an incoming packet.
|
||||||
func (ph *Router) handle(p *Packet) {
|
func (ph *Router) handle(p Packet) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println(p)
|
fmt.Println(p)
|
||||||
|
@ -5,20 +5,26 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ChannelBufferSize = 4096
|
const (
|
||||||
|
// How many packets we will buffer in case our consumer can't keep up.
|
||||||
|
ChannelBufferSize = 4096
|
||||||
|
|
||||||
|
// The maximum data length of a UDP datagram (8 bytes UDP header, 20 bytes IP header).
|
||||||
|
UDPDataMaxLength = 65535 - 8 - 20
|
||||||
|
)
|
||||||
|
|
||||||
// Server represents a UDP server.
|
// Server represents a UDP server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
handlers [256]Handler
|
handlers [256]Handler
|
||||||
socket *net.UDPConn
|
socket *net.UDPConn
|
||||||
incoming chan *Packet
|
incoming chan Packet
|
||||||
packetCount int
|
packetCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new server.
|
// NewServer creates a new server.
|
||||||
func NewServer() *Server {
|
func NewServer() *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
incoming: make(chan *Packet, ChannelBufferSize),
|
incoming: make(chan Packet, ChannelBufferSize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,8 +53,10 @@ func (s *Server) ResetPacketCount() {
|
|||||||
|
|
||||||
// Send sends the data prefixed with the byte code to the client.
|
// Send sends the data prefixed with the byte code to the client.
|
||||||
func (s *Server) Send(code byte, data []byte, address *net.UDPAddr) error {
|
func (s *Server) Send(code byte, data []byte, address *net.UDPAddr) error {
|
||||||
data = append([]byte{code}, data...)
|
tmp := make([]byte, len(data)+1)
|
||||||
_, err := s.socket.WriteToUDP(data, address)
|
tmp[0] = code
|
||||||
|
copy(tmp[1:], data)
|
||||||
|
_, err := s.socket.WriteToUDP(tmp, address)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +79,7 @@ func listen(port int) *net.UDPConn {
|
|||||||
|
|
||||||
// read is a blocking call which will read incoming packets and handle them.
|
// read is a blocking call which will read incoming packets and handle them.
|
||||||
func (s *Server) read() {
|
func (s *Server) read() {
|
||||||
buffer := make([]byte, 16384)
|
buffer := make([]byte, UDPDataMaxLength)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, addr, err := s.socket.ReadFromUDP(buffer)
|
n, addr, err := s.socket.ReadFromUDP(buffer)
|
||||||
@ -87,7 +95,7 @@ func (s *Server) read() {
|
|||||||
|
|
||||||
tmp := make([]byte, n)
|
tmp := make([]byte, n)
|
||||||
copy(tmp, buffer)
|
copy(tmp, buffer)
|
||||||
s.incoming <- &Packet{Data: tmp, Address: addr}
|
s.incoming <- Packet{Data: tmp, Address: addr}
|
||||||
s.packetCount++
|
s.packetCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
62
server/game/Server_test.go
Normal file
62
server/game/Server_test.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package game_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"server/game"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
code = byte(1)
|
||||||
|
data = []byte("Hello")
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkSendAppend(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
tmp := append([]byte{code}, data...)
|
||||||
|
noop(tmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSendCopy(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
tmp := make([]byte, len(data)+1)
|
||||||
|
tmp[0] = code
|
||||||
|
copy(tmp[1:], data)
|
||||||
|
noop(tmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func noop([]byte) {}
|
||||||
|
|
||||||
|
func BenchmarkReceivePointer(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
incoming := make(chan *game.Packet, 1)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
incoming <- &game.Packet{data, nil}
|
||||||
|
packet := <-incoming
|
||||||
|
|
||||||
|
if packet.Data[0] != 'H' {
|
||||||
|
b.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkReceiveValue(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
incoming := make(chan game.Packet, 1)
|
||||||
|
data := []byte("Hello")
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
incoming <- game.Packet{data, nil}
|
||||||
|
packet := <-incoming
|
||||||
|
|
||||||
|
if packet.Data[0] != 'H' {
|
||||||
|
b.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user