Improved network communication
This commit is contained in:
6
server/core/Handler.go
Normal file
6
server/core/Handler.go
Normal file
@ -0,0 +1,6 @@
|
||||
package core
|
||||
|
||||
import "net"
|
||||
|
||||
// Handler is a byte code specific packet handler.
|
||||
type Handler func([]byte, *net.UDPAddr, *Server) error
|
103
server/core/Server.go
Normal file
103
server/core/Server.go
Normal file
@ -0,0 +1,103 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
// Server represents a UDP server.
|
||||
type Server struct {
|
||||
handlers [256]Handler
|
||||
socket *net.UDPConn
|
||||
packetCount int
|
||||
}
|
||||
|
||||
// New creates a new server.
|
||||
func New() *Server {
|
||||
return &Server{}
|
||||
}
|
||||
|
||||
// SetHandler sets the handler for the given byte code.
|
||||
func (s *Server) SetHandler(code byte, handler Handler) {
|
||||
s.handlers[code] = handler
|
||||
}
|
||||
|
||||
// Run starts the server on the given port.
|
||||
func (s *Server) Run(port int) {
|
||||
s.socket = listen(port)
|
||||
defer s.socket.Close()
|
||||
|
||||
s.read()
|
||||
}
|
||||
|
||||
// PacketCount returns the number of processed packets.
|
||||
func (s *Server) PacketCount() int {
|
||||
return s.packetCount
|
||||
}
|
||||
|
||||
// ResetPacketCount resets the number of processed packets to zero.
|
||||
func (s *Server) ResetPacketCount() {
|
||||
s.packetCount = 0
|
||||
}
|
||||
|
||||
// Send sends the data prefixed with the byte code to the client.
|
||||
func (s *Server) Send(code byte, data []byte, address *net.UDPAddr) error {
|
||||
data = append([]byte{code}, data...)
|
||||
_, err := s.socket.WriteToUDP(data, address)
|
||||
return err
|
||||
}
|
||||
|
||||
// listen creates a socket for the server and starts listening for incoming packets.
|
||||
func listen(port int) *net.UDPConn {
|
||||
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port))
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
connection, err := net.ListenUDP("udp", addr)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return connection
|
||||
}
|
||||
|
||||
// read is a blocking call which will read incoming packets and handle them.
|
||||
func (s *Server) read() {
|
||||
buffer := make([]byte, 4096)
|
||||
|
||||
for {
|
||||
n, addr, err := s.socket.ReadFromUDP(buffer)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from UDP connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
s.handle(buffer[:n], addr)
|
||||
}
|
||||
}
|
||||
|
||||
// handle deals with an incoming packet.
|
||||
func (s *Server) handle(data []byte, addr *net.UDPAddr) {
|
||||
handler := s.handlers[data[0]]
|
||||
|
||||
if handler == nil {
|
||||
fmt.Printf("No callback registered for packet type %d\n", data[0])
|
||||
return
|
||||
}
|
||||
|
||||
err := handler(data[1:], addr, s)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
s.packetCount++
|
||||
}
|
Reference in New Issue
Block a user