├── demo ├── logs │ ├── log │ ├── log.20191109.log │ └── log.20191106.log ├── toml │ └── user.toml ├── swaggerui │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── index.html │ ├── oauth2-redirect.html │ └── swagger.json ├── docker │ ├── build.sh │ ├── docker-compose.yml │ └── Dockerfile ├── test │ ├── di_test │ │ ├── demo │ │ │ ├── people_interface.go │ │ │ └── man.go │ │ └── di_test.go │ ├── str_test │ │ └── str_test.go │ ├── timer │ │ └── timer_test.go │ ├── toml │ │ └── toml_test.go │ ├── client │ │ └── client_test.go │ ├── json_demo │ │ └── json_test.go │ ├── ctx │ │ └── ctx_test.go │ ├── token │ │ └── token_test.go │ ├── mytest │ │ └── my_test.go │ ├── mqtt │ │ └── mqtt_test.go │ ├── extends │ │ └── extend_test.go │ ├── queue │ │ └── queue_test.go │ ├── num │ │ └── num_test.go │ ├── ctl │ │ └── controller_test.go │ ├── json_str │ │ └── json_test.go │ ├── conver │ │ └── conver_test.go │ ├── mgo │ │ └── mgo_test.go │ ├── reflect_test │ │ └── reflect_test.go │ └── xorm │ │ └── xorm_test.go ├── src │ ├── service │ │ ├── two_service.go │ │ ├── one_service.go │ │ ├── parallel_two.go │ │ ├── parallel_one.go │ │ └── sql_service.go │ ├── controller │ │ ├── sleep_controller.go │ │ ├── auth_controller.go │ │ ├── sql_controller.go │ │ ├── event_controller.go │ │ ├── queue_controller.go │ │ ├── publish_controller.go │ │ ├── queue2_controller.go │ │ ├── cache_set_controller.go │ │ ├── consul_controller.go │ │ ├── valid_controller.go │ │ ├── cache_get_controller.go │ │ ├── redis_controller.go │ │ ├── mqtt_event_controller.go │ │ ├── parallel_controller.go │ │ ├── two_controller.go │ │ ├── post_controller.go │ │ └── one_controller.go │ ├── model │ │ ├── comm_demo.go │ │ └── comm_user_info.go │ ├── router │ │ ├── command_router.go │ │ ├── cron_router.go │ │ ├── queue_router.go │ │ ├── websocket_router.go │ │ ├── grpc_router.go │ │ ├── timer_router.go │ │ ├── subscribe_router.go │ │ └── http_router.go │ ├── dto │ │ ├── queue_dto.go │ │ └── test_dto.go │ ├── fsm │ │ └── user_fsm.go │ └── provider │ │ └── demo_provider.go ├── go.mod ├── env.toml └── main.go ├── constants ├── dto.go ├── code.go ├── time_format.go └── error.go ├── contracts ├── mock_interface.go ├── valid_interface.go ├── service_interface.go ├── provider_interface.go ├── router_interface.go ├── filter_interface.go ├── controller_interface.go ├── logger_interface.go ├── message_struct.go └── context.go ├── servers ├── queues │ ├── job.go │ ├── payload.go │ ├── signal_stop.go │ ├── client.go │ ├── signals.go │ ├── helper.go │ └── server.go ├── events │ ├── helper.go │ ├── event.go │ └── server.go ├── transports │ ├── protobuf │ │ └── message.go.proto │ ├── cron_transport.go │ ├── timer_transport.go │ ├── command_transport.go │ ├── queue_transport.go │ ├── grpc_transport.go │ ├── websocket_transport.go │ ├── http_transport.go │ ├── mqtt_subscribe_transport.go │ └── codecs │ │ ├── timer_codec.go │ │ ├── queue_codec.go │ │ ├── websocket_codec.go │ │ ├── cron_codec.go │ │ ├── command_codec.go │ │ ├── mqtt_codec.go │ │ ├── gprc_codec.go │ │ └── http_codec.go ├── commons │ ├── comm_handler.go │ └── Server.go ├── mqtts │ ├── publish.go │ ├── ins.go │ └── subscribe_server.go ├── cronjobs │ └── server.go ├── command_comm_server.go ├── gateway_comm_server.go ├── timer_comm_server.go ├── event_comm_server.go ├── websocket_comm_server.go ├── mqtt_subscribe_comm_server.go ├── commands │ └── server.go ├── queue_comm_server.go ├── cron_comm_server.go ├── gateways │ ├── maxBytesReader.go │ ├── server.go │ └── codec.go ├── timers │ └── server.go ├── http_comm_server.go ├── websockets │ └── server.go └── grpc_comm_server.go ├── tools ├── idwork │ ├── helper.go │ └── worker.go ├── jwt │ ├── claims.go │ └── token.go ├── util │ └── md5.go ├── errors │ └── error.go ├── tests │ └── test.go ├── helpers.go ├── convert │ └── convert.go └── local_time.go ├── container ├── ins.go └── container.go ├── loggers ├── logger.go ├── ins.go └── logrus_log.go ├── configs ├── cache_config.go ├── token_config.go ├── event_config.go ├── grpc_config.go ├── http_config.go ├── log_config.go ├── websocket_config.go ├── queue_config.go ├── redis_config.go ├── mqtt_config.go ├── mongo_config.go ├── mysql_config.go └── init.go ├── filters ├── helpers.go ├── health_endpoint.go ├── filter.go ├── limit_endpoint.go ├── Jwt_endpoint.go ├── gateway_endpoint.go ├── response_endpoint.go └── comm_endpoint.go ├── clients ├── helpers.go ├── mysql │ ├── ins.go │ └── helper.go ├── http.go ├── service.go ├── mongo │ └── session.go ├── redis │ └── pool_ins.go ├── grpc.go └── consul.go ├── validations ├── helpers.go └── util.go ├── args └── init.go ├── providers └── consul_registy_provider.go ├── cache └── ins.go ├── services └── service.go ├── go.mod └── wego.go /demo/logs/log: -------------------------------------------------------------------------------- 1 | logs/log.20191109.log -------------------------------------------------------------------------------- /demo/toml/user.toml: -------------------------------------------------------------------------------- 1 | [type] 2 | register ="注册用户" 3 | -------------------------------------------------------------------------------- /constants/dto.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const RequestDto = "REQUEST_DTO" 4 | -------------------------------------------------------------------------------- /constants/code.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | type Code struct { 4 | Code string 5 | Msg string 6 | } 7 | -------------------------------------------------------------------------------- /contracts/mock_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IMock interface { 4 | Mock() interface{} 5 | } 6 | -------------------------------------------------------------------------------- /demo/swaggerui/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9299381/wego/HEAD/demo/swaggerui/favicon-16x16.png -------------------------------------------------------------------------------- /demo/swaggerui/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9299381/wego/HEAD/demo/swaggerui/favicon-32x32.png -------------------------------------------------------------------------------- /contracts/valid_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IValid interface { 4 | GetRules() interface{} 5 | } 6 | -------------------------------------------------------------------------------- /servers/queues/job.go: -------------------------------------------------------------------------------- 1 | package queues 2 | 3 | type Job struct { 4 | Queue string 5 | Payload Payload 6 | } 7 | -------------------------------------------------------------------------------- /contracts/service_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IService interface { 4 | Handle(ctx Context) error 5 | } 6 | -------------------------------------------------------------------------------- /demo/docker/build.sh: -------------------------------------------------------------------------------- 1 | GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -o main main.go && 2 | docker image build -t demo_app ./docker -------------------------------------------------------------------------------- /demo/test/di_test/demo/people_interface.go: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | type IPeople interface { 4 | Work() 5 | Write(string) string 6 | } 7 | -------------------------------------------------------------------------------- /contracts/provider_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IProvider interface { 4 | Register() //在这里注册路由 5 | Boot() //加载配置文件等 6 | } 7 | -------------------------------------------------------------------------------- /contracts/router_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IRouter interface { 4 | Boot() 5 | Load() 6 | Register() 7 | Start() error 8 | Close() 9 | } 10 | -------------------------------------------------------------------------------- /demo/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | demo_app: 4 | build: 5 | context: . 6 | ports: 7 | - 8341:8341 8 | command: /home/main 9 | -------------------------------------------------------------------------------- /demo/logs/log.20191109.log: -------------------------------------------------------------------------------- 1 | {"level":"info","msg":"Http Server Start :8341","time":"2019-11-09 15:52:26"} 2 | {"level":"info","msg":"interrupt","time":"2019-11-09 15:53:02"} 3 | -------------------------------------------------------------------------------- /servers/queues/payload.go: -------------------------------------------------------------------------------- 1 | package queues 2 | 3 | type Payload struct { 4 | Route string `json:"route"` 5 | Params map[string]interface{} `json:"params"` 6 | } 7 | -------------------------------------------------------------------------------- /constants/time_format.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const YmdHis = "2006-01-02 15:04:05" 4 | const YmdHi = "2006-01-02 15:04" 5 | const YmdH = "2006-01-02 15" 6 | const Ymd = "2006-01-02" 7 | -------------------------------------------------------------------------------- /tools/idwork/helper.go: -------------------------------------------------------------------------------- 1 | package idwork 2 | 3 | import ( 4 | "github.com/9299381/wego/configs" 5 | ) 6 | 7 | func ID() string { 8 | return getID(int64(configs.EnvInt("server_id", 512))) 9 | } 10 | -------------------------------------------------------------------------------- /contracts/filter_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | import "github.com/go-kit/kit/endpoint" 4 | 5 | type IFilter interface { 6 | Next(next endpoint.Endpoint) IFilter 7 | Make() endpoint.Endpoint 8 | } 9 | -------------------------------------------------------------------------------- /servers/queues/signal_stop.go: -------------------------------------------------------------------------------- 1 | // +build go1.1 2 | 3 | package queues 4 | 5 | import ( 6 | "os" 7 | "os/signal" 8 | ) 9 | 10 | func signalStop(c chan<- os.Signal) { 11 | signal.Stop(c) 12 | } 13 | -------------------------------------------------------------------------------- /tools/jwt/claims.go: -------------------------------------------------------------------------------- 1 | package jwt 2 | 3 | type Claims struct { 4 | Id string `json:"id"` 5 | Name string `json:"name"` 6 | Role string `json:"role"` 7 | Iat int64 `json:"iat"` 8 | Exp int64 `json:"exp"` 9 | } 10 | -------------------------------------------------------------------------------- /container/ins.go: -------------------------------------------------------------------------------- 1 | package container 2 | 3 | import "sync" 4 | 5 | var ins *Container 6 | var once sync.Once 7 | 8 | func GetIns() *Container { 9 | once.Do(func() { 10 | ins = NewContainer() 11 | }) 12 | return ins 13 | } 14 | -------------------------------------------------------------------------------- /demo/test/str_test/str_test.go: -------------------------------------------------------------------------------- 1 | package str_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestString(t *testing.T) { 9 | str := "a.b.c" 10 | ret := strings.ReplaceAll(str, ".", "/") 11 | t.Log(ret) 12 | } 13 | -------------------------------------------------------------------------------- /tools/util/md5.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | ) 7 | 8 | func Md5(plain string) string { 9 | h := md5.New() 10 | h.Write([]byte(plain)) 11 | return hex.EncodeToString(h.Sum(nil)) 12 | } 13 | -------------------------------------------------------------------------------- /loggers/logger.go: -------------------------------------------------------------------------------- 1 | package loggers 2 | 3 | import ( 4 | "github.com/sirupsen/logrus" 5 | ) 6 | 7 | type logger struct { 8 | *logrus.Logger 9 | } 10 | 11 | func (s logger) Log(keyvals ...interface{}) error { 12 | s.Info(keyvals) 13 | return nil 14 | } 15 | -------------------------------------------------------------------------------- /configs/cache_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type CacheConfig struct { 4 | Size int `json:"size"` 5 | } 6 | 7 | func LoadCacheConfig() *CacheConfig { 8 | 9 | config := &CacheConfig{ 10 | Size: EnvInt("cache.size", 1048576), 11 | } 12 | return config 13 | } 14 | -------------------------------------------------------------------------------- /container/container.go: -------------------------------------------------------------------------------- 1 | package container 2 | 3 | import "github.com/go-macaron/inject" 4 | 5 | type Container struct { 6 | inject.Injector 7 | } 8 | 9 | func NewContainer() *Container { 10 | injector := inject.New() 11 | return &Container{ 12 | Injector: injector, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/test/timer/timer_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/tools" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestTimer(t *testing.T) { 11 | now := tools.LocalTime(time.Now()) 12 | n := fmt.Sprintf("%s", now) 13 | fmt.Println(n) 14 | } 15 | -------------------------------------------------------------------------------- /demo/src/service/two_service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | ) 6 | 7 | type TwoService struct { 8 | } 9 | 10 | func (s *TwoService) Handle(ctx contracts.Context) error { 11 | 12 | ctx.Set("one", "tow") 13 | ctx.Log.Info("two......") 14 | return nil 15 | } 16 | -------------------------------------------------------------------------------- /demo/test/toml/toml_test.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego" 6 | "testing" 7 | ) 8 | 9 | func TestToml(t *testing.T) { 10 | // 加载过程 11 | wego.Toml("user", "user") 12 | // 读取过程 13 | level := wego.Toml("user").GetString("type.register") 14 | fmt.Println(level) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /servers/events/helper.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | ) 6 | 7 | func Fire(payload *contracts.Payload) { 8 | //发送事件需要判断是否有处理器,否则不处理 9 | _, isExist := Handlers[payload.Route] 10 | if isExist { 11 | event := newEvent(payload) 12 | addEvent(event) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /demo/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # 基础镜像 2 | FROM scratch 3 | # 镜像作者 4 | MAINTAINER 9299381@qq.com 5 | 6 | # 复制文件或目录到容器指定路径中 7 | COPY . /home 8 | 9 | # 容器对外映射的本地端口,需要在 docker run 的时候使用-p或者-P选项生效 10 | EXPOSE 8341 11 | 12 | 13 | # 为后续的RUN、CMD、ENTRYPOINT指令配置工作目录 14 | WORKDIR /home 15 | 16 | # 在启动容器时提供一个命令执行选项,这里运行我们的应用 17 | #CMD ["/home/main"] -------------------------------------------------------------------------------- /demo/test/client/client_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "testing" 6 | ) 7 | 8 | func TestClientService(t *testing.T) { 9 | param := make(map[string]interface{}) 10 | resp := clients.Service("demo"). 11 | Api("demo.post"). 12 | Params(param). 13 | Run() 14 | 15 | t.Log(resp) 16 | } 17 | -------------------------------------------------------------------------------- /servers/transports/protobuf/message.go.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package protobuf; 4 | 5 | service Service{ 6 | rpc Handle(Request) returns (Response) {} 7 | } 8 | 9 | message Request { 10 | string id = 1; 11 | string param = 2; 12 | } 13 | message Response { 14 | string code = 1; 15 | string msg = 2; 16 | string data = 3; 17 | } -------------------------------------------------------------------------------- /configs/token_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type TokenConfig struct { 4 | Key string `json:"key"` 5 | Exp int64 `json:"exp"` 6 | } 7 | 8 | func LoadTokenConfig() *TokenConfig { 9 | config := &TokenConfig{ 10 | Key: EnvString("token.key", "EHKHHP54PXKYTS2E"), 11 | Exp: int64(EnvInt("token.exp", 2592000)), 12 | } 13 | return config 14 | } 15 | -------------------------------------------------------------------------------- /demo/test/di_test/demo/man.go: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type Man struct { 9 | } 10 | 11 | func (s *Man) Work() { 12 | fmt.Println("man working") 13 | } 14 | func (s *Man) Write(content string) string { 15 | str := "man write something" 16 | ret := strings.Join([]string{str, content}, ":") 17 | return ret 18 | } 19 | -------------------------------------------------------------------------------- /filters/helpers.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/go-kit/kit/endpoint" 6 | ) 7 | 8 | func Chain(endpoints ...contracts.IFilter) endpoint.Endpoint { 9 | len := len(endpoints) - 1 10 | for i := 0; i < len; i++ { 11 | endpoints[i].Next(endpoints[i+1].Make()) 12 | } 13 | return endpoints[0].Make() 14 | } 15 | -------------------------------------------------------------------------------- /configs/event_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type EventConfig struct { 4 | Concurrency int `json:"concurrency"` 5 | After int `json:"after"` 6 | } 7 | 8 | func LoadEventConfig() *EventConfig { 9 | 10 | config := &EventConfig{ 11 | Concurrency: EnvInt("event.concurrency", 1), 12 | After: EnvInt("event.after", 1), 13 | } 14 | return config 15 | } 16 | -------------------------------------------------------------------------------- /demo/test/json_demo/json_test.go: -------------------------------------------------------------------------------- 1 | package json_demo 2 | 3 | import ( 4 | "github.com/tidwall/gjson" 5 | "testing" 6 | ) 7 | 8 | /** 9 | https://www.jianshu.com/p/623f8ca5ec12 10 | */ 11 | func TestJson(t *testing.T) { 12 | const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}` 13 | value := gjson.Get(json, "name.last").Str 14 | println(value) 15 | } 16 | -------------------------------------------------------------------------------- /demo/test/ctx/ctx_test.go: -------------------------------------------------------------------------------- 1 | package ctx 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | "testing" 7 | ) 8 | 9 | func TestContext(t *testing.T) { 10 | ctx := &contracts.Context{ 11 | Keys: make(map[string]interface{}), 12 | } 13 | 14 | ctx.Set("a", "1") 15 | ctx.Set("a.b", "2") 16 | //ctx.Set("a", "2") 17 | fmt.Println(ctx.Get("a")) 18 | } 19 | -------------------------------------------------------------------------------- /configs/grpc_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type GrpcConfig struct { 4 | GrpcHost string `json:"grpc_host"` 5 | GrpcPort string `json:"grpc_port"` 6 | } 7 | 8 | func LoadGrpcConfig() *GrpcConfig { 9 | config := &GrpcConfig{ 10 | GrpcHost: EnvString("server.grpc_host", "127.0.0.1"), 11 | GrpcPort: EnvString("server.grpc_port", "9341"), 12 | } 13 | return config 14 | } 15 | -------------------------------------------------------------------------------- /configs/http_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type HttpConfig struct { 4 | HttpHost string `json:"http_host"` 5 | HttpPort string `json:"http_port"` 6 | } 7 | 8 | func LoadHttpConfig() *HttpConfig { 9 | config := &HttpConfig{ 10 | HttpHost: EnvString("server.http_host", "127.0.0.1"), 11 | HttpPort: EnvString("server.http_port", "8341"), 12 | } 13 | return config 14 | } 15 | -------------------------------------------------------------------------------- /configs/log_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type LogConfig struct { 4 | LogFilePath string `json:"log_file_path"` 5 | LogFileName string `json:"log_file_name"` 6 | } 7 | 8 | func LoadLogConfig() *LogConfig { 9 | config := &LogConfig{ 10 | LogFilePath: EnvString("log.file_path", "./logs"), 11 | LogFileName: EnvString("log.file_name", "log"), 12 | } 13 | 14 | return config 15 | } 16 | -------------------------------------------------------------------------------- /demo/src/service/one_service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | ) 6 | 7 | type OneService struct { 8 | } 9 | 10 | func (s *OneService) Handle(ctx contracts.Context) error { 11 | ctx.Log.Info("one....") 12 | ctx.Set("k.a", "a") 13 | ctx.Set("k.b", "b") 14 | ctx.Set("k.a", "b") 15 | 16 | ctx.Log.Info(ctx.Get("k")) 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /demo/src/controller/sleep_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "time" 6 | ) 7 | 8 | //用于测试并行,串行 9 | type SleepController struct { 10 | } 11 | 12 | func (s *SleepController) Handle(ctx contracts.Context) (interface{}, error) { 13 | 14 | time.Sleep(10 * time.Second) 15 | ctx.Log.Info("sleep ......") 16 | 17 | return nil, nil 18 | } 19 | -------------------------------------------------------------------------------- /demo/src/controller/auth_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | type AuthController struct { 9 | } 10 | 11 | func (s *AuthController) Handle(ctx contracts.Context) (interface{}, error) { 12 | 13 | fmt.Println(ctx.Get("request.claim.Id")) 14 | fmt.Println(ctx.Get("request.claim.Name")) 15 | 16 | return nil, nil 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/service/parallel_two.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | type ParallelTwo struct { 9 | } 10 | 11 | func (s *ParallelTwo) Handle(ctx contracts.Context) error { 12 | ctx.Log.Info(ctx.Get("controller")) 13 | fmt.Println("two~~~~~~~~~~~~") 14 | ctx.Set("aaa", "ccc") 15 | ctx.Set("two", "two") 16 | 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /demo/src/model/comm_demo.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type CommDemoModel struct { 4 | Id string `xorm:"pk varchar(21) notnull unique 'id'" json:"id"` 5 | NumInt1 int `xorm:"int(11)" json:"num_int1"` 6 | NumInt2 int `xorm:"bigint(20)" json:"num_int2"` 7 | NumBig int64 `xorm:"bigint(20)" json:"num_big"` 8 | } 9 | 10 | func (s *CommDemoModel) TableName() string { 11 | return "comm_demo" 12 | } 13 | -------------------------------------------------------------------------------- /tools/errors/error.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import "strings" 4 | 5 | func Code(code string, text string) error { 6 | return &Error{Code: code, Message: text} 7 | } 8 | 9 | // errorString is a trivial implementation of error. 10 | type Error struct { 11 | Code string 12 | Message string 13 | } 14 | 15 | func (e *Error) Error() string { 16 | return strings.Join([]string{e.Code, e.Message}, "::") 17 | } 18 | -------------------------------------------------------------------------------- /servers/transports/cron_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewCronJob(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.CronDecodeRequest, 13 | codecs.CronEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /servers/transports/timer_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewTimer(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.TimerDecodeRequest, 13 | codecs.TimerEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /contracts/controller_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type IController interface { 4 | Handle(ctx Context) (interface{}, error) 5 | } 6 | 7 | type Controller struct { 8 | } 9 | 10 | func (s *Controller) Handle(ctx Context) (interface{}, error) { 11 | return nil, nil 12 | } 13 | func (s *Controller) GetRules() interface{} { 14 | return nil 15 | } 16 | func (s *Controller) Mock() interface{} { 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /demo/src/service/parallel_one.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | type ParallelOne struct { 9 | } 10 | 11 | func (s *ParallelOne) Handle(ctx contracts.Context) error { 12 | ctx.Log.Info(ctx.Get("controller")) 13 | fmt.Println("one~~~~~~~~~~~~") 14 | ctx.Set("aaa", "bbb") 15 | ctx.Set("one", "one") 16 | //return errors.New("error") 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /servers/transports/command_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewCommand(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.CommandDecodeRequest, 13 | codecs.CommandEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /servers/transports/queue_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewQueue(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.QueueServerDecodeRequest, 13 | codecs.QueueServerEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /servers/transports/grpc_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/transports/codecs" 5 | "github.com/go-kit/kit/endpoint" 6 | GrpcTransport "github.com/go-kit/kit/transport/grpc" 7 | ) 8 | 9 | func NewGRPC(endpoint endpoint.Endpoint) *GrpcTransport.Server { 10 | return GrpcTransport.NewServer( 11 | endpoint, 12 | codecs.GprcDecodeRequest, 13 | codecs.GprcEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /servers/transports/websocket_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewWebSocket(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.WebSocketDecodeRequest, 13 | codecs.WebSocketEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /servers/transports/http_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/transports/codecs" 5 | "github.com/go-kit/kit/endpoint" 6 | HttpTransport "github.com/go-kit/kit/transport/http" 7 | ) 8 | 9 | func NewHTTP(endpoint endpoint.Endpoint) *HttpTransport.Server { 10 | return HttpTransport.NewServer( 11 | endpoint, 12 | codecs.HttpFormDecodeRequest, 13 | codecs.HttpEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /clients/helpers.go: -------------------------------------------------------------------------------- 1 | package clients 2 | 3 | import ( 4 | "github.com/9299381/wego/clients/mysql" 5 | "github.com/9299381/wego/clients/redis" 6 | redigo "github.com/gomodule/redigo/redis" 7 | "xorm.io/xorm" 8 | ) 9 | 10 | func DB() *xorm.Engine { 11 | return mysql.GetDB() 12 | } 13 | 14 | func Redis() redigo.Conn { 15 | return redis.GetRedisPool().Get() 16 | } 17 | 18 | func RedisPool() *redigo.Pool { 19 | return redis.GetRedisPool() 20 | } 21 | -------------------------------------------------------------------------------- /loggers/ins.go: -------------------------------------------------------------------------------- 1 | package loggers 2 | 3 | import ( 4 | "github.com/go-kit/kit/log" 5 | "github.com/sirupsen/logrus" 6 | "sync" 7 | ) 8 | 9 | var ins *logrus.Logger 10 | var once sync.Once 11 | 12 | func GetLog() *logrus.Logger { 13 | once.Do(func() { 14 | ins = newLogrus() 15 | }) 16 | return ins 17 | } 18 | 19 | // log.logger 接口的一种实现,用以注入 go-kit 的服务注册 20 | func NewKitLog() log.Logger { 21 | return logger{ 22 | Logger: GetLog(), 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /servers/transports/mqtt_subscribe_transport.go: -------------------------------------------------------------------------------- 1 | package transports 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/transports/codecs" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | func NewMqttSubscribe(endpoint endpoint.Endpoint) *commons.Server { 10 | return commons.NewServer( 11 | endpoint, 12 | codecs.MqttSubscribeDecodeRequest, 13 | codecs.MqttSubscribeEncodeResponse, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /demo/test/token/token_test.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/tools/jwt" 6 | "testing" 7 | ) 8 | 9 | func TestToken(t *testing.T) { 10 | token := jwt.New(). 11 | SetId("123"). 12 | SetName("abc"). 13 | SetRole("p1101"). 14 | GetToken() 15 | //eyJpZCI6IjEyMyIsIm5hbWUiOiJhYmMiLCJyb2xlIjoicDExMDEiLCJpYXQiOjE1Njk1NzkwOTQsImV4cCI6MTU3MjE3MTA5NH0=.228a1c01bdce8cd3405d2295d7a2eb30 16 | fmt.Println(token) 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/router/command_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type CommandRouter struct { 9 | *servers.CommandCommServer 10 | } 11 | 12 | func (s *CommandRouter) Boot() { 13 | s.CommandCommServer = servers.NewCommandCommServer() 14 | } 15 | 16 | //todo 写个队列server 编解码,路由等 17 | 18 | func (s *CommandRouter) Register() { 19 | s.Route("cmd_test", wego.Handler("two")) 20 | } 21 | -------------------------------------------------------------------------------- /servers/queues/client.go: -------------------------------------------------------------------------------- 1 | package queues 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/gomodule/redigo/redis" 7 | ) 8 | 9 | func Enqueue(conn redis.Conn, job *Job, prefix string) error { 10 | buffer, err := json.Marshal(job.Payload) 11 | if err != nil { 12 | return err 13 | } 14 | err = conn.Send("RPUSH", fmt.Sprintf("%s_queue:%s", prefix, job.Queue), buffer) 15 | if err != nil { 16 | return err 17 | } 18 | return conn.Flush() 19 | } 20 | -------------------------------------------------------------------------------- /servers/queues/signals.go: -------------------------------------------------------------------------------- 1 | package queues 2 | 3 | import ( 4 | "os" 5 | "os/signal" 6 | "syscall" 7 | ) 8 | 9 | func signals() <-chan bool { 10 | quit := make(chan bool) 11 | 12 | go func() { 13 | signals := make(chan os.Signal) 14 | defer close(signals) 15 | 16 | signal.Notify(signals, syscall.SIGQUIT, syscall.SIGTERM, os.Interrupt) 17 | defer signalStop(signals) 18 | 19 | <-signals 20 | quit <- true 21 | }() 22 | 23 | return quit 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/controller/sql_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/demo/src/service" 6 | "github.com/9299381/wego/services" 7 | ) 8 | 9 | type SqlController struct { 10 | } 11 | 12 | func (s *SqlController) Handle(ctx contracts.Context) (interface{}, error) { 13 | _ = services.Pipe().Middle(&service.SqlService{}).Line(ctx) 14 | ret := ctx.Get("user") 15 | return ret, nil 16 | 17 | } 18 | -------------------------------------------------------------------------------- /demo/src/router/cron_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type CronRouter struct { 9 | *servers.CronCommServer 10 | } 11 | 12 | func (s *CronRouter) Boot() { 13 | s.CronCommServer = servers.NewCronCommServer() 14 | } 15 | 16 | func (s *CronRouter) Register() { 17 | 18 | s.Route("*/5 * * * * *", wego.Handler("one")) 19 | s.Route("*/2 * * * * *", wego.Handler("two")) 20 | } 21 | -------------------------------------------------------------------------------- /demo/src/router/queue_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type QueueRouter struct { 9 | *servers.QueueCommServer 10 | } 11 | 12 | func (s *QueueRouter) Boot() { 13 | s.QueueCommServer = servers.NewQueueCommServer() 14 | } 15 | 16 | func (s *QueueRouter) Register() { 17 | s.Route("queue_test", wego.Handler("two")) 18 | s.Route("queue2", wego.Handler("queue2")) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo/src/router/websocket_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | //websocket 服务器尽量采用 emqx mqtt broker 9 | type WebSocketRouter struct { 10 | *servers.WebSocketCommServer 11 | } 12 | 13 | func (s *WebSocketRouter) Boot() { 14 | s.WebSocketCommServer = servers.NewWebSocketCommServer() 15 | } 16 | 17 | func (s *WebSocketRouter) Register() { 18 | s.Route("Two", wego.Handler("two")) 19 | } 20 | -------------------------------------------------------------------------------- /validations/helpers.go: -------------------------------------------------------------------------------- 1 | package validations 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | ) 7 | 8 | func Valid(obj interface{}) error { 9 | //如何验证嵌套的问题 10 | valid := Validation{} 11 | b, _ := valid.Valid(obj) 12 | if !b { 13 | var msg string 14 | for _, err := range valid.Errors { 15 | m := strings.Join([]string{err.Field, err.Message}, ":") 16 | msg = strings.Join([]string{m, msg}, ";") 17 | } 18 | return errors.New(msg) 19 | } 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/controller/event_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/servers/events" 6 | ) 7 | 8 | type EventController struct { 9 | } 10 | 11 | func (s *EventController) Handle(ctx contracts.Context) (interface{}, error) { 12 | params := make(map[string]interface{}) 13 | payload := &contracts.Payload{ 14 | Route: "two", 15 | Params: params, 16 | } 17 | events.Fire(payload) 18 | return nil, nil 19 | } 20 | -------------------------------------------------------------------------------- /demo/test/mytest/my_test.go: -------------------------------------------------------------------------------- 1 | package mytest 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/tools/idwork" 6 | "testing" 7 | ) 8 | 9 | func TestDoSomething(t *testing.T) { 10 | fmt.Println("here") 11 | } 12 | func BenchmarkDoSomething(b *testing.B) { 13 | b.StopTimer() //调用该函数停止压力测试的时间计数 14 | //做一些初始化的工作,例如读取文件数据,数据库连接之类的, 15 | //这样这些时间不影响我们测试函数本身的性能 16 | b.StartTimer() //重新开始时间 17 | for i := 0; i < b.N; i++ { //use b.N for looping 18 | idwork.ID() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /demo/test/mqtt/mqtt_test.go: -------------------------------------------------------------------------------- 1 | package mqtt 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/servers/mqtts" 6 | "strconv" 7 | "testing" 8 | ) 9 | 10 | func TestMqtt(t *testing.T) { 11 | 12 | m := make(map[string]interface{}) 13 | m["pub"] = "pub" 14 | m["sub"] = "sub" 15 | err := mqtts.Publish("sub_test3", m) 16 | 17 | fmt.Println(err) 18 | } 19 | func TestByte(t *testing.T) { 20 | s := 2 21 | data := []byte(strconv.Itoa(s)) 22 | b := data[0] 23 | fmt.Println(string(b)) 24 | } 25 | -------------------------------------------------------------------------------- /configs/websocket_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type WebSocketConfig struct { 4 | WebSocketHost string `json:"web_socket_host"` 5 | WebSocketPort string `json:"web_socket_port"` 6 | Path string 7 | } 8 | 9 | func LoadWebSocketConfig() *WebSocketConfig { 10 | config := &WebSocketConfig{ 11 | Path: "/ws", 12 | WebSocketPort: EnvString("server.websocket_port", "8342"), 13 | WebSocketHost: EnvString("server.websocket_host", "127.0.0.1"), 14 | } 15 | return config 16 | } 17 | -------------------------------------------------------------------------------- /servers/events/event.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | ) 6 | 7 | func addEvent(event *contracts.Payload) { 8 | go func() { 9 | eventChan <- event 10 | }() 11 | } 12 | 13 | func newEvent(event *contracts.Payload) *contracts.Payload { 14 | e := eventPool.Get() 15 | if e == nil { 16 | return event 17 | } else { 18 | ret := e.(*contracts.Payload) 19 | (*ret).Route = event.Route 20 | (*ret).Params = event.Params 21 | return ret 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/controller/queue_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/servers/queues" 6 | ) 7 | 8 | type QueueController struct { 9 | } 10 | 11 | func (s *QueueController) Handle(ctx contracts.Context) (interface{}, error) { 12 | 13 | msg := make(map[string]interface{}) 14 | msg["aaa"] = "bbb" 15 | 16 | err := queues.Fire("demo1", "queue_test", msg) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return nil, nil 21 | } 22 | -------------------------------------------------------------------------------- /servers/transports/codecs/timer_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | func TimerDecodeRequest(ctx context.Context, req interface{}) (interface{}, error) { 9 | request := req.(map[string]interface{}) 10 | return contracts.Request{ 11 | Id: request["request_id"].(string), 12 | Data: request, 13 | }, nil 14 | } 15 | 16 | func TimerEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 17 | return rsp, nil 18 | } 19 | -------------------------------------------------------------------------------- /servers/queues/helper.go: -------------------------------------------------------------------------------- 1 | package queues 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "github.com/9299381/wego/configs" 6 | ) 7 | 8 | func Fire(name string, router string, params map[string]interface{}) error { 9 | conn := clients.Redis() 10 | defer conn.Close() 11 | job := &Job{ 12 | Queue: name, 13 | Payload: Payload{ 14 | Route: router, 15 | Params: params, 16 | }, 17 | } 18 | prefix := configs.EnvString("queue.prefix", "wego") 19 | return Enqueue(conn, job, prefix) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/controller/publish_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/servers/mqtts" 6 | ) 7 | 8 | type PublishController struct { 9 | } 10 | 11 | func (s *PublishController) Handle(ctx contracts.Context) (interface{}, error) { 12 | 13 | m := make(map[string]interface{}) 14 | m["pub"] = "pub" 15 | m["sub"] = "sub" 16 | err := mqtts.Publish("sub_test", m) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return nil, nil 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/router/grpc_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type GrpcRouter struct { 9 | *servers.GrpcCommServer 10 | } 11 | 12 | func (s *GrpcRouter) Boot() { 13 | s.GrpcCommServer = servers.NewGrpcCommServer() 14 | } 15 | 16 | //这里注册路由 17 | func (s *GrpcRouter) Register() { 18 | 19 | s.Route("demo.two", wego.Handler("two")) 20 | s.Route("demo.one", wego.Handler("one")) 21 | s.Route("demo.post", wego.Handler("post")) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /filters/health_endpoint.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | type HealthEndpoint struct { 10 | } 11 | 12 | func (s *HealthEndpoint) Next(next endpoint.Endpoint) contracts.IFilter { 13 | return s 14 | } 15 | 16 | func (s *HealthEndpoint) Make() endpoint.Endpoint { 17 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 18 | return contracts.ResponseSucess("SERVING"), nil 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /servers/transports/codecs/queue_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/tools/idwork" 7 | ) 8 | 9 | func QueueServerDecodeRequest(ctx context.Context, req interface{}) (interface{}, error) { 10 | id := idwork.ID() 11 | return contracts.Request{ 12 | Id: id, 13 | Data: req.(map[string]interface{}), 14 | }, nil 15 | } 16 | 17 | func QueueServerEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 18 | return rsp, nil 19 | } 20 | -------------------------------------------------------------------------------- /servers/transports/codecs/websocket_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/tools/idwork" 7 | ) 8 | 9 | func WebSocketDecodeRequest(ctx context.Context, req interface{}) (interface{}, error) { 10 | id := idwork.ID() 11 | return contracts.Request{ 12 | Id: id, 13 | Data: req.(map[string]interface{}), 14 | }, nil 15 | } 16 | 17 | func WebSocketEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 18 | return rsp, nil 19 | } 20 | -------------------------------------------------------------------------------- /demo/src/controller/queue2_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/demo/src/dto" 7 | ) 8 | 9 | type Queue2Controller struct { 10 | } 11 | 12 | func (s *Queue2Controller) Handle(ctx contracts.Context) (interface{}, error) { 13 | req := ctx.Request().(*dto.TaskRequest) 14 | for _, v := range req.OrderList { 15 | fmt.Print(v) 16 | } 17 | return nil, nil 18 | } 19 | func (s *Queue2Controller) GetRules() interface{} { 20 | return &dto.TaskRequest{} 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/controller/cache_set_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/cache" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | type CacheSetController struct { 9 | } 10 | 11 | func (s *CacheSetController) Handle(ctx contracts.Context) (interface{}, error) { 12 | 13 | v := make(map[string]interface{}) 14 | v["aaa"] = "bbb" 15 | 16 | dd := make(map[string]interface{}) 17 | dd["a"] = "111" 18 | dd["b"] = "222" 19 | 20 | v["ccc"] = dd 21 | _ = cache.Set("key", v, 60) 22 | 23 | return nil, nil 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/router/timer_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type TimerRouter struct { 9 | *servers.TimerCommServer 10 | } 11 | 12 | func (s *TimerRouter) Boot() { 13 | s.TimerCommServer = servers.NewTimerCommServer() 14 | } 15 | 16 | func (s *TimerRouter) Register() { 17 | 18 | params := make(map[string]interface{}) 19 | params["timer"] = "test" 20 | s.Route("one", 2, wego.Handler("one"), params) 21 | s.Route("two", 5, wego.Handler("two"), params) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /servers/commons/comm_handler.go: -------------------------------------------------------------------------------- 1 | package commons 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type CommHandler struct { 8 | Handler Handler 9 | } 10 | 11 | func (s *CommHandler) Handle(ctx context.Context, req interface{}) (interface{}, error) { 12 | rsp, err := s.Handler.ServeHandle(ctx, req) 13 | if err != nil { 14 | return nil, err 15 | } 16 | return rsp, err 17 | } 18 | 19 | //该接口的实现是为了 cronjob 20 | func (s *CommHandler) Run() { 21 | ctx := context.Background() 22 | req := make(map[string]interface{}) 23 | _, _ = s.Handler.ServeHandle(ctx, req) 24 | } 25 | -------------------------------------------------------------------------------- /contracts/logger_interface.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | type ILogger interface { 4 | Info(keyvals ...interface{}) 5 | Error(keyvals ...interface{}) 6 | Fatal(keyvals ...interface{}) 7 | Trace(keyvals ...interface{}) 8 | Debug(keyvals ...interface{}) 9 | Panic(keyvals ...interface{}) 10 | 11 | Infof(format string, args ...interface{}) 12 | Errorf(format string, args ...interface{}) 13 | Fatalf(format string, args ...interface{}) 14 | Tracef(format string, args ...interface{}) 15 | Debugf(format string, args ...interface{}) 16 | Panicf(format string, args ...interface{}) 17 | } 18 | -------------------------------------------------------------------------------- /servers/transports/codecs/cron_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/tools/idwork" 7 | ) 8 | 9 | func CronDecodeRequest(ctx context.Context, req interface{}) (interface{}, error) { 10 | request := req.(map[string]interface{}) 11 | request["request_id"] = idwork.ID() 12 | return contracts.Request{ 13 | Id: request["request_id"].(string), 14 | Data: request, 15 | }, nil 16 | } 17 | 18 | func CronEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 19 | return rsp, nil 20 | } 21 | -------------------------------------------------------------------------------- /configs/queue_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type QueueConfig struct { 8 | Prefix string 9 | Listen []string 10 | Interval time.Duration 11 | Concurrency int 12 | } 13 | 14 | func LoadQueueConfig() *QueueConfig { 15 | interval := EnvInt("queue.interval", 1) 16 | config := &QueueConfig{ 17 | Prefix: EnvString("queue.prefix", "wego"), 18 | Listen: EnvStringSlice("queue.listen", []string{}), 19 | Interval: time.Duration(interval) * time.Second, 20 | Concurrency: EnvInt("queue.concurrency", 1), 21 | } 22 | return config 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/controller/consul_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/args" 5 | "github.com/9299381/wego/clients" 6 | "github.com/9299381/wego/contracts" 7 | ) 8 | 9 | type ConsulController struct { 10 | } 11 | 12 | func (s *ConsulController) Handle(ctx contracts.Context) (interface{}, error) { 13 | 14 | entity, _ := clients.GetConsulService(args.Name) 15 | ctx.Log.Info(entity.Service.Service) 16 | ctx.Log.Info(entity.Service.Address) 17 | ctx.Log.Info(entity.Service.Port) 18 | tag := entity.Service.Tags[0] 19 | ctx.Log.Info(tag) 20 | 21 | return nil, nil 22 | } 23 | -------------------------------------------------------------------------------- /servers/mqtts/publish.go: -------------------------------------------------------------------------------- 1 | package mqtts 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "github.com/9299381/wego/configs" 7 | "github.com/9299381/wego/constants" 8 | ) 9 | 10 | func Publish(topic string, payload interface{}) error { 11 | if GetIns() == nil { 12 | return errors.New(constants.ErrMQTTConnect) 13 | } 14 | param, err := json.Marshal(payload) 15 | if err != nil { 16 | return err 17 | } 18 | config := configs.LoadMqttConfig() 19 | token := GetIns().Publish(topic, config.PublishQos, false, param) 20 | if token.Wait() && token.Error() != nil { 21 | return token.Error() 22 | } 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/router/subscribe_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/servers" 6 | ) 7 | 8 | type SubscribeRouter struct { 9 | *servers.MqttSubscribeCommCommServer 10 | } 11 | 12 | func (s *SubscribeRouter) Boot() { 13 | s.MqttSubscribeCommCommServer = servers.NewMqttSubscribeCommCommServer() 14 | } 15 | 16 | func (s *SubscribeRouter) Register() { 17 | //topic -> handler 18 | s.Route("sub_test", wego.Handler("two")) 19 | s.Route("sub_test2", wego.Handler("two")) 20 | s.Route("sub_test3", wego.Handler("sleep")) 21 | s.Route("$SYS/brokers/+/clients/+/+", wego.Handler("mqtt_event")) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /clients/mysql/ins.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "github.com/9299381/wego/configs" 5 | _ "github.com/go-sql-driver/mysql" 6 | "sync" 7 | "xorm.io/xorm" 8 | ) 9 | 10 | var db *xorm.Engine 11 | var onceMysql sync.Once 12 | 13 | func GetDB() *xorm.Engine { 14 | onceMysql.Do(func() { 15 | db = newMySql() 16 | }) 17 | return db 18 | } 19 | func newMySql() *xorm.Engine { 20 | conf := configs.LoadMySqlConfig() 21 | engine, _ := xorm.NewEngine( 22 | conf.Driver, 23 | conf.DataSource, 24 | ) 25 | engine.SetMaxIdleConns(conf.MaxIdleConns) 26 | engine.SetMaxOpenConns(conf.MaxOpenConns) 27 | engine.ShowSQL(conf.ShowSQL) 28 | return engine 29 | } 30 | -------------------------------------------------------------------------------- /servers/cronjobs/server.go: -------------------------------------------------------------------------------- 1 | package cronjobs 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/robfig/cron/v3" 6 | "time" 7 | ) 8 | 9 | type Server struct { 10 | Serv *cron.Cron 11 | } 12 | 13 | func NewServer() *Server { 14 | nyc, _ := time.LoadLocation("Asia/Shanghai") 15 | ss := &Server{ 16 | Serv: cron.New(cron.WithSeconds(), cron.WithLocation(nyc)), 17 | } 18 | return ss 19 | } 20 | 21 | func (s *Server) Register(spec string, job *commons.CommHandler) { 22 | _, _ = s.Serv.AddJob(spec, job) 23 | } 24 | 25 | func (s *Server) Serve() error { 26 | s.Serv.Start() 27 | select {} 28 | } 29 | func (s *Server) Close() { 30 | 31 | } 32 | -------------------------------------------------------------------------------- /demo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/9299381/wego/demo 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/9299381/wego v0.2.0 7 | github.com/gomodule/redigo v2.0.0+incompatible 8 | github.com/looplab/fsm v0.1.0 9 | github.com/mitchellh/mapstructure v1.1.2 10 | github.com/satori/go.uuid v1.2.0 // indirect 11 | github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 12 | github.com/tidwall/gjson v1.3.4 13 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect 14 | golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect 15 | gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 16 | xorm.io/builder v0.3.7 17 | ) 18 | 19 | replace github.com/9299381/wego => ../ 20 | -------------------------------------------------------------------------------- /demo/test/extends/extend_test.go: -------------------------------------------------------------------------------- 1 | package extends 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestExtend(t *testing.T) { 9 | p := &pc{} 10 | testInterface(p) 11 | } 12 | 13 | func testInterface(usb usbInterface) { 14 | usb.SayHello() 15 | usb.DoSth() 16 | } 17 | 18 | type usbInterface interface { 19 | SayHello() 20 | DoSth() 21 | } 22 | type usb struct { 23 | } 24 | 25 | func (i *usb) SayHello() { 26 | fmt.Println("usb....sayhello") 27 | } 28 | 29 | func (i *usb) DoSth() { 30 | fmt.Println("usb....do ") 31 | } 32 | 33 | type pc struct { 34 | *usb //可以直接引用usb的 dosth 无需new 35 | } 36 | 37 | func (i *pc) SayHello() { 38 | fmt.Println("pc....sayhello") 39 | } 40 | -------------------------------------------------------------------------------- /configs/redis_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type RedisConfig struct { 8 | Uri string 9 | Auth string 10 | Db int 11 | MaxActive int 12 | MaxIdle int 13 | IdleTimeout time.Duration 14 | } 15 | 16 | func LoadRedisConfig() *RedisConfig { 17 | config := &RedisConfig{ 18 | Uri: EnvString("redis.uri", "127.0.0.1:6937"), 19 | Auth: EnvString("redis.auth", "password"), 20 | Db: EnvInt("redis.db", 0), 21 | MaxActive: EnvInt("redis.max_active", 50), 22 | MaxIdle: EnvInt("redis.max_idle", 5), 23 | IdleTimeout: time.Duration(EnvInt("redis.timeout", 10)) * time.Second, 24 | } 25 | return config 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/controller/valid_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/demo/src/dto" 6 | ) 7 | 8 | type ValidController struct { 9 | } 10 | 11 | // swagger:route Post /demo/valid 分组2 validController 12 | // Test swagger 13 | // This will ....... 14 | // Responses: 15 | // 200: postResponse 16 | func (s *ValidController) Handle(ctx contracts.Context) (interface{}, error) { 17 | st := ctx.Request().(*dto.TestDto) 18 | resp := &dto.ValidResponse{ 19 | Age: st.Age, 20 | List: st.DemoList, 21 | } 22 | return resp, nil 23 | } 24 | 25 | func (s *ValidController) GetRules() interface{} { 26 | return &dto.TestDto{} 27 | } 28 | -------------------------------------------------------------------------------- /demo/src/controller/cache_get_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/cache" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/tidwall/gjson" 7 | ) 8 | 9 | type CacheGetController struct { 10 | } 11 | 12 | func (s *CacheGetController) Handle(ctx contracts.Context) (interface{}, error) { 13 | //GetByte 方式 14 | jsonBytes, _ := cache.GetByte("key") 15 | // Get方式 16 | obj := make(map[string]interface{}) 17 | _ = cache.Get("key", &obj) 18 | 19 | //使用gjson 更方便 直接从json字符串中取值 20 | return map[string]interface{}{ 21 | "ccc": gjson.Get(string(jsonBytes), "ccc.a").Str, 22 | "aaa": obj["aaa"], 23 | "gaaa": gjson.Get(string(jsonBytes), "aaa").String(), 24 | }, nil 25 | } 26 | -------------------------------------------------------------------------------- /filters/filter.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/go-kit/kit/endpoint" 6 | ) 7 | 8 | func New(controller contracts.IController) endpoint.Endpoint { 9 | return Chain( 10 | &ResponseEndpoint{}, 11 | &CommEndpoint{Controller: controller}, 12 | ) 13 | } 14 | 15 | func Auth(controller contracts.IController) endpoint.Endpoint { 16 | return Chain( 17 | &ResponseEndpoint{}, 18 | &JwtEndpoint{}, 19 | &CommEndpoint{Controller: controller}, 20 | ) 21 | } 22 | 23 | func Limit(controller contracts.IController) endpoint.Endpoint { 24 | return Chain( 25 | &ResponseEndpoint{}, 26 | &LimitEndpoint{}, 27 | &CommEndpoint{Controller: controller}, 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /demo/test/queue/queue_test.go: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/9299381/wego/demo/src/dto" 6 | "github.com/9299381/wego/servers/queues" 7 | "github.com/9299381/wego/tools/idwork" 8 | "testing" 9 | ) 10 | 11 | func TestQueue(t *testing.T) { 12 | var orders []*dto.Order 13 | orders = append(orders, &dto.Order{ 14 | Id: idwork.ID(), 15 | Name: "one", 16 | }) 17 | orders = append(orders, &dto.Order{ 18 | Id: idwork.ID(), 19 | Name: "two", 20 | }) 21 | orderJson, _ := json.Marshal(orders) 22 | 23 | _ = queues.Fire( 24 | "demo1", 25 | "queue2", 26 | map[string]interface{}{ 27 | "task_id": idwork.ID(), 28 | "order_json": string(orderJson), 29 | }, 30 | ) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /servers/transports/codecs/command_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "errors" 7 | "github.com/9299381/wego/constants" 8 | "github.com/9299381/wego/contracts" 9 | "github.com/9299381/wego/tools/idwork" 10 | ) 11 | 12 | func CommandDecodeRequest(_ context.Context, req interface{}) (interface{}, error) { 13 | var mapResult map[string]interface{} 14 | err := json.Unmarshal([]byte(req.(string)), &mapResult) 15 | if err != nil { 16 | return nil, errors.New(constants.ErrJson) 17 | } 18 | return contracts.Request{ 19 | Id: idwork.ID(), 20 | Data: mapResult, 21 | }, nil 22 | } 23 | 24 | func CommandEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 25 | return rsp, nil 26 | } 27 | -------------------------------------------------------------------------------- /servers/mqtts/ins.go: -------------------------------------------------------------------------------- 1 | package mqtts 2 | 3 | import ( 4 | "github.com/9299381/wego/configs" 5 | "github.com/9299381/wego/tools/idwork" 6 | mqtt "github.com/eclipse/paho.mqtt.golang" 7 | "sync" 8 | ) 9 | 10 | var ins mqtt.Client 11 | var once sync.Once 12 | 13 | func GetIns() mqtt.Client { 14 | once.Do(func() { 15 | ins = init_mc() 16 | }) 17 | return ins 18 | } 19 | func init_mc() mqtt.Client { 20 | config := configs.LoadMqttConfig() 21 | opts := mqtt.NewClientOptions().AddBroker(config.Host) 22 | opts.SetUsername(config.UserName) 23 | opts.SetPassword(config.PassWord) 24 | opts.SetClientID(idwork.ID()) 25 | mc := mqtt.NewClient(opts) 26 | if token := mc.Connect(); token.Wait() && token.Error() != nil { 27 | return nil 28 | } 29 | return mc 30 | } 31 | -------------------------------------------------------------------------------- /filters/limit_endpoint.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/9299381/wego/contracts" 7 | "github.com/go-kit/kit/endpoint" 8 | "github.com/juju/ratelimit" 9 | "time" 10 | ) 11 | 12 | type LimitEndpoint struct { 13 | next endpoint.Endpoint 14 | } 15 | 16 | func (s *LimitEndpoint) Next(next endpoint.Endpoint) contracts.IFilter { 17 | s.next = next 18 | return s 19 | } 20 | 21 | func (s *LimitEndpoint) Make() endpoint.Endpoint { 22 | limit := ratelimit.NewBucket(time.Second*1, 3) 23 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 24 | if limit.TakeAvailable(1) == 0 { 25 | return nil, errors.New("Rate limit exceed!") 26 | } 27 | return s.next(ctx, request) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /configs/mqtt_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | type MqttConfig struct { 4 | Host string `json:"host"` 5 | UserName string `json:"user_name"` 6 | PassWord string `json:"pass_word"` 7 | Parallel bool `json:"parallel"` 8 | SubscribeQos uint8 `json:"subscribe_qos"` 9 | PublishQos uint8 `json:"publish_qos"` 10 | } 11 | 12 | func LoadMqttConfig() *MqttConfig { 13 | config := &MqttConfig{ 14 | Host: EnvString("mqtt.host", "tcp://127.0.0.1:1883"), 15 | UserName: EnvString("mqtt.username", ""), 16 | PassWord: EnvString("mqtt.password", ""), 17 | Parallel: EnvBool("mqtt.parallel", false), 18 | SubscribeQos: uint8(EnvInt("mqtt.subscribe_qos", 2)), 19 | PublishQos: uint8(EnvInt("mqtt.publish_qos", 2)), 20 | } 21 | return config 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/model/comm_user_info.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/9299381/wego/tools" 5 | ) 6 | 7 | type CommUser struct { 8 | Id string `xorm:"pk varchar(21) notnull unique 'id'" json:"id"` 9 | UserName string `xorm:"varchar(50) not null 'user_name'" json:"user_name"` 10 | LoginName string `xorm:"varchar(20) 'login_name'" json:"login_name"` 11 | Status string `xorm:"varchar(2) 'status'" json:"status"` 12 | CreateTime tools.LocalTime `xorm:"datetime created 'create_time'" json:"create_time"` 13 | UpdateTime tools.LocalTime `xorm:"datetime updated 'update_time'" json:"update_time"` 14 | } 15 | 16 | func (s *CommUser) TableName() string { 17 | return "comm_user_info" 18 | 19 | //return "comm_user_info_copy1" 20 | } 21 | -------------------------------------------------------------------------------- /args/init.go: -------------------------------------------------------------------------------- 1 | package args 2 | 3 | import ( 4 | "flag" 5 | "testing" 6 | ) 7 | 8 | var Name string 9 | var Mode string 10 | 11 | var Registy string 12 | 13 | var Server string 14 | var Config string 15 | 16 | var Cmd string 17 | var Args string 18 | 19 | func init() { 20 | 21 | flag.StringVar(&Name, "name", "app", "服务名称") 22 | flag.StringVar(&Mode, "mode", "dev", "开发模式") 23 | flag.StringVar(&Registy, "registy", "", "consul服务注册中心") 24 | 25 | flag.StringVar(&Server, "server", "http,event", "需要启动的服务器") 26 | flag.StringVar(&Config, "config", "env,consul", "顺序1环境配置") 27 | 28 | flag.StringVar(&Cmd, "cmd", "cmd", "cli命令") 29 | flag.StringVar(&Args, "args", "{}", "json参数") 30 | var _ = func() bool { 31 | testing.Init() 32 | return true 33 | }() 34 | if !flag.Parsed() { 35 | flag.Parse() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/controller/redis_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/gomodule/redigo/redis" 7 | ) 8 | 9 | type RedisController struct { 10 | } 11 | 12 | func (s *RedisController) Handle(ctx contracts.Context) (interface{}, error) { 13 | 14 | client := clients.Redis() //从pool中获取一个链接 15 | defer client.Close() //延时释放链接,本方法执行完毕时释放 16 | _, _ = client.Do("SET", "go_key", "value") 17 | res, _ := redis.String(client.Do("GET", "go_key")) 18 | exists, _ := redis.Bool(client.Do("EXISTS", "foo")) 19 | if exists { 20 | ctx.Log.Info("foo 存在") 21 | } else { 22 | _, _ = client.Do("SET", "foo", "value") 23 | ctx.Log.Info("foo 不存在") 24 | 25 | } 26 | ctx.Log.Info("redis-go_key 的值:", res) 27 | 28 | return nil, nil 29 | } 30 | -------------------------------------------------------------------------------- /constants/error.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const Err string = "9999::错误" 4 | const ErrStop string = "9990::暂停服务" 5 | const ErrMQTTConnect string = "9991::MQTT链接失败" 6 | const ErrCacheInit string = "9992::Cache初始化错误" 7 | const ErrLoadEnv string = "9993::ENV环境加载失败" 8 | const ErrSign string = "9994::数据签名错误" 9 | const ErrBalance = "9995::金额不可为负值" 10 | 11 | const ErrNotExist string = "9000::数据不存在" 12 | const ErrIsExist string = "9001::数据已存在" 13 | const ErrSaveFailed string = "9002::数据保存失败" 14 | 15 | const ErrConvert string = "9010::类型转换错误" 16 | const ErrJson string = "9011::JSON报文解析错误" 17 | 18 | const ErrNoToken string = "9020::缺少authToken" 19 | const ErrTokenFmt string = "9021::Token格式错误" 20 | const ErrTokenExp string = "9022::Token过期,请重新登录" 21 | const ErrTokenSign string = "9023::签名错误,请重新登录" 22 | 23 | const ErrRoute string = "9030::路由解析错误" 24 | -------------------------------------------------------------------------------- /demo/src/controller/mqtt_event_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "time" 6 | ) 7 | 8 | type MqttEventController struct { 9 | } 10 | 11 | func (s *MqttEventController) Handle(ctx contracts.Context) (interface{}, error) { 12 | if ctx.Get("request.connected_at") != nil { 13 | connect := int64(ctx.Get("request.connected_at").(float64)) 14 | var conn string = time.Unix(connect, 0).Format("2006-01-02 15:04:05") 15 | println(ctx.Get("request.clientid").(string), "connect_at", conn) 16 | } 17 | if ctx.Get("request.disconnected_at") != nil { 18 | connect := int64(ctx.Get("request.disconnected_at").(float64)) 19 | var disconn string = time.Unix(connect, 0).Format("2006-01-02 15:04:05") 20 | println(ctx.Get("request.clientid").(string), "disconnect_at", disconn) 21 | } 22 | return nil, nil 23 | } 24 | -------------------------------------------------------------------------------- /servers/transports/codecs/mqtt_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "errors" 7 | "github.com/9299381/wego/constants" 8 | "github.com/9299381/wego/contracts" 9 | "github.com/9299381/wego/tools/idwork" 10 | ) 11 | 12 | func MqttSubscribeDecodeRequest(_ context.Context, req interface{}) (interface{}, error) { 13 | var mapResult map[string]interface{} 14 | err := json.Unmarshal(req.([]byte), &mapResult) 15 | if err != nil { 16 | return nil, errors.New(constants.ErrJson) 17 | } 18 | requestId, ok := mapResult["request_id"].(string) 19 | if ok == false { 20 | requestId = idwork.ID() 21 | } 22 | return contracts.Request{ 23 | Id: requestId, 24 | Data: mapResult, 25 | }, nil 26 | } 27 | 28 | func MqttSubscribeEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 29 | return rsp, nil 30 | } 31 | -------------------------------------------------------------------------------- /demo/src/controller/parallel_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/demo/src/service" 6 | "github.com/9299381/wego/services" 7 | ) 8 | 9 | type ParallelController struct { 10 | } 11 | 12 | func (s *ParallelController) Handle(ctx contracts.Context) (interface{}, error) { 13 | ctx.Set("controller", "parallel") 14 | 15 | //并行service中间件 16 | err := services.Pipe(). 17 | Middle(&service.ParallelOne{}). 18 | Middle(&service.ParallelTwo{}). 19 | Parallel(ctx) 20 | if err != nil { 21 | return nil, err 22 | } 23 | m := make(map[string]interface{}) 24 | m["aaa"] = ctx.Get("aaa") //不确定值, 25 | m["one"] = ctx.Get("one") //one中设置 26 | m["two"] = ctx.Get("two") //two中设置 27 | m["controller"] = ctx.Get("controller") //controller中设置 28 | 29 | return m, nil 30 | } 31 | -------------------------------------------------------------------------------- /demo/src/service/sql_service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/demo/src/fsm" 7 | "github.com/9299381/wego/demo/src/model" 8 | ) 9 | 10 | type SqlService struct { 11 | } 12 | 13 | func (s *SqlService) Handle(ctx contracts.Context) error { 14 | 15 | user := &model.CommUser{Id: "1189164474851006208"} 16 | _, _ = clients.DB().Get(user) 17 | ctx.Log.Info(user) 18 | 19 | ////初始化状态机 20 | sm := fsm.NewUserFSM(ctx, user) 21 | ctx.Log.Info(user.Status) 22 | //发送状态转换的事件 23 | if sm.Can("login") { 24 | err := sm.Event("login") 25 | if err != nil { 26 | return err 27 | } 28 | user.UserName = "aaaaaaaaa" 29 | ctx.Log.Info(user.Status) 30 | _, _ = clients.DB().Update(user, &model.CommUser{Id: user.Id}) 31 | } 32 | ctx.Set("user", user) 33 | 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /clients/mysql/helper.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "errors" 5 | "github.com/9299381/wego/constants" 6 | ) 7 | 8 | func First(query interface{}, args []interface{}, bean interface{}) error { 9 | has, err := GetDB().SQL(query, args...).Get(bean) 10 | if err != nil { 11 | return err 12 | } 13 | if !has { 14 | return errors.New(constants.ErrNotExist) 15 | } 16 | return nil 17 | } 18 | 19 | func Fetch(query interface{}, args []interface{}, bean interface{}) error { 20 | return GetDB().SQL(query, args...).Find(bean) 21 | } 22 | 23 | func Insert(bean interface{}) bool { 24 | affected, _ := GetDB().Insert(bean) 25 | if affected == 1 { 26 | return true 27 | } 28 | return false 29 | } 30 | 31 | func Update(bean interface{}, cond interface{}) bool { 32 | affected, _ := GetDB().Update(bean, cond) 33 | if affected == 1 { 34 | return true 35 | } 36 | return false 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/dto/queue_dto.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/9299381/wego/constants" 6 | "github.com/9299381/wego/validations" 7 | ) 8 | 9 | type TaskRequest struct { 10 | TaskId string `json:"task_id" valid:"Required"` 11 | OrderJson string `json:"order_json" valid:"Required"` 12 | OrderList []*Order `json:"-" valid:"Custom(CheckOrder)"` 13 | } 14 | 15 | func (s *TaskRequest) CheckOrder(v *validations.Validation) { 16 | err := json.Unmarshal([]byte(s.OrderJson), &s.OrderList) 17 | if err != nil { 18 | _ = v.SetError("order_json", constants.ErrJson) 19 | return 20 | } 21 | for _, order := range s.OrderList { 22 | err := validations.Valid(order) 23 | if err != nil { 24 | _ = v.SetError("list_json", err.Error()) 25 | } 26 | } 27 | } 28 | 29 | type Order struct { 30 | Id string `json:"id" valid:"Required" ` 31 | Name string `json:"name" valid:"Required"` 32 | } 33 | -------------------------------------------------------------------------------- /servers/transports/codecs/gprc_codec.go: -------------------------------------------------------------------------------- 1 | package codecs 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "github.com/9299381/wego/contracts" 7 | protobuf2 "github.com/9299381/wego/servers/transports/protobuf" 8 | ) 9 | 10 | // TCP请求数据解码函数 11 | func GprcDecodeRequest(ctx context.Context, req interface{}) (interface{}, error) { 12 | request := req.(*protobuf2.Request) 13 | data := make(map[string]interface{}) 14 | _ = json.Unmarshal([]byte(request.Param), &data) 15 | 16 | return contracts.Request{ 17 | Id: request.Id, 18 | Data: data, 19 | }, nil 20 | } 21 | 22 | // TCP返回数据编码函数 23 | func GprcEncodeResponse(_ context.Context, rsp interface{}) (interface{}, error) { 24 | response := rsp.(contracts.Response) 25 | data, _ := json.Marshal(response.Data) 26 | resp := &protobuf2.Response{ 27 | Code: response.Code, 28 | Data: string(data), 29 | Msg: response.Message, 30 | } 31 | return resp, nil 32 | } 33 | -------------------------------------------------------------------------------- /configs/mongo_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | import "time" 4 | 5 | type MongoConfig struct { 6 | Address []string 7 | Database string 8 | Username string 9 | Password string 10 | MaxIdleTime time.Duration 11 | MinPoolSize int 12 | } 13 | 14 | /** 15 | 每次有连接被重置到空闲池时,打一个时间戳。 16 | 在轮询 goroutine 中每隔一段时间 review 空闲连接的空闲时长, 17 | 当时长大于maxIdleTimeMS时,就释放连接,将空闲池的大小控制在minPoolSize。 18 | 若maxIdleTimeMS不设置或为 0,则默认为不进行释放 19 | */ 20 | func LoadMongoConfig() *MongoConfig { 21 | idle := EnvInt("mongo.max_idle_time", 30) 22 | config := &MongoConfig{ 23 | Address: EnvStringSlice("mongo.uri", []string{"127.0.0.1:27017"}), 24 | Database: EnvString("mongo.database", "base"), 25 | Username: EnvString("mongo.username", ""), 26 | Password: EnvString("mongo.password", ""), 27 | MinPoolSize: EnvInt("mongo.min_pool_size", 10), 28 | MaxIdleTime: time.Duration(idle) * time.Second, 29 | } 30 | return config 31 | } 32 | -------------------------------------------------------------------------------- /demo/test/num/num_test.go: -------------------------------------------------------------------------------- 1 | package num 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "github.com/9299381/wego/demo/src/model" 6 | "github.com/9299381/wego/tools/idwork" 7 | "testing" 8 | ) 9 | 10 | func TestNum(t *testing.T) { 11 | 12 | } 13 | 14 | func TestDemoTestModel(t *testing.T) { 15 | err := clients.DB().Sync2(new(model.CommDemoModel)) 16 | if err != nil { 17 | t.Error(err) 18 | } 19 | } 20 | func TestInsert(t *testing.T) { 21 | demo := &model.CommDemoModel{ 22 | Id: idwork.ID(), 23 | NumInt1: 9876543210, 24 | NumInt2: 0, 25 | NumBig: 1111111111111111111, 26 | } 27 | _, _ = clients.DB().Insert(demo) 28 | } 29 | func TestUpdate(t *testing.T) { 30 | demo := &model.CommDemoModel{Id: "1298580054575415296"} 31 | _, _ = clients.DB().Get(demo) 32 | demo.NumInt1 = 0 33 | demo.NumInt2 = 123 34 | _, _ = clients.DB(). 35 | Id(demo.Id). 36 | Cols("num_int1", "num_int2"). 37 | Update(demo) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /demo/test/ctl/controller_test.go: -------------------------------------------------------------------------------- 1 | package ctl 2 | 3 | import ( 4 | "github.com/9299381/wego/demo/src/controller" 5 | "github.com/9299381/wego/tools" 6 | "testing" 7 | ) 8 | 9 | func TestOneController(t *testing.T) { 10 | resp, err := tools.Test(). 11 | Controller(&controller.OneController{}). 12 | Request(nil). 13 | Run() 14 | 15 | if err != nil { 16 | t.Error(err) 17 | } else { 18 | t.Log(resp.Data) 19 | } 20 | 21 | } 22 | func TestTwoController(t *testing.T) { 23 | resp, err := tools.Test(). 24 | Controller(&controller.TwoController{}). 25 | Request(nil). 26 | Run() 27 | 28 | if err != nil { 29 | t.Error(err) 30 | } else { 31 | t.Log(resp.Data) 32 | } 33 | 34 | } 35 | func TestParallelController(t *testing.T) { 36 | resp, err := tools.Test(). 37 | Controller(&controller.ParallelController{}). 38 | Request(nil). 39 | Run() 40 | 41 | if err != nil { 42 | t.Error(err) 43 | } else { 44 | t.Log(resp.Data) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /configs/mysql_config.go: -------------------------------------------------------------------------------- 1 | package configs 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/args" 6 | ) 7 | 8 | type MySqlConfig struct { 9 | Driver string 10 | DataSource string 11 | MaxIdleConns int 12 | MaxOpenConns int 13 | ShowSQL bool 14 | } 15 | 16 | func LoadMySqlConfig() *MySqlConfig { 17 | driver := EnvString("db.connection", "mysql") 18 | dataSource := fmt.Sprintf( 19 | "%s:%s@(%s:%s)/%s"+"?charset=utf8&collation=utf8_general_ci", 20 | EnvString("db.username", "root"), 21 | EnvString("db.password", "root"), 22 | EnvString("db.host", "127.0.0.1"), 23 | EnvString("db.port", "3306"), 24 | EnvString("db.database", "default"), 25 | ) 26 | show := false 27 | if args.Mode != "prod" { 28 | show = true 29 | } 30 | config := &MySqlConfig{ 31 | Driver: driver, 32 | DataSource: dataSource, 33 | ShowSQL: show, 34 | MaxIdleConns: EnvInt("db.max_idle", 5), 35 | MaxOpenConns: EnvInt("db.max_open", 50), 36 | } 37 | return config 38 | } 39 | -------------------------------------------------------------------------------- /servers/command_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/loggers" 5 | "github.com/9299381/wego/servers/commands" 6 | "github.com/9299381/wego/servers/commons" 7 | "github.com/9299381/wego/servers/transports" 8 | "github.com/go-kit/kit/endpoint" 9 | ) 10 | 11 | type CommandCommServer struct { 12 | *commands.Server 13 | } 14 | 15 | func NewCommandCommServer() *CommandCommServer { 16 | ss := &CommandCommServer{ 17 | Server: commands.NewServer(), 18 | } 19 | ss.Logger = loggers.GetLog() 20 | return ss 21 | } 22 | 23 | func (s *CommandCommServer) Route(name string, endpoint endpoint.Endpoint) { 24 | 25 | handler := &commons.CommHandler{ 26 | Handler: transports.NewCommand(endpoint), 27 | } 28 | s.Register(name, handler) 29 | } 30 | 31 | func (s *CommandCommServer) Load() { 32 | 33 | //注册通用路由 34 | } 35 | 36 | func (s *CommandCommServer) Start() error { 37 | return s.Serve() 38 | 39 | } 40 | func (s *CommandCommServer) Close() { 41 | s.Server.Close() 42 | } 43 | -------------------------------------------------------------------------------- /clients/http.go: -------------------------------------------------------------------------------- 1 | package clients 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/9299381/wego/tools/convert" 7 | "io/ioutil" 8 | "net/http" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func NewHttpPostCall(host, service string, params map[string]interface{}) (ret contracts.Response) { 14 | 15 | path := "http://" + host + "/" + strings.Replace(service, ".", "/", -1) 16 | client := &http.Client{ 17 | Timeout: 10 * time.Second, 18 | } 19 | resp, err := client.PostForm(path, convert.FormEncode(params)) 20 | if err != nil { 21 | ret = contracts.ResponseFailed(err) 22 | return 23 | } 24 | defer resp.Body.Close() 25 | body, err := ioutil.ReadAll(resp.Body) 26 | 27 | response := &contracts.Response{} 28 | err = json.Unmarshal(body, response) 29 | if err != nil { 30 | ret = contracts.ResponseFailed(err) 31 | } else { 32 | m := response.Data.(map[string]interface{}) 33 | m["call_method"] = "http" 34 | response.Data = m 35 | ret = *response 36 | } 37 | return 38 | } 39 | -------------------------------------------------------------------------------- /servers/gateway_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/filters" 5 | "github.com/9299381/wego/loggers" 6 | "github.com/9299381/wego/servers/gateways" 7 | "github.com/go-kit/kit/endpoint" 8 | ) 9 | 10 | type GateWayCommServer struct { 11 | *gateways.Server 12 | } 13 | 14 | func NewGateWayCommServer() *GateWayCommServer { 15 | ss := &GateWayCommServer{ 16 | Server: gateways.NewServer(), 17 | } 18 | ss.Logger = loggers.GetLog() 19 | return ss 20 | } 21 | 22 | func (s *GateWayCommServer) Route(method, path string, endpoint endpoint.Endpoint) { 23 | //如果有本地注册的路由,则跑本地,2种情况组合endpoint filter 24 | //1 跑本地服务 25 | //2 只跑本地endpoint filter 26 | s.Register(method, path, endpoint) 27 | } 28 | 29 | func (s *GateWayCommServer) Load() { 30 | //注册通用路由,consul 心跳检测 31 | s.Route("GET", "/health", (&filters.HealthEndpoint{}).Make()) 32 | 33 | } 34 | 35 | func (s *GateWayCommServer) Start() error { 36 | return s.Serve() 37 | } 38 | func (s *GateWayCommServer) Close() { 39 | s.Server.Close() 40 | } 41 | -------------------------------------------------------------------------------- /filters/Jwt_endpoint.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/9299381/wego/constants" 7 | "github.com/9299381/wego/contracts" 8 | "github.com/9299381/wego/tools/convert" 9 | "github.com/9299381/wego/tools/jwt" 10 | "github.com/go-kit/kit/endpoint" 11 | ) 12 | 13 | type JwtEndpoint struct { 14 | next endpoint.Endpoint 15 | } 16 | 17 | func (s *JwtEndpoint) Next(next endpoint.Endpoint) contracts.IFilter { 18 | s.next = next 19 | return s 20 | } 21 | 22 | func (s *JwtEndpoint) Make() endpoint.Endpoint { 23 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 24 | req := request.(contracts.Request) 25 | token := req.Data["authToken"] 26 | if token == nil || token == "" { 27 | return nil, errors.New(constants.ErrNoToken) 28 | } 29 | claim, err := jwt.New().VerifyToken(token.(string)) 30 | if err != nil { 31 | return nil, err 32 | } 33 | req.Data["claim"] = convert.Struct2Map(claim) 34 | //这里进行token的jwt认证 35 | return s.next(ctx, req) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /servers/timer_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/loggers" 5 | "github.com/9299381/wego/servers/commons" 6 | "github.com/9299381/wego/servers/timers" 7 | "github.com/9299381/wego/servers/transports" 8 | "github.com/go-kit/kit/endpoint" 9 | ) 10 | 11 | /** 12 | 定时器 13 | */ 14 | type TimerCommServer struct { 15 | *timers.Server 16 | } 17 | 18 | func NewTimerCommServer() *TimerCommServer { 19 | ss := &TimerCommServer{ 20 | Server: timers.NewServer(), 21 | } 22 | ss.Logger = loggers.GetLog() 23 | return ss 24 | } 25 | 26 | func (s *TimerCommServer) Load() { 27 | 28 | //注册通用路由 29 | } 30 | 31 | func (s *TimerCommServer) Route(name string, freq int, endpoint endpoint.Endpoint, params map[string]interface{}) { 32 | 33 | handler := &commons.CommHandler{ 34 | Handler: transports.NewTimer(endpoint), 35 | } 36 | s.Register(name, freq, handler, params) 37 | } 38 | 39 | func (s *TimerCommServer) Start() error { 40 | return s.Serve() 41 | } 42 | func (s *TimerCommServer) Close() { 43 | s.Server.Close() 44 | } 45 | -------------------------------------------------------------------------------- /filters/gateway_endpoint.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "context" 5 | "github.com/9299381/wego/contracts" 6 | "github.com/go-kit/kit/endpoint" 7 | ) 8 | 9 | type GateWayEndpoint struct { 10 | next endpoint.Endpoint 11 | } 12 | 13 | func (s *GateWayEndpoint) Next(next endpoint.Endpoint) contracts.IFilter { 14 | s.next = next 15 | return s 16 | } 17 | 18 | func (s *GateWayEndpoint) Make() endpoint.Endpoint { 19 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 20 | req := request.(contracts.Request) 21 | req.Data["GATEWAY"] = "GATEWAY" 22 | if s.next == nil { 23 | response = contracts.ResponseSucess(req.Data) 24 | } else { 25 | response, err = s.next(ctx, req) 26 | res := response.(contracts.Response) 27 | if res.Code == "0000" { 28 | m, b := res.Data.(map[string]interface{}) 29 | if b && m != nil { 30 | for k, v := range m { 31 | req.Data[k] = v 32 | } 33 | response = contracts.ResponseSucess(req.Data) 34 | } 35 | } 36 | } 37 | return 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /servers/event_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/configs" 6 | "github.com/9299381/wego/loggers" 7 | "github.com/9299381/wego/servers/events" 8 | "time" 9 | ) 10 | 11 | type EventCommServer struct { 12 | *events.Server 13 | } 14 | 15 | func NewEventCommServer() *EventCommServer { 16 | config := configs.LoadEventConfig() 17 | ss := &EventCommServer{ 18 | Server: events.NewServer(), 19 | } 20 | ss.Logger = loggers.GetLog() 21 | ss.Concurrency = config.Concurrency 22 | ss.After = time.After(time.Duration(config.After) * time.Second) 23 | events.Handlers = wego.App.Handlers 24 | return ss 25 | } 26 | func (s *EventCommServer) Boot() { 27 | 28 | } 29 | 30 | func (s *EventCommServer) Load() { 31 | 32 | //注册通用路由 33 | } 34 | func (s *EventCommServer) Register() { 35 | } 36 | 37 | func (s *EventCommServer) Route() { 38 | 39 | } 40 | 41 | func (s *EventCommServer) Start() error { 42 | return s.Serve() 43 | } 44 | func (s *EventCommServer) Close() { 45 | s.Server.Close() 46 | } 47 | -------------------------------------------------------------------------------- /servers/websocket_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/loggers" 5 | "github.com/9299381/wego/servers/commons" 6 | "github.com/9299381/wego/servers/transports" 7 | "github.com/9299381/wego/servers/websockets" 8 | "github.com/go-kit/kit/endpoint" 9 | ) 10 | 11 | //websocket 服务器尽量采用 emqx mqtt broker 12 | type WebSocketCommServer struct { 13 | *websockets.Server 14 | } 15 | 16 | func NewWebSocketCommServer() *WebSocketCommServer { 17 | 18 | ss := &WebSocketCommServer{ 19 | Server: websockets.NewServer(), 20 | } 21 | ss.Logger = loggers.GetLog() 22 | return ss 23 | } 24 | 25 | func (s *WebSocketCommServer) Route(name string, endpoint endpoint.Endpoint) { 26 | 27 | handler := &commons.CommHandler{ 28 | Handler: transports.NewWebSocket(endpoint), 29 | } 30 | s.Register(name, handler) 31 | } 32 | 33 | func (s *WebSocketCommServer) Load() { 34 | //注册通用路由 35 | } 36 | 37 | func (s *WebSocketCommServer) Start() error { 38 | return s.Serve() 39 | } 40 | func (s *WebSocketCommServer) Close() { 41 | s.Server.Close() 42 | } 43 | -------------------------------------------------------------------------------- /filters/response_endpoint.go: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/9299381/wego" 7 | "github.com/9299381/wego/constants" 8 | "github.com/9299381/wego/contracts" 9 | "github.com/9299381/wego/loggers" 10 | "github.com/go-kit/kit/endpoint" 11 | ) 12 | 13 | type ResponseEndpoint struct { 14 | next endpoint.Endpoint 15 | } 16 | 17 | func (s *ResponseEndpoint) Next(next endpoint.Endpoint) contracts.IFilter { 18 | s.next = next 19 | return s 20 | } 21 | 22 | func (s *ResponseEndpoint) Make() endpoint.Endpoint { 23 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 24 | //全局扑捉错误 25 | defer func() { 26 | if err := recover(); err != nil { 27 | loggers.GetLog().Info(err) 28 | response = contracts.MakeResponse(nil, err.(error)) 29 | } 30 | }() 31 | if wego.App.Status == false { 32 | err := errors.New(constants.ErrStop) 33 | return contracts.MakeResponse(nil, err), nil 34 | } 35 | response, err = s.next(ctx, request) 36 | return contracts.MakeResponse(response, err), nil 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /servers/mqtt_subscribe_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/loggers" 5 | "github.com/9299381/wego/servers/commons" 6 | "github.com/9299381/wego/servers/mqtts" 7 | "github.com/9299381/wego/servers/transports" 8 | "github.com/go-kit/kit/endpoint" 9 | ) 10 | 11 | type MqttSubscribeCommCommServer struct { 12 | *mqtts.Server 13 | } 14 | 15 | func NewMqttSubscribeCommCommServer() *MqttSubscribeCommCommServer { 16 | ss := &MqttSubscribeCommCommServer{ 17 | Server: mqtts.NewServer(), 18 | } 19 | ss.Logger = loggers.GetLog() 20 | return ss 21 | } 22 | 23 | func (s *MqttSubscribeCommCommServer) Route(name string, endpoint endpoint.Endpoint) { 24 | 25 | handler := &commons.CommHandler{ 26 | Handler: transports.NewMqttSubscribe(endpoint), 27 | } 28 | s.Register(name, handler) 29 | } 30 | 31 | func (s *MqttSubscribeCommCommServer) Load() { 32 | 33 | //注册通用路由 34 | } 35 | 36 | func (s *MqttSubscribeCommCommServer) Start() error { 37 | return s.Serve() 38 | 39 | } 40 | 41 | func (s *MqttSubscribeCommCommServer) Close() { 42 | s.Server.Close() 43 | } 44 | -------------------------------------------------------------------------------- /demo/test/di_test/di_test.go: -------------------------------------------------------------------------------- 1 | package di_test 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/demo/test/di_test/demo" 6 | "reflect" 7 | "testing" 8 | ) 9 | 10 | func TestOne(t *testing.T) { 11 | str := "aaaaaaa" 12 | people := &demo.Man{} 13 | wego.DI().MapTo(people, (*demo.IPeople)(nil)) 14 | ret, _ := wego.DI().Invoke(func(p demo.IPeople) string { 15 | return p.Write(str) 16 | }) 17 | t.Log(ret) 18 | } 19 | 20 | func TestTwo(t *testing.T) { 21 | str := "aaaaaaa" 22 | people := &demo.Man{} 23 | wego.DI().Map(people) 24 | ret, _ := wego.DI().Invoke(func(p *demo.Man) string { 25 | return p.Write(str) 26 | }) 27 | t.Log(ret) 28 | } 29 | 30 | func TestThree(t *testing.T) { 31 | people := &demo.Man{} 32 | wego.DI().MapTo(people, (*demo.IPeople)(nil)) 33 | _, _ = wego.DI().Invoke(MyFastInvoker(nil)) 34 | } 35 | 36 | type MyFastInvoker func(people demo.IPeople) 37 | 38 | func (invoker MyFastInvoker) Invoke(args []interface{}) ([]reflect.Value, error) { 39 | if people, ok := args[0].(demo.IPeople); ok { 40 | people.Work() 41 | } 42 | return nil, nil 43 | } 44 | -------------------------------------------------------------------------------- /demo/test/json_str/json_test.go: -------------------------------------------------------------------------------- 1 | package json_str 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/9299381/wego/contracts" 7 | "github.com/9299381/wego/tools/idwork" 8 | "testing" 9 | ) 10 | 11 | type DemoStruct struct { 12 | Id string `json:"id"` 13 | Name string `json:"name"` 14 | } 15 | 16 | func TestDemoStruct(t *testing.T) { 17 | var records []*DemoStruct 18 | records = append(records, &DemoStruct{ 19 | Id: idwork.ID(), 20 | Name: "one", 21 | }) 22 | records = append(records, &DemoStruct{ 23 | Id: idwork.ID(), 24 | Name: "two", 25 | }) 26 | args, _ := json.Marshal(records) 27 | fmt.Println(string(args)) 28 | params := map[string]interface{}{ 29 | "args": string(args), 30 | } 31 | 32 | payload := &contracts.Payload{ 33 | Route: "route", 34 | Params: params, 35 | } 36 | jb, _ := json.Marshal(payload) 37 | 38 | p := &contracts.Payload{} 39 | _ = json.Unmarshal(jb, p) 40 | fmt.Println(p) 41 | 42 | var st []*DemoStruct 43 | _ = json.Unmarshal([]byte(p.Params["args"].(string)), &st) 44 | for _, v := range st { 45 | fmt.Println(v) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/controller/two_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/demo/src/service" 6 | "github.com/9299381/wego/services" 7 | "github.com/9299381/wego/tools/idwork" 8 | ) 9 | 10 | type TwoController struct { 11 | } 12 | 13 | func (s *TwoController) Handle(ctx contracts.Context) (interface{}, error) { 14 | // swagger:route Get /demo/two 分组1 twoController 15 | // Test swagger 16 | // This will ....... 17 | // Responses: 18 | // 200: twoResponse 19 | _ = services.Pipe(). 20 | Middle(&service.TwoService{}). 21 | Line(ctx) 22 | ret := &TwoResponse{ 23 | Id: idwork.ID(), 24 | UserName: ctx.Get("one").(string), 25 | } 26 | return ret, nil 27 | } 28 | func (s *TwoController) GetRules() interface{} { 29 | return &TwoRequest{} 30 | } 31 | 32 | // swagger:parameters twoController 33 | type TwoRequest struct { 34 | // 备注 35 | Name string `json:"name"` 36 | } 37 | 38 | // swagger:response twoResponse 39 | type TwoResponse struct { 40 | Id string `json:"id"` 41 | UserName string `json:"user_name"` 42 | } 43 | -------------------------------------------------------------------------------- /servers/commands/server.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/9299381/wego/args" 7 | "github.com/9299381/wego/constants" 8 | "github.com/9299381/wego/contracts" 9 | "github.com/9299381/wego/servers/commons" 10 | ) 11 | 12 | type Server struct { 13 | handlers map[string]*commons.CommHandler 14 | Logger contracts.ILogger 15 | } 16 | 17 | func NewServer() *Server { 18 | //初始化,logger,redis池 19 | s := &Server{ 20 | handlers: make(map[string]*commons.CommHandler), 21 | } 22 | return s 23 | } 24 | 25 | func (s *Server) Register(name string, handler *commons.CommHandler) { 26 | s.handlers[name] = handler 27 | 28 | } 29 | 30 | func (s *Server) Serve() error { 31 | if args.Cmd != "" { 32 | //调用服务 33 | handler, isExist := s.handlers[args.Cmd] 34 | if isExist == false { 35 | return errors.New(constants.ErrRoute) 36 | } 37 | ctx := context.Background() 38 | response, err := handler.Handle(ctx, args.Args) 39 | if err != nil { 40 | return err 41 | } 42 | s.Logger.Info(response) 43 | } 44 | return nil 45 | } 46 | func (s *Server) Close() { 47 | 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/controller/post_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/tools/convert" 6 | "github.com/9299381/wego/tools/idwork" 7 | ) 8 | 9 | type PostController struct { 10 | } 11 | 12 | // swagger:route Post /demo/post 分组2 postController 13 | // Test swagger 14 | // This will ....... 15 | // Responses: 16 | // 200: postResponse 17 | 18 | func (s *PostController) Handle(ctx contracts.Context) (interface{}, error) { 19 | 20 | request := &postRequest{} 21 | err := convert.Map2Struct(ctx.Get("request"), request) 22 | 23 | if err != nil { 24 | return nil, err 25 | } 26 | ctx.Log.Info(request) 27 | 28 | ret := &postResponse{ 29 | Id: idwork.ID(), 30 | Resp: *request, 31 | } 32 | return ret, nil 33 | } 34 | 35 | // swagger:parameters postController 36 | type postRequest struct { 37 | Id string `json:"id"` 38 | Value string `json:"value"` 39 | Number int `json:"number"` 40 | } 41 | 42 | // swagger:response postResponse 43 | type postResponse struct { 44 | Id string `json:"id"` 45 | Resp postRequest `json:"resp"` 46 | } 47 | -------------------------------------------------------------------------------- /demo/src/router/http_router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/args" 6 | "github.com/9299381/wego/servers" 7 | ) 8 | 9 | type HttpRouter struct { 10 | *servers.HttpCommServer 11 | } 12 | 13 | func (s *HttpRouter) Boot() { 14 | s.HttpCommServer = servers.NewHttpCommServer() 15 | } 16 | 17 | func (s *HttpRouter) Register() { 18 | 19 | s.Get("/demo/one", wego.Handler("one")) 20 | s.Get("/demo/two", wego.Handler("two")) 21 | s.Post("/demo/auth", wego.Handler("auth")) 22 | s.Get("/demo/sql", wego.Handler("sql")) 23 | s.Get("/demo/redis", wego.Handler("redis")) 24 | s.Post("/demo/post", wego.Handler("post")) 25 | s.Get("/demo/queue", wego.Handler("queue")) 26 | 27 | s.Get("/demo/cache_set", wego.Handler("cache_set")) 28 | s.Get("/demo/cache_get", wego.Handler("cache_get")) 29 | //验证validate 30 | s.Post("/demo/valid", wego.Handler("valid")) 31 | 32 | s.Get("/demo/consul", wego.Handler("consul")) 33 | s.Get("/demo/event", wego.Handler("event")) 34 | s.Get("/demo/publish", wego.Handler("publish")) 35 | 36 | if args.Mode != "prod" { 37 | s.HandleSwagger() 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /providers/consul_registy_provider.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/args" 6 | "github.com/9299381/wego/clients" 7 | "github.com/9299381/wego/configs" 8 | "strings" 9 | ) 10 | 11 | type ConsulRegistyProvider struct { 12 | } 13 | 14 | func (s *ConsulRegistyProvider) Boot() { 15 | 16 | } 17 | 18 | func (s *ConsulRegistyProvider) Register() { 19 | if args.Registy != "" { 20 | s.consulHttpRegister() 21 | s.consulGrpcRegister() 22 | } 23 | } 24 | func (s *ConsulRegistyProvider) consulHttpRegister() { 25 | if strings.Contains(args.Server, "http") || strings.Contains(args.Server, "gateway") { 26 | httpConfig := configs.LoadHttpConfig() 27 | wego.App.Consul["http"] = clients.NewConsulHttpRegister( 28 | args.Name, 29 | httpConfig.HttpHost, 30 | httpConfig.HttpPort, 31 | ) 32 | } 33 | } 34 | func (s *ConsulRegistyProvider) consulGrpcRegister() { 35 | if strings.Contains(args.Server, "grpc") { 36 | grpcConfig := configs.LoadGrpcConfig() 37 | wego.App.Consul["grpc"] = clients.NewConsulGrpcRegister( 38 | args.Name, 39 | grpcConfig.GrpcHost, 40 | grpcConfig.GrpcPort, 41 | ) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /clients/service.go: -------------------------------------------------------------------------------- 1 | package clients 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/contracts" 6 | ) 7 | 8 | // 为统一php模式而封装 9 | // micro -> service, service ->route 10 | func Service(service string) *microService { 11 | return µService{ 12 | service: service, 13 | params: make(map[string]interface{}), 14 | } 15 | } 16 | 17 | type microService struct { 18 | service string 19 | api string 20 | params map[string]interface{} 21 | } 22 | 23 | func (s *microService) Api(api string) *microService { 24 | s.api = api 25 | return s 26 | } 27 | 28 | func (s *microService) Params(params map[string]interface{}) *microService { 29 | s.params = params 30 | return s 31 | } 32 | 33 | func (s *microService) Run() (resp contracts.Response) { 34 | entity, err := GetConsulService(s.service) 35 | if err != nil { 36 | resp = contracts.ResponseFailed(err) 37 | return 38 | } 39 | tag := entity.Service.Tags[0] 40 | host := fmt.Sprintf("%s:%d", entity.Service.Address, entity.Service.Port) 41 | if tag == "http" { 42 | return NewHttpPostCall(host, s.api, s.params) 43 | } else if tag == "grpc" { 44 | resp = NewGrpcCall(host, s.api, s.params) 45 | } 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /clients/mongo/session.go: -------------------------------------------------------------------------------- 1 | package mongo 2 | 3 | import ( 4 | "github.com/9299381/wego/configs" 5 | "gopkg.in/mgo.v2" 6 | "log" 7 | ) 8 | 9 | var session *mgo.Session 10 | 11 | func Session() *mgo.Session { 12 | if session == nil { 13 | var err error 14 | conf := configs.LoadMongoConfig() 15 | info := &mgo.DialInfo{ 16 | Addrs: conf.Address, 17 | Timeout: conf.MaxIdleTime, 18 | Username: conf.Username, 19 | Password: conf.Password, 20 | Database: conf.Database, 21 | PoolLimit: conf.MinPoolSize, 22 | } 23 | session, err = mgo.DialWithInfo(info) 24 | if err != nil { 25 | log.Fatalf("MongoCreateSession: %s\n", err) 26 | } 27 | session.SetMode(mgo.Monotonic, true) 28 | } 29 | return session.Clone() 30 | } 31 | func Col(collection string, f func(*mgo.Collection)) { 32 | Table(configs.LoadMongoConfig().Database, collection, f) 33 | } 34 | func Table(database string, collection string, f func(*mgo.Collection)) { 35 | session := Session() 36 | defer func() { 37 | session.Close() 38 | if err := recover(); err != nil { 39 | log.Fatalf("MongoSessionError: %v", err) 40 | } 41 | }() 42 | c := session.DB(database).C(collection) 43 | f(c) 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/fsm/user_fsm.go: -------------------------------------------------------------------------------- 1 | package fsm 2 | 3 | import ( 4 | "github.com/9299381/wego/contracts" 5 | "github.com/9299381/wego/demo/src/model" 6 | "github.com/looplab/fsm" 7 | ) 8 | 9 | const Begin = "0" 10 | const Reg = "10" 11 | const Login = "20" 12 | const Lock = "30" 13 | const Named = "60" 14 | 15 | type UserFSM struct { 16 | contracts.Context 17 | *fsm.FSM 18 | User *model.CommUser 19 | } 20 | 21 | func NewUserFSM(ctx contracts.Context, user *model.CommUser) *UserFSM { 22 | s := &UserFSM{ 23 | Context: ctx, 24 | User: user, 25 | } 26 | sm := fsm.NewFSM( 27 | Begin, 28 | fsm.Events{ 29 | {Name: "register", Src: []string{Begin}, Dst: Reg}, 30 | {Name: "login", Src: []string{Reg}, Dst: Login}, 31 | {Name: "named", Src: []string{Reg, Login}, Dst: Named}, 32 | {Name: "lock", Src: []string{Reg, Login, Named}, Dst: Lock}, 33 | }, 34 | fsm.Callbacks{ 35 | "after_event": func(e *fsm.Event) { 36 | s.Log.Infof("fsm event:%s change status to %s", e.Event, e.Dst) 37 | s.User.Status = e.Dst 38 | }, 39 | }, 40 | ) 41 | if s.User.Status != "" { 42 | sm.SetState(s.User.Status) 43 | } else { 44 | sm.SetState(Begin) 45 | } 46 | 47 | s.FSM = sm 48 | return s 49 | } 50 | -------------------------------------------------------------------------------- /demo/env.toml: -------------------------------------------------------------------------------- 1 | # dev,test,prod等优先,common通用 2 | [common] 3 | # 为避免与php发生冲突,SERVER_ID 从512开始-1023,PHP则从0-63计算 4 | server_id = 512 5 | [common.server] 6 | # 用于侦听和注册到consul服务器 7 | http_host = "" 8 | http_port = 8341 9 | grpc_host = "" 10 | grpc_port = 9341 11 | # 单机版时有意义,分布式用emqx替代 12 | websocket_host = "" 13 | websocket_port = 7341 14 | 15 | 16 | [common.db] 17 | # mysql 部分 18 | connection = "mysql" 19 | host = "192.168.0.1" 20 | port = 3306 21 | database = "base" 22 | username = "root" 23 | password = "123123" 24 | timezone = "+08:00" 25 | max_idle = 5 26 | max_open = 50 27 | 28 | [common.redis] 29 | # redis 部分 30 | uri = "127.0.0.1:6937" 31 | auth = "123123" 32 | db = 1 33 | max_active = 50 34 | max_idle = 5 35 | time_out = 10 36 | 37 | [common.queue] 38 | # 队列部分 39 | # 前缀 40 | prefix = "wego" 41 | # 侦听队列 42 | listen = ["demo1"] 43 | #扫描频率,分钟 44 | interval = 1 45 | # 并发 46 | concurrency = 10 47 | 48 | [common.cache] 49 | # 缓存设置 100*1024*1024 50 | size = 104857600 51 | 52 | [common.mqtt] 53 | host = "tcp://127.0.0.1:1883" 54 | username = "" 55 | password = "" 56 | parallel = true 57 | 58 | 59 | 60 | [dev.server] 61 | http_port = 8342 62 | [dev.db] 63 | host = "127.0.0.1" 64 | 65 | 66 | [prod.db] 67 | host = "123.123.123.123" -------------------------------------------------------------------------------- /demo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/9299381/wego" 5 | "github.com/9299381/wego/args" 6 | "github.com/9299381/wego/demo/src/provider" 7 | "github.com/9299381/wego/demo/src/router" 8 | "github.com/9299381/wego/providers" 9 | "github.com/9299381/wego/servers" 10 | ) 11 | 12 | func main() { 13 | 14 | //args.Registy = "127.0.0.1:8500" 15 | args.Server = "http,grpc" 16 | 17 | //args.Server = "http,event,subscribe" 18 | //args.Server = "subscribe" 19 | //args.Server = "queue" 20 | args.Name = "demo" 21 | args.Mode = "dev" 22 | //服务注册 23 | wego.Provider(&providers.ConsulRegistyProvider{}) 24 | // api 接口 25 | wego.Provider(new(provider.DemoProvider)) 26 | // http服务器路由 27 | wego.Router("http", &router.HttpRouter{}) 28 | // grpc_api 接口服务路由 29 | wego.Router("grpc", &router.GrpcRouter{}) 30 | wego.Router("queue", &router.QueueRouter{}) 31 | wego.Router("command", &router.CommandRouter{}) 32 | wego.Router("timer", &router.TimerRouter{}) 33 | wego.Router("cron", &router.CronRouter{}) 34 | wego.Router("websocket", &router.WebSocketRouter{}) 35 | wego.Router("subscribe", &router.SubscribeRouter{}) 36 | //内置加载事件服务,无需路由,直接调用 filter handler 37 | wego.Router("event", servers.NewEventCommServer()) 38 | 39 | wego.Start() 40 | 41 | } 42 | -------------------------------------------------------------------------------- /demo/test/conver/conver_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/mitchellh/mapstructure" 6 | "testing" 7 | ) 8 | 9 | func TestMap2Struct(t *testing.T) { 10 | 11 | m := getMap() 12 | obj := &DTOStruct{} 13 | //要去掉map中key的下划线 14 | err := mapstructure.WeakDecode(m, obj) 15 | 16 | if err != nil { 17 | t.Error(err) 18 | } else { 19 | t.Log(obj) 20 | } 21 | 22 | } 23 | 24 | func getMap() map[string]interface{} { 25 | 26 | //jjson := "[{\"id\":\"123123\",\"name\":\"abcde\"},{\"id\":\"234234\",\"name\":\"asdfasdf\"}]" 27 | 28 | m := make(map[string]interface{}) 29 | //m["name"] = "asdf" 30 | //m["age"] = "123" 31 | //m["desc"] = "随便练" 32 | //m["Username"] = string(getJson()) 33 | m["user_name"] = string(getJson()) 34 | 35 | return m 36 | } 37 | 38 | func getJson() []byte { 39 | 40 | var jj []map[string]interface{} 41 | ss1 := make(map[string]interface{}) 42 | ss1["id"] = "123123" 43 | ss1["name"] = "abcde" 44 | ss2 := make(map[string]interface{}) 45 | ss2["id"] = "234234" 46 | ss2["name"] = "asdfasdf" 47 | jj = append(jj, ss1) 48 | jj = append(jj, ss2) 49 | jjson, _ := json.Marshal(jj) 50 | return jjson 51 | 52 | } 53 | 54 | type DTOStruct struct { 55 | User_Name string `json:"user_name"` 56 | } 57 | -------------------------------------------------------------------------------- /tools/tests/test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/9299381/wego/contracts" 7 | "github.com/9299381/wego/filters" 8 | "github.com/9299381/wego/tools/idwork" 9 | ) 10 | 11 | type TestStruct struct { 12 | controller contracts.IController 13 | request map[string]interface{} 14 | } 15 | 16 | func NewTest() *TestStruct { 17 | return &TestStruct{ 18 | request: make(map[string]interface{}), 19 | } 20 | } 21 | func (s *TestStruct) Controller(controller contracts.IController) *TestStruct { 22 | s.controller = controller 23 | return s 24 | } 25 | func (s *TestStruct) Request(m map[string]interface{}) *TestStruct { 26 | if m != nil { 27 | s.request = m 28 | } 29 | return s 30 | } 31 | func (s *TestStruct) Run() (contracts.Response, error) { 32 | e := filters.Chain( 33 | &filters.ResponseEndpoint{}, 34 | &filters.CommEndpoint{Controller: s.controller}, 35 | ) 36 | request := contracts.Request{ 37 | Id: idwork.ID(), 38 | Data: s.request, 39 | } 40 | response, err := e(context.Background(), request) 41 | resp := response.(contracts.Response) 42 | if err != nil { 43 | return resp, err 44 | } 45 | if resp.Code != "0000" { 46 | return resp, errors.New(resp.Message) 47 | } 48 | return resp, nil 49 | } 50 | -------------------------------------------------------------------------------- /servers/queue_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/clients" 5 | "github.com/9299381/wego/configs" 6 | "github.com/9299381/wego/loggers" 7 | "github.com/9299381/wego/servers/commons" 8 | "github.com/9299381/wego/servers/queues" 9 | "github.com/9299381/wego/servers/transports" 10 | "github.com/go-kit/kit/endpoint" 11 | ) 12 | 13 | /** 14 | redis queue 15 | */ 16 | type QueueCommServer struct { 17 | *queues.Server 18 | } 19 | 20 | func NewQueueCommServer() *QueueCommServer { 21 | config := configs.LoadQueueConfig() 22 | ss := &QueueCommServer{ 23 | Server: queues.NewServer(&queues.Options{ 24 | Prefix: config.Prefix, 25 | Listen: config.Listen, 26 | Interval: config.Interval, 27 | UseNumber: true, 28 | Concurrency: config.Concurrency, 29 | }), 30 | } 31 | ss.RedisPool = clients.RedisPool() 32 | ss.Logger = loggers.GetLog() 33 | return ss 34 | } 35 | 36 | func (s *QueueCommServer) Route(name string, endpoint endpoint.Endpoint) { 37 | 38 | handler := &commons.CommHandler{ 39 | Handler: transports.NewQueue(endpoint), 40 | } 41 | s.Register(name, handler) 42 | } 43 | 44 | func (s *QueueCommServer) Load() { 45 | 46 | //注册通用路由 47 | } 48 | 49 | func (s *QueueCommServer) Start() error { 50 | return s.Serve() 51 | 52 | } 53 | func (s *QueueCommServer) Close() { 54 | s.Server.Close() 55 | } 56 | -------------------------------------------------------------------------------- /cache/ins.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "github.com/9299381/wego/configs" 7 | "github.com/9299381/wego/constants" 8 | "github.com/coocood/freecache" 9 | "runtime/debug" 10 | "sync" 11 | ) 12 | 13 | var ins *freecache.Cache 14 | var once sync.Once 15 | 16 | func GetIns() *freecache.Cache { 17 | once.Do(func() { 18 | ins = initCache() 19 | }) 20 | return ins 21 | } 22 | 23 | func initCache() *freecache.Cache { 24 | config := configs.LoadCacheConfig() 25 | if config.Size != 0 { 26 | c := freecache.NewCache(config.Size) 27 | //根据cache的大小进行设置 28 | debug.SetGCPercent(20) 29 | return c 30 | } 31 | return nil 32 | } 33 | 34 | func Set(key string, value interface{}, exp int) error { 35 | if GetIns() == nil { 36 | return errors.New(constants.ErrCacheInit) 37 | } 38 | 39 | k := []byte(key) 40 | v, err := json.Marshal(value) 41 | if err != nil { 42 | return err 43 | } 44 | err = GetIns().Set(k, v, exp) 45 | if err != nil { 46 | return err 47 | } 48 | return nil 49 | } 50 | func Get(key string, obj interface{}) error { 51 | b, err := GetByte(key) 52 | if err != nil { 53 | return err 54 | } 55 | err = json.Unmarshal(b, obj) 56 | if err != nil { 57 | return err 58 | } 59 | return nil 60 | } 61 | func GetByte(key string) ([]byte, error) { 62 | if GetIns() == nil { 63 | return nil, errors.New(constants.ErrCacheInit) 64 | } 65 | k := []byte(key) 66 | return GetIns().Get(k) 67 | } 68 | -------------------------------------------------------------------------------- /clients/redis/pool_ins.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "fmt" 5 | "github.com/9299381/wego/configs" 6 | "github.com/gomodule/redigo/redis" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | /** 12 | MaxActive 最大连接数,即最多的tcp连接数,一般建议往大的配置, 13 | 但不要超过操作系统文件句柄个数(centos下可以ulimit -n查看)。 14 | MaxIdle 最大空闲连接数,即会有这么多个连接提前等待着,但过了超时时间也会关闭。 15 | IdleTimeout 空闲连接超时时间, 16 | 但应该设置比redis服务器超时时间短。否则服务端超时了,客户端保持着连接也没用。 17 | Wait 这是个很有用的配置。如果超过最大连接,是报错,还是等待 18 | */ 19 | 20 | var pool *redis.Pool 21 | var onceRedis sync.Once 22 | 23 | func GetRedisPool() *redis.Pool { 24 | onceRedis.Do(func() { 25 | pool = newRedisPool() 26 | }) 27 | return pool 28 | } 29 | 30 | func newRedisPool() *redis.Pool { 31 | conf := configs.LoadRedisConfig() 32 | timeout := conf.IdleTimeout 33 | pool = &redis.Pool{ 34 | MaxActive: conf.MaxActive, 35 | MaxIdle: conf.MaxIdle, 36 | IdleTimeout: timeout, 37 | Wait: true, 38 | Dial: func() (conn redis.Conn, err error) { 39 | conn, err = redis.Dial( 40 | "tcp", 41 | conf.Uri, 42 | redis.DialPassword(conf.Auth), 43 | redis.DialDatabase(conf.Db), 44 | redis.DialConnectTimeout(timeout), 45 | redis.DialReadTimeout(timeout), 46 | redis.DialWriteTimeout(timeout), 47 | ) 48 | if err != nil { 49 | return nil, fmt.Errorf("redis connection error: %s", err) 50 | } 51 | return 52 | }, 53 | TestOnBorrow: func(c redis.Conn, t time.Time) error { 54 | _, err := c.Do("PING") 55 | return err 56 | }, 57 | } 58 | 59 | return pool 60 | 61 | } 62 | -------------------------------------------------------------------------------- /contracts/message_struct.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | import "strings" 4 | 5 | type Request struct { 6 | Id string `json:"request_id"` 7 | Data map[string]interface{} 8 | } 9 | 10 | type Response struct { 11 | Ret int `json:"ret"` 12 | Code string `json:"code"` 13 | Data interface{} `json:"data"` 14 | Message string `json:"message"` 15 | } 16 | 17 | func MakeResponse(data interface{}, err error) Response { 18 | if err != nil { 19 | return ResponseFailed(err) 20 | } else { 21 | return ResponseSucess(data) 22 | } 23 | } 24 | func ResponseSucess(data interface{}) Response { 25 | return Response{ 26 | Code: "0000", 27 | Data: data, 28 | Ret: 200, 29 | Message: "请求成功", 30 | } 31 | } 32 | func ResponseFailed(err error) Response { 33 | errMap := strings.Split(err.Error(), "::") 34 | if len(errMap) == 2 { 35 | return Response{ 36 | Code: errMap[0], 37 | Data: make(map[string]interface{}), 38 | Ret: 200, 39 | Message: errMap[1], 40 | } 41 | } else { 42 | return Response{ 43 | Code: "9999", 44 | Data: make(map[string]interface{}), 45 | Ret: 200, 46 | Message: err.Error(), 47 | } 48 | } 49 | } 50 | 51 | type Payload struct { 52 | Route string `json:"route"` 53 | Params map[string]interface{} `json:"params"` 54 | } 55 | 56 | type GateWayRequest struct { 57 | Dest string 58 | Method string 59 | Id string 60 | Service string 61 | Route string 62 | Data map[string]interface{} 63 | } 64 | -------------------------------------------------------------------------------- /clients/grpc.go: -------------------------------------------------------------------------------- 1 | package clients 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "errors" 7 | "github.com/9299381/wego/contracts" 8 | "github.com/9299381/wego/servers/transports/protobuf" 9 | "github.com/9299381/wego/tools/idwork" 10 | "google.golang.org/grpc" 11 | "log" 12 | ) 13 | 14 | func NewGrpcClient(serviceAddress string, service string, params map[string]interface{}) (*protobuf.Response, error) { 15 | conn, err := grpc.Dial(serviceAddress, grpc.WithInsecure()) 16 | if err != nil { 17 | log.Fatalf("did not connect: %v", err) 18 | } 19 | defer conn.Close() 20 | 21 | jsonParam, _ := json.Marshal(params) 22 | in := &protobuf.Request{ 23 | Id: idwork.ID(), 24 | Param: string(jsonParam), 25 | } 26 | 27 | out := new(protobuf.Response) 28 | 29 | method := "/protobuf." + service + "/Handle" 30 | err = conn.Invoke(context.Background(), method, in, out) 31 | return out, err 32 | } 33 | 34 | func NewGrpcCall(host, service string, params map[string]interface{}) (ret contracts.Response) { 35 | resp, err := NewGrpcClient(host, service, params) 36 | if err != nil { 37 | ret = contracts.ResponseFailed(errors.New("没有响应的服务:" + service)) 38 | } else { 39 | m := make(map[string]interface{}) 40 | m["call_method"] = "grpc" 41 | err := json.Unmarshal([]byte(resp.GetData()), &m) 42 | if err != nil { 43 | ret = contracts.ResponseFailed(err) 44 | } else { 45 | ret.Code = resp.Code 46 | ret.Ret = 200 47 | ret.Message = resp.Msg 48 | ret.Data = m 49 | } 50 | } 51 | return 52 | } 53 | -------------------------------------------------------------------------------- /tools/helpers.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import ( 4 | "github.com/9299381/wego/tools/tests" 5 | "math/rand" 6 | "net" 7 | "time" 8 | ) 9 | 10 | func LocalIp() (string, error) { 11 | 12 | netInterfaces, err := net.Interfaces() 13 | if err != nil { 14 | return "", err 15 | } 16 | for i := 0; i < len(netInterfaces); i++ { 17 | if (netInterfaces[i].Flags & net.FlagUp) != 0 { 18 | addrs, _ := netInterfaces[i].Addrs() 19 | for _, address := range addrs { 20 | if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { 21 | if ipnet.IP.To4() != nil { 22 | return ipnet.IP.String(), nil 23 | } 24 | } 25 | } 26 | } 27 | } 28 | return "", nil 29 | 30 | } 31 | 32 | func Test() *tests.TestStruct { 33 | return tests.NewTest() 34 | } 35 | 36 | // RandString 生成随机字符串 37 | func RandString(length int, opt ...string) string { 38 | str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 39 | if opt != nil { 40 | if opt[0] == "0" { 41 | str = "0123456789" 42 | } else if opt[0] == "a" { 43 | str = "abcdefghijklmnopqrstuvwxyz" 44 | } else if opt[0] == "A" { 45 | str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 46 | } else if opt[0] == "aA" { 47 | str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 48 | } 49 | } 50 | bytes := []byte(str) 51 | bytesLen := len(bytes) 52 | var result []byte 53 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 54 | for i := 0; i < length; i++ { 55 | result = append(result, bytes[r.Intn(bytesLen)]) 56 | } 57 | return string(result) 58 | } 59 | -------------------------------------------------------------------------------- /servers/cron_comm_server.go: -------------------------------------------------------------------------------- 1 | package servers 2 | 3 | import ( 4 | "github.com/9299381/wego/servers/commons" 5 | "github.com/9299381/wego/servers/cronjobs" 6 | "github.com/9299381/wego/servers/transports" 7 | "github.com/go-kit/kit/endpoint" 8 | ) 9 | 10 | type CronCommServer struct { 11 | *cronjobs.Server 12 | } 13 | 14 | func (s *CronCommServer) Desc() { 15 | //1)星号(*) 16 | //表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month),表示每个月 17 | //2)斜线(/) 18 | //表示增长间隔,如第1个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后每隔 15 分钟执行一次(即 3、18、33、48 这些时间点执行),这里也可以表示为:3/15 19 | //3)逗号(,) 20 | //用于枚举值,如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行 21 | //4)连字号(-) 22 | //表示一个范围,如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时(包括9和17) 23 | //5)问号(?) 24 | //只用于日(Day of month)和星期(Day of week),\表示不指定值,可以用于代替 * 25 | //每隔5秒执行一次:*/5 * * * * ? 26 | //每隔1分钟执行一次:0 */1 * * * ? 27 | //每天23点执行一次:0 0 23 * * ? 28 | //每天凌晨1点执行一次:0 0 1 * * ? 29 | //每月1号凌晨1点执行一次:0 0 1 1 * ? 30 | //在26分、29分、33分执行一次:0 26,29,33 * * * ? 31 | //每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ? 32 | } 33 | 34 | func NewCronCommServer() *CronCommServer { 35 | ss := &CronCommServer{ 36 | Server: cronjobs.NewServer(), 37 | } 38 | return ss 39 | } 40 | 41 | func (s *CronCommServer) Route(spec string, endpoint endpoint.Endpoint) { 42 | 43 | handler := &commons.CommHandler{ 44 | Handler: transports.NewCronJob(endpoint), 45 | } 46 | s.Register(spec, handler) 47 | } 48 | 49 | func (s *CronCommServer) Load() { 50 | //通用加载 todo 51 | } 52 | 53 | func (s *CronCommServer) Start() error { 54 | 55 | return s.Serve() 56 | } 57 | func (s *CronCommServer) Close() { 58 | s.Server.Close() 59 | } 60 | -------------------------------------------------------------------------------- /servers/gateways/maxBytesReader.go: -------------------------------------------------------------------------------- 1 | package gateways 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | //copy from http.request 10 | type maxBytesReader struct { 11 | w http.ResponseWriter 12 | r io.ReadCloser // underlying reader 13 | n int64 // max bytes remaining 14 | err error // sticky error 15 | } 16 | 17 | func (l *maxBytesReader) Read(p []byte) (n int, err error) { 18 | if l.err != nil { 19 | return 0, l.err 20 | } 21 | if len(p) == 0 { 22 | return 0, nil 23 | } 24 | // If they asked for a 32KB byte read but only 5 bytes are 25 | // remaining, no need to read 32KB. 6 bytes will answer the 26 | // question of the whether we hit the limit or go past it. 27 | if int64(len(p)) > l.n+1 { 28 | p = p[:l.n+1] 29 | } 30 | n, err = l.r.Read(p) 31 | 32 | if int64(n) <= l.n { 33 | l.n -= int64(n) 34 | l.err = err 35 | return n, err 36 | } 37 | 38 | n = int(l.n) 39 | l.n = 0 40 | 41 | // The server code and client code both use 42 | // maxBytesReader. This "requestTooLarge" check is 43 | // only used by the server code. To prevent binaries 44 | // which only using the HTTP Client code (such as 45 | // cmd/go) from also linking in the HTTP server, don't 46 | // use a static type assertion to the server 47 | // "*response" type. Check this interface instead: 48 | type requestTooLarger interface { 49 | requestTooLarge() 50 | } 51 | if res, ok := l.w.(requestTooLarger); ok { 52 | res.requestTooLarge() 53 | } 54 | l.err = errors.New("http: request body too large") 55 | return n, l.err 56 | } 57 | 58 | func (l *maxBytesReader) Close() error { 59 | return l.r.Close() 60 | } 61 | -------------------------------------------------------------------------------- /demo/swaggerui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |