166 lines
3.9 KiB
Go
166 lines
3.9 KiB
Go
package net
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
|
|
"cellbot/internal/engine"
|
|
"cellbot/internal/protocol"
|
|
"github.com/valyala/fasthttp"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Server HTTP服务器
|
|
type Server struct {
|
|
host string
|
|
port int
|
|
logger *zap.Logger
|
|
botManager *protocol.BotManager
|
|
eventBus *engine.EventBus
|
|
server *fasthttp.Server
|
|
}
|
|
|
|
// NewServer 创建HTTP服务器
|
|
func NewServer(host string, port int, logger *zap.Logger, botManager *protocol.BotManager, eventBus *engine.EventBus) *Server {
|
|
return &Server{
|
|
host: host,
|
|
port: port,
|
|
logger: logger.Named("server"),
|
|
botManager: botManager,
|
|
eventBus: eventBus,
|
|
}
|
|
}
|
|
|
|
// Start 启动服务器
|
|
func (s *Server) Start() error {
|
|
s.server = &fasthttp.Server{
|
|
Handler: s.requestHandler,
|
|
MaxConnsPerIP: 1000,
|
|
MaxRequestsPerConn: 1000,
|
|
ReadTimeout: 0,
|
|
WriteTimeout: 0,
|
|
IdleTimeout: 0,
|
|
DisableKeepalive: false,
|
|
}
|
|
|
|
addr := net.JoinHostPort(s.host, strconv.Itoa(s.port))
|
|
s.logger.Info("Starting HTTP server", zap.String("address", addr))
|
|
|
|
go func() {
|
|
if err := s.server.ListenAndServe(addr); err != nil {
|
|
s.logger.Error("Server error", zap.Error(err))
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop 停止服务器
|
|
func (s *Server) Stop() error {
|
|
if s.server != nil {
|
|
s.logger.Info("Stopping HTTP server")
|
|
return s.server.Shutdown()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// requestHandler 请求处理器
|
|
func (s *Server) requestHandler(ctx *fasthttp.RequestCtx) {
|
|
path := string(ctx.Path())
|
|
method := string(ctx.Method())
|
|
|
|
s.logger.Debug("Received request",
|
|
zap.String("path", path),
|
|
zap.String("method", method))
|
|
|
|
// 路由处理
|
|
switch path {
|
|
case "/":
|
|
s.handleRoot(ctx)
|
|
case "/health":
|
|
s.handleHealth(ctx)
|
|
case "/bots":
|
|
s.handleBots(ctx)
|
|
case "/bots/create":
|
|
s.handleCreateBot(ctx)
|
|
case "/events/publish":
|
|
s.handlePublishEvent(ctx)
|
|
case "/events/subscribe":
|
|
s.handleSubscribeEvent(ctx)
|
|
default:
|
|
ctx.Error("Not Found", fasthttp.StatusNotFound)
|
|
}
|
|
}
|
|
|
|
// handleRoot 根路径处理
|
|
func (s *Server) handleRoot(ctx *fasthttp.RequestCtx) {
|
|
ctx.SetContentType("application/json")
|
|
ctx.SetBodyString(`{"message":"CellBot Server","version":"1.0.0"}`)
|
|
}
|
|
|
|
// handleHealth 健康检查
|
|
func (s *Server) handleHealth(ctx *fasthttp.RequestCtx) {
|
|
ctx.SetContentType("application/json")
|
|
ctx.SetBodyString(`{"status":"ok"}`)
|
|
}
|
|
|
|
// handleBots 获取机器人列表
|
|
func (s *Server) handleBots(ctx *fasthttp.RequestCtx) {
|
|
bots := s.botManager.GetAll()
|
|
ctx.SetContentType("application/json")
|
|
|
|
if len(bots) == 0 {
|
|
ctx.SetBodyString(`{"bots":[]}`)
|
|
return
|
|
}
|
|
|
|
// 简化实现,实际应该序列化完整信息
|
|
response := `{"bots":[`
|
|
for i, bot := range bots {
|
|
if i > 0 {
|
|
response += ","
|
|
}
|
|
response += fmt.Sprintf(`{"id":"%s","name":"%s","status":"%s"}`,
|
|
bot.GetID(), bot.Name(), bot.GetStatus())
|
|
}
|
|
response += `]}`
|
|
|
|
ctx.SetBodyString(response)
|
|
}
|
|
|
|
// handleCreateBot 创建机器人
|
|
func (s *Server) handleCreateBot(ctx *fasthttp.RequestCtx) {
|
|
if string(ctx.Method()) != "POST" {
|
|
ctx.Error("Method Not Allowed", fasthttp.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
ctx.SetContentType("application/json")
|
|
ctx.SetBodyString(`{"message":"Bot creation not implemented yet"}`)
|
|
}
|
|
|
|
// handlePublishEvent 发布事件
|
|
func (s *Server) handlePublishEvent(ctx *fasthttp.RequestCtx) {
|
|
if string(ctx.Method()) != "POST" {
|
|
ctx.Error("Method Not Allowed", fasthttp.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
// 解析请求体并发布事件
|
|
// 这里简化实现,实际应该解析JSON并创建Event
|
|
ctx.SetContentType("application/json")
|
|
ctx.SetBodyString(`{"message":"Event published"}`)
|
|
}
|
|
|
|
// handleSubscribeEvent 订阅事件
|
|
func (s *Server) handleSubscribeEvent(ctx *fasthttp.RequestCtx) {
|
|
if string(ctx.Method()) != "GET" {
|
|
ctx.Error("Method Not Allowed", fasthttp.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
ctx.SetContentType("application/json")
|
|
ctx.SetBodyString(`{"message":"Event subscription not implemented yet"}`)
|
|
}
|