//go:build server || (!server && !client) package main import ( "log" "os" "os/signal" "syscall" internalinterceptor "github.com/noahlann/nnet/internal/interceptor" "github.com/noahlann/nnet/internal/interceptor/builtin" "github.com/noahlann/nnet/pkg/interceptor" "github.com/noahlann/nnet/pkg/nnet" routerpkg "github.com/noahlann/nnet/pkg/router" ) // This example demonstrates interceptor chain usage. // Interceptors can validate, transform, or filter data before it reaches handlers. func main() { cfg := &nnet.Config{ Addr: "tcp://:8084", Codec: &nnet.CodecConfig{ DefaultCodec: "json", EnableProtocolEncode: false, }, } srv, err := nnet.NewServer(cfg) if err != nil { log.Fatal("create server:", err) } // 创建拦截器链 // 拦截器1:最小长度验证(至少5字节) minLenInterceptor := builtin.MinLengthInterceptor(5) // 拦截器2:最大长度验证(最多100字节) maxLenInterceptor := builtin.MaxLengthInterceptor(100) // 拦截器3:自定义验证拦截器(验证数据不为空且不为"forbidden") customInterceptor := interceptor.HandlerFunc(func(data []byte, ctx nnet.Context, next interceptor.Chain) ([]byte, bool, error) { if len(data) == 0 { return nil, false, interceptor.New("data cannot be empty") } if string(data) == "forbidden" { return nil, false, interceptor.New("forbidden data") } // 记录到上下文 ctx.Set("intercepted", true) ctx.Set("data_length", len(data)) return next.Next(data, ctx) }) // 使用自定义匹配器,匹配所有请求并在handler中应用拦截器 // 路由1:验证端点(使用拦截器链) srv.Router().RegisterCustom( func(input routerpkg.MatchInput, ctx nnet.Context) bool { data := input.Raw // 匹配以"validate"开头的数据 return len(data) >= 8 && string(data[:8]) == "validate" }, func(ctx nnet.Context) error { rawData := ctx.Request().Raw() // 提取实际数据(跳过"validate"命令) var actualData []byte if len(rawData) > 8 { actualData = rawData[8:] // 跳过空格或换行 for len(actualData) > 0 && (actualData[0] == ' ' || actualData[0] == '\n') { actualData = actualData[1:] } } // 如果没有数据,使用默认测试数据 if len(actualData) == 0 { actualData = []byte("test data for validation") } // 执行拦截器链 interceptors := []interceptor.Interceptor{ minLenInterceptor, maxLenInterceptor, customInterceptor, } data, continueProcessing, err := internalinterceptor.Execute(actualData, ctx, interceptors...) if err != nil { return ctx.Response().Write(map[string]any{ "error": err.Error(), "valid": false, "message": "validation failed", }) } if !continueProcessing { return ctx.Response().Write(map[string]any{ "error": "processing stopped", "valid": false, }) } // 获取拦截器设置的值 intercepted := ctx.GetBool("intercepted") dataLength := ctx.GetInt("data_length") return ctx.Response().Write(map[string]any{ "valid": true, "data": string(data), "intercepted": intercepted, "data_length": dataLength, "message": "validation passed", }) }, ) // 路由2:简单的echo srv.Router().RegisterString("echo", func(ctx nnet.Context) error { data := ctx.Request().Raw() return ctx.Response().Write(map[string]any{ "echo": string(data), }) }) // 路由3:测试端点(使用最小长度拦截器) srv.Router().RegisterString("test", func(ctx nnet.Context) error { rawData := ctx.Request().Raw() // 只使用最小长度拦截器 data, continueProcessing, err := internalinterceptor.Execute(rawData, ctx, minLenInterceptor) if err != nil { return ctx.Response().Write(map[string]any{ "error": err.Error(), "valid": false, }) } if !continueProcessing { return ctx.Response().Write(map[string]any{ "error": "processing stopped", "valid": false, }) } return ctx.Response().Write(map[string]any{ "valid": true, "data": string(data), }) }) log.Println("interceptor_server listening on :8084") log.Println("Interceptors:") log.Println(" - MinLengthInterceptor (min: 5 bytes)") log.Println(" - MaxLengthInterceptor (max: 100 bytes)") log.Println(" - CustomInterceptor (rejects 'forbidden')") if err := srv.Start(); err != nil { log.Fatal("start server:", err) } defer srv.Stop() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit }