mirror of
https://github.com/Kyren223/eko.git
synced 2026-07-20 02:21:03 +00:00
feat: basic server connection handling
This commit is contained in:
@@ -3,13 +3,11 @@ package main
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/kyren223/eko/internal/server"
|
||||
"github.com/kyren223/eko/internal/utils/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetDefault(log.NewLogger("Server", os.Stdout, true))
|
||||
log.Debug("Eko 'Hello, World!'")
|
||||
log.Info("Eko 'Hello, World!'")
|
||||
log.Warn("Eko 'Hello, World!'")
|
||||
log.Error("Eko 'Hello, World!'")
|
||||
server.Start()
|
||||
}
|
||||
|
||||
32
internal/server/handler.go
Normal file
32
internal/server/handler.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/kyren223/eko/internal/utils/log"
|
||||
)
|
||||
|
||||
func handleClient(conn net.Conn, wg *sync.WaitGroup) {
|
||||
log.Info("Handling client... %v", conn.RemoteAddr().String())
|
||||
defer log.Info("Disconnecting client: %v", conn.RemoteAddr().String())
|
||||
defer conn.Close()
|
||||
defer wg.Done()
|
||||
|
||||
var request []byte
|
||||
n, err := conn.Read(request)
|
||||
if err != nil {
|
||||
log.Error("Failed reading: %v", err)
|
||||
return
|
||||
}
|
||||
log.Info("Read %v bytes: %v", n, string(request))
|
||||
|
||||
response := []byte("Server response")
|
||||
n, err = conn.Write(response)
|
||||
if err != nil {
|
||||
log.Error("Failed writing response: %v", err)
|
||||
return
|
||||
}
|
||||
log.Info("Responded successfully")
|
||||
}
|
||||
|
||||
79
internal/server/server.go
Normal file
79
internal/server/server.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/kyren223/eko/internal/utils/log"
|
||||
)
|
||||
|
||||
const PORT int = 7223
|
||||
|
||||
func Start() {
|
||||
server, err := NewServer(6969)
|
||||
if err != nil {
|
||||
log.Error("Unable to start server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
stopChan := make(chan os.Signal, 1)
|
||||
signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
wg.Add(1)
|
||||
go handleInterrupt(server, stopChan, &wg)
|
||||
|
||||
server.Listen()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func handleInterrupt(server *Server, stopChan <-chan os.Signal, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
<-stopChan
|
||||
log.Info("Interrupt Occurred")
|
||||
log.Info("Shutting down server...")
|
||||
server.Close()
|
||||
log.Info("Waiting for all connections to close")
|
||||
server.Wait()
|
||||
log.Info("Server has been shutdown")
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
listener net.Listener
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewServer(port int) (*Server, error) {
|
||||
listener, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Info("Created server on port %v", port)
|
||||
return &Server{listener, sync.WaitGroup{}}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Listen() {
|
||||
log.Info("Server started listening... %v", s.listener.Addr().String())
|
||||
for {
|
||||
conn, err := s.listener.Accept()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
s.wg.Add(1)
|
||||
go handleClient(conn, &s.wg)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop stops the server. The blocked Listen call will be unlocked
|
||||
func (s *Server) Close() {
|
||||
s.listener.Close()
|
||||
}
|
||||
|
||||
// Wait blocks until all active connections to the server are done
|
||||
func (s *Server) Wait() {
|
||||
s.wg.Wait()
|
||||
}
|
||||
@@ -10,17 +10,17 @@ func SetDefault(l *Logger) {
|
||||
}
|
||||
|
||||
func Debug(message string, a ...any) error {
|
||||
return logger.Log(LevelDebug, message, a)
|
||||
return logger.Debug(message, a...)
|
||||
}
|
||||
|
||||
func Info(message string, a ...any) error {
|
||||
return logger.Log(LevelInfo, message, a)
|
||||
return logger.Info(message, a...)
|
||||
}
|
||||
|
||||
func Warn(message string, a ...any) error {
|
||||
return logger.Log(LevelWarn, message, a)
|
||||
return logger.Warn(message, a...)
|
||||
}
|
||||
|
||||
func Error(message string, a ...any) error {
|
||||
return logger.Log(LevelError, message, a)
|
||||
return logger.Error(message, a...)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
@@ -29,27 +28,28 @@ func (l *Logger) Log(level Level, message string, a ...any) error {
|
||||
|
||||
timestamp := time.Now().Format(time.TimeOnly)
|
||||
severity := level.String()
|
||||
formattedMessage := fmt.Sprintf(message, a...)
|
||||
|
||||
// TODO: add support for ANSI coloring
|
||||
l.mu.Lock()
|
||||
_, err := fmt.Fprintf(l.writer, "[%s] [%s/%s]: %s\n", timestamp, l.name, severity, message, a)
|
||||
_, err := fmt.Fprintf(l.writer, "[%s] [%s/%s]: %s\n", timestamp, l.name, severity, formattedMessage)
|
||||
l.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(message string, a ...any) error {
|
||||
return l.Log(LevelDebug, message, a)
|
||||
return l.Log(LevelDebug, message, a...)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(message string, a ...any) error {
|
||||
return l.Log(LevelInfo, message, a)
|
||||
return l.Log(LevelInfo, message, a...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(message string, a ...any) error {
|
||||
return l.Log(LevelWarn, message, a)
|
||||
return l.Log(LevelWarn, message, a...)
|
||||
}
|
||||
|
||||
func (l *Logger) Error(message string, a ...any) error {
|
||||
return l.Log(LevelError, message, a)
|
||||
return l.Log(LevelError, message, a...)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user