Commit 4282c0d1 by 李洪

提交

parents
File added
package db
import (
"fmt"
"sync"
"github.com/astaxie/beego/orm"
beeLogger "github.com/beego/bee/logger"
"github.com/go-redis/redis/v8"
_ "github.com/go-sql-driver/mysql"
)
var (
RedisClient *redis.Client
once sync.Once
MysqlClient orm.Ormer
)
var (
redis_host = "192.168.10.20:6379"
redis_pass = "test.eoffcn.com"
redis_db = 13
mysql_host = "rm-2zevlk47ul0ovuci80o.mysql.rds.aliyuncs.com"
mysql_user = "video"
mysql_pass = "vlty&AxMwT$lmLv6bN8dkDuBYlh%N5pe"
mysql_port = "3306"
mysql_db = "media_microservice"
mysql_charset = "utf8"
mysql_driver = "mysql"
)
func init() {
once.Do(func() {
newRedisClient()
newMysqlClient()
})
}
func newRedisClient() {
RedisClient = redis.NewClient(&redis.Options{
Addr: redis_host,
Password: redis_pass, // no password set
DB: redis_db, // use default DB
})
beeLogger.Log.Success("Redis connect success")
}
func newMysqlClient() {
dbConfStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s",
mysql_user, mysql_pass, mysql_host, mysql_port, mysql_db, mysql_charset)
_ = orm.RegisterDriver(mysql_driver, orm.DRMySQL)
err := orm.RegisterDataBase("default", mysql_driver, dbConfStr, 10, 100)
if err != nil {
beeLogger.Log.Fatalf("db connect error => %v", err)
return
}
orm.RegisterModel(new(ImUser))
orm.Debug = true
MysqlClient = orm.NewOrm()
beeLogger.Log.Success("MySQL connect success")
}
package db
type ImUser struct {
Id int64
Accid string
Appkey string
Name string
Icon string
Token string
Sign string
Mobile string
Email string
Birth string
Gender int64
Valid int64
MuteEstoppel int64
MuteAudioVideo int64
Ex string
Createtime string
Edition string
}
package gateway
import (
"context"
"net/http"
"strings"
_ "im-auth/google_api"
"im-auth/pb"
beeLogger "github.com/beego/bee/logger"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
)
// ProvideHTTP 把gRPC服务转成HTTP服务,让gRPC同时支持HTTP
func ProvideHTTP(endpoint string, grpcServer *grpc.Server) *http.Server {
ctx := context.Background()
//获取证书
//添加证书
dopts := []grpc.DialOption{grpc.WithInsecure()}
//新建gwmux,它是grpc-gateway的请求复用器。它将http请求与模式匹配,并调用相应的处理程序。
gwmux := runtime.NewServeMux()
//将服务的http处理程序注册到gwmux。处理程序通过endpoint转发请求到grpc端点
//im用户
//err = pb.RegisterImUserHandlerFromEndpoint(ctx, gwmux, endpoint, dopts)
err := pb.RegisterImAuthServiceHandlerFromEndpoint(ctx, gwmux, endpoint, dopts)
if err != nil {
beeLogger.Log.Fatalf("Register imUser err: %v", err)
}
//新建mux,它是http的请求复用器
mux := http.NewServeMux()
//注册gwmux
mux.Handle("/", gwmux)
beeLogger.Log.Success(endpoint + " HTTP.Listing...")
return &http.Server{
Addr: endpoint,
Handler: grpcHandlerFunc(grpcServer, mux),
}
}
var HeaderValues map[string]string
// grpcHandlerFunc 根据不同的请求重定向到指定的Handler处理
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Appkey") != "" {
HeaderValues = map[string]string{
"Appkey": r.Header.Get("Appkey"),
"Nonce": r.Header.Get("Nonce"),
"Curtime": r.Header.Get("Curtime"),
"Checksum": r.Header.Get("Checksum"),
}
}
ctx := context.WithValue(r.Context(), "Header", HeaderValues)
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r.WithContext(ctx))
} else {
otherHandler.ServeHTTP(w, r.WithContext(ctx))
}
}), &http2.Server{})
}
module im-auth
go 1.14
require (
cloud.google.com/go/bigquery v1.9.0 // indirect
cloud.google.com/go/storage v1.10.0 // indirect
github.com/Masterminds/goutils v1.1.0 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/aokoli/goutils v1.1.0 // indirect
github.com/astaxie/beego v1.12.1
github.com/beego/bee v1.11.1
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 // indirect
github.com/creack/pty v1.1.11 // indirect
github.com/envoyproxy/go-control-plane v0.9.5 // indirect
github.com/envoyproxy/protoc-gen-validate v0.4.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-redis/redis/v8 v8.0.0-beta.5
github.com/go-sql-driver/mysql v1.5.0
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.4.2
github.com/google/pprof v0.0.0-20200630070148-6609db78bf68 // indirect
github.com/google/uuid v1.1.1 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.2.0
github.com/grpc-ecosystem/grpc-gateway v1.14.6
github.com/grpc-ecosystem/grpc-health-probe v0.3.2 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 // indirect
github.com/ianlancetaylor/demangle v0.0.0-20200705045648-b855e248e31b // indirect
github.com/imdario/mergo v0.3.9 // indirect
github.com/kisielk/errcheck v1.3.0 // indirect
github.com/kr/pretty v0.2.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/lyft/protoc-gen-star v0.4.15 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/mwitkow/go-proto-validators v0.3.0
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.11.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/pseudomuto/protoc-gen-doc v1.3.2 // indirect
github.com/rogpeppe/go-internal v1.6.0 // indirect
github.com/rs/xid v1.2.1
github.com/segmentio/ksuid v1.0.2
github.com/spf13/afero v1.3.1 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.6.1 // indirect
go.opencensus.io v0.22.4 // indirect
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 // indirect
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
golang.org/x/text v0.3.3 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
golang.org/x/tools v0.0.0-20200709181711-e327e1019dfe // indirect
google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect
google.golang.org/grpc v1.30.0
google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/go-playground/validator.v9 v9.31.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
rsc.io/sampler v1.99.99 // indirect
)
This diff is collapsed. Click to expand it.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// source: annotations.proto
package google_api
import (
proto "github.com/golang/protobuf/proto"
descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
var file_annotations_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*descriptor.MethodOptions)(nil),
ExtensionType: (*HttpRule)(nil),
Field: 72295728,
Name: "google.api.http",
Tag: "bytes,72295728,opt,name=http",
Filename: "annotations.proto",
},
}
// Extension fields to descriptor.MethodOptions.
var (
// See `HttpRule`.
//
// optional google.api.HttpRule http = 72295728;
E_Http = &file_annotations_proto_extTypes[0]
)
var File_annotations_proto protoreflect.FileDescriptor
var file_annotations_proto_rawDesc = []byte{
0x0a, 0x11, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a,
0x0a, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73,
0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x4b, 0x0a,
0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb0, 0xca, 0xbc, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70,
0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x42, 0x24, 0x0a, 0x0e, 0x63, 0x6f,
0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x10, 0x41, 0x6e,
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_annotations_proto_goTypes = []interface{}{
(*descriptor.MethodOptions)(nil), // 0: google.protobuf.MethodOptions
(*HttpRule)(nil), // 1: google.api.HttpRule
}
var file_annotations_proto_depIdxs = []int32{
0, // 0: google.api.http:extendee -> google.protobuf.MethodOptions
1, // 1: google.api.http:type_name -> google.api.HttpRule
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
1, // [1:2] is the sub-list for extension type_name
0, // [0:1] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_annotations_proto_init() }
func file_annotations_proto_init() {
if File_annotations_proto != nil {
return
}
file_http_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_annotations_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 1,
NumServices: 0,
},
GoTypes: file_annotations_proto_goTypes,
DependencyIndexes: file_annotations_proto_depIdxs,
ExtensionInfos: file_annotations_proto_extTypes,
}.Build()
File_annotations_proto = out.File
file_annotations_proto_rawDesc = nil
file_annotations_proto_goTypes = nil
file_annotations_proto_depIdxs = nil
}
package helper
import (
"context"
"log"
"math"
"time"
"im-auth/db"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gopkg.in/go-playground/validator.v9"
)
func Valiator(in interface{}) error {
validate := validator.New()
err := validate.Struct(in)
if err != nil {
for _, err := range err.(validator.ValidationErrors) {
log.Println("error == ", err)
return status.Error(codes.PermissionDenied, "表单验证失败")
}
}
return nil
}
func GetNowTime() string {
return time.Now().Format("2006-01-02 15:04:05")
}
var ctx = context.Background()
func GetRedis(field string) (string, error) {
val, err := db.RedisClient.Get(ctx, field).Result()
if err != nil {
return "", err
}
return val, nil
}
func SetRedis(fieldKey string, val string) error {
err := db.RedisClient.Set(ctx, fieldKey, val, 0).Err()
return err
}
func DelRedis(fieldKey string) error {
err := db.RedisClient.Del(ctx, fieldKey).Err()
return err
}
func Paginate(count, step, page int64) (int64, int64) {
offset := step * (page - 1)
total := int64(math.Ceil(float64(count) / float64(step)))
return offset, total
}
package initialization
import (
"time"
"im-auth/middleware"
"im-auth/pb"
"im-auth/service/auth"
"im-auth/service/health"
"github.com/grpc-ecosystem/go-grpc-middleware"
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
grpc_validator "github.com/grpc-ecosystem/go-grpc-middleware/validator"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/reflection"
)
var (
RpcServer *grpc.Server
kaep = keepalive.EnforcementPolicy{
MinTime: 5 * time.Second,
PermitWithoutStream: true,
}
kasp = keepalive.ServerParameters{
MaxConnectionIdle: 15 * time.Second,
MaxConnectionAge: 30 * time.Second,
MaxConnectionAgeGrace: 5 * time.Second,
Time: 5 * time.Second,
Timeout: 1 * time.Second,
}
)
func init() {
rpc_server := grpc.NewServer(grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp),
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
middleware.Interceptor,
grpc_validator.UnaryServerInterceptor(),
grpc_recovery.UnaryServerInterceptor(middleware.RecoveryInterceptor()),
grpc_zap.UnaryServerInterceptor(middleware.ZapInterceptor()),
)))
srv := health.NewServer()
//pb.RegisterImUserServer(rpc_server, &im_user.ImUserServer{})
pb.RegisterHealthServer(rpc_server, srv)
pb.RegisterImAuthServiceServer(rpc_server, &auth.ImAuthServer{})
reflection.Register(rpc_server)
RpcServer = rpc_server
}
This diff is collapsed. Click to expand it.
package main
import (
"net"
"im-auth/gateway"
initialize "im-auth/initialization"
beeLogger "github.com/beego/bee/logger"
)
const (
Address string = "127.0.0.1:8000"
port = ":50051"
)
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
beeLogger.Log.Fatalf("failed to listen: %v", err)
}
beeLogger.Log.Success("gRPC server is running on " + port + " port.")
// 启动http服务
go func() {
if err := gateway.ProvideHTTP(Address, initialize.RpcServer).ListenAndServe(); err != nil {
beeLogger.Log.Fatalf("failed to api serve: %v", err)
}
}()
// 启动grpc服务
if err := initialize.RpcServer.Serve(lis); err != nil {
beeLogger.Log.Fatalf("failed to serve: %v", err)
}
}
package middleware
import (
"context"
"time"
"golang.org/x/time/rate"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
const (
healthPath = "/pb.Health/Check"
)
func Interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler) (interface{}, error) {
if info.FullMethod != healthPath {
limiter := rate.NewLimiter(rate.Every(100*time.Millisecond), 1)
if limiter.Allow() {
return handler(ctx, req)
} else {
return nil, status.Error(codes.Unauthenticated, "请求超过限制,请稍后再试")
}
}
return handler(ctx, req)
}
package middleware
import (
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// RecoveryInterceptor panic时返回Unknown错误吗
func RecoveryInterceptor() grpc_recovery.Option {
return grpc_recovery.WithRecoveryHandler(func(p interface{}) (err error) {
return status.Error(codes.Unknown, "panic triggered: "+err.Error())
})
}
package middleware
import (
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
func ZapInterceptor() *zap.Logger {
w := zapcore.AddSync(&lumberjack.Logger{
Filename: "log/debug.log",
MaxSize: 1024, //MB
LocalTime: true,
})
config := zap.NewProductionEncoderConfig()
config.EncodeTime = zapcore.ISO8601TimeEncoder
core := zapcore.NewCore(
zapcore.NewJSONEncoder(config),
w,
zap.NewAtomicLevel(),
)
logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
grpc_zap.ReplaceGrpcLoggerV2(logger)
return logger
}
This diff is collapsed. Click to expand it.
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: u-proto/im_auth.proto
/*
Package pb is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package pb
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
func request_ImAuthService_ImAuth_0(ctx context.Context, marshaler runtime.Marshaler, client ImAuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AuthRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ImAuth(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ImAuthService_ImAuth_0(ctx context.Context, marshaler runtime.Marshaler, server ImAuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AuthRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ImAuth(ctx, &protoReq)
return msg, metadata, err
}
// RegisterImAuthServiceHandlerServer registers the http handlers for service ImAuthService to "mux".
// UnaryRPC :call ImAuthServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
func RegisterImAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ImAuthServiceServer) error {
mux.Handle("POST", pattern_ImAuthService_ImAuth_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ImAuthService_ImAuth_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_ImAuthService_ImAuth_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterImAuthServiceHandlerFromEndpoint is same as RegisterImAuthServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterImAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterImAuthServiceHandler(ctx, mux, conn)
}
// RegisterImAuthServiceHandler registers the http handlers for service ImAuthService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterImAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterImAuthServiceHandlerClient(ctx, mux, NewImAuthServiceClient(conn))
}
// RegisterImAuthServiceHandlerClient registers the http handlers for service ImAuthService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ImAuthServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ImAuthServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "ImAuthServiceClient" to call the correct interceptors.
func RegisterImAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ImAuthServiceClient) error {
mux.Handle("POST", pattern_ImAuthService_ImAuth_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ImAuthService_ImAuth_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_ImAuthService_ImAuth_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_ImAuthService_ImAuth_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"im", "auth"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_ImAuthService_ImAuth_0 = runtime.ForwardResponseMessage
)
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: u-proto/im_auth.proto
package pb
import (
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
_ "github.com/mwitkow/go-proto-validators"
github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func (this *AuthRequest) Validate() error {
if this.AppId == "" {
return github_com_mwitkow_go_proto_validators.FieldError("AppId", fmt.Errorf(`value '%v' must not be an empty string`, this.AppId))
}
if this.Accid == "" {
return github_com_mwitkow_go_proto_validators.FieldError("Accid", fmt.Errorf(`value '%v' must not be an empty string`, this.Accid))
}
if this.Token == "" {
return github_com_mwitkow_go_proto_validators.FieldError("Token", fmt.Errorf(`value '%v' must not be an empty string`, this.Token))
}
if this.DeviceType == "" {
return github_com_mwitkow_go_proto_validators.FieldError("DeviceType", fmt.Errorf(`value '%v' must not be an empty string`, this.DeviceType))
}
return nil
}
func (this *AuthReply) Validate() error {
return nil
}
package auth
import (
"bytes"
"im-auth/db"
"im-auth/helper"
"im-auth/pb"
"google.golang.org/grpc/status"
)
const (
tableName = "im_user"
)
//通过accid和appkey获取用户信息
func GetImUserByAccidAppkey(accid string, appkey string) (db.ImUser, error) {
var c_user db.ImUser
err := db.MysqlClient.QueryTable(tableName).Filter("accid", accid).Filter("appkey", appkey).One(&c_user)
if err != nil {
return c_user, err
}
return c_user, nil
}
func GetLogKey(in *pb.AuthRequest) string {
var buffer bytes.Buffer
buffer.WriteString(in.Accid)
buffer.WriteString("_")
buffer.WriteString(in.AppId)
buffer.WriteString("_")
buffer.WriteString(in.DeviceType)
return buffer.String()
}
//登录处理
func LoginHandle(in *pb.AuthRequest) (int64, string) {
fieldKey := GetLogKey(in)
_, err := helper.GetRedis(fieldKey)
if err == nil {
return 417, "该种设备已经登录过了"
}
//写入redis
loginTime := helper.GetNowTime()
err = helper.SetRedis(fieldKey, loginTime)
if err != nil {
return 500, "写入redis失败"
}
return 0, "登录成功"
}
//退出处理
func LogoutHandle(in *pb.AuthRequest) error {
fieldKey := GetLogKey(in)
logStr, err := helper.GetRedis(fieldKey)
if logStr == "" {
err = status.Error(404, "没有登录信息")
return err
}
err = helper.DelRedis(fieldKey)
return err
}
package auth
import (
"context"
"im-auth/pb"
)
type ImAuthServer struct {
pb.UnimplementedImAuthServiceServer
}
//验权
func (u *ImAuthServer) ImAuth(ctx context.Context, in *pb.AuthRequest) (reply *pb.AuthReply, err error) {
reply = &pb.AuthReply{}
// 请求超时
if ctx.Err() == context.Canceled {
reply.Code = 408
reply.Msg = "请求超时"
return
}
//获取用户信息
c_user, _ := GetImUserByAccidAppkey(in.Accid, in.AppId)
if c_user.Token == "" {
reply.Code = 404
reply.Msg = "用户不存在"
return
}
//验证token
if in.Token != c_user.Token {
reply.Code = 302
reply.Msg = "token已失效"
return
}
//用户登录处理
//res, msg := LoginHandle(in)
reply.Code = 0
reply.Msg = "ok"
return
}
package health
import (
"context"
"sync"
"im-auth/pb"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type Health interface {
// Check returns if server is healthy or not
Check(c context.Context) (bool, error)
}
// 健康检测
type Server struct {
mu sync.Mutex
statusMap map[string]pb.HealthCheckResponse_ServingStatus
}
func (s *Server) Check(ctx context.Context, in *pb.HealthCheckRequest) (*pb.HealthCheckResponse, error) {
s.mu.Lock()
defer s.mu.Unlock()
if in.Service == "" {
return &pb.HealthCheckResponse{Status: pb.HealthCheckResponse_SERVING}, nil
}
if status, ok := s.statusMap[in.Service]; ok {
return &pb.HealthCheckResponse{Status: status}, nil
}
return nil, status.Error(codes.NotFound, "unkonw service")
}
func NewServer() *Server {
return &Server{
statusMap: make(map[string]pb.HealthCheckResponse_ServingStatus),
}
}
syntax = "proto3";
package google.api;
import "u-proto/google/api/http.proto";
import "google/protobuf/descriptor.proto";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}
\ No newline at end of file
// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
option cc_enable_arenas = true;
option java_multiple_files = true;
option java_outer_classname = "HttpProto";
option java_package = "com.google.api";
// Defines the HTTP configuration for a service. It contains a list of
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
message Http {
// A list of HTTP rules for configuring the HTTP REST API methods.
repeated HttpRule rules = 1;
}
// `HttpRule` defines the mapping of an RPC method to one or more HTTP
// REST APIs. The mapping determines what portions of the request
// message are populated from the path, query parameters, or body of
// the HTTP request. The mapping is typically specified as an
// `google.api.http` annotation, see "google/api/annotations.proto"
// for details.
//
// The mapping consists of a field specifying the path template and
// method kind. The path template can refer to fields in the request
// message, as in the example below which describes a REST GET
// operation on a resource collection of messages:
//
// ```proto
// service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}";
// }
// }
// message GetMessageRequest {
// message SubMessage {
// string subfield = 1;
// }
// string message_id = 1; // mapped to the URL
// SubMessage sub = 2; // `sub.subfield` is url-mapped
// }
// message Message {
// string text = 1; // content of the resource
// }
// ```
//
// This definition enables an automatic, bidrectional mapping of HTTP
// JSON to RPC. Example:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))`
//
// In general, not only fields but also field paths can be referenced
// from a path pattern. Fields mapped to the path pattern cannot be
// repeated and must have a primitive (non-message) type.
//
// Any fields in the request message which are not bound by the path
// pattern automatically become (optional) HTTP query
// parameters. Assume the following definition of the request message:
//
// ```proto
// message GetMessageRequest {
// message SubMessage {
// string subfield = 1;
// }
// string message_id = 1; // mapped to the URL
// int64 revision = 2; // becomes a parameter
// SubMessage sub = 3; // `sub.subfield` becomes a parameter
// }
// ```
//
// This enables a HTTP JSON to RPC mapping as below:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))`
//
// Note that fields which are mapped to HTTP parameters must have a
// primitive type or a repeated primitive type. Message types are not
// allowed. In the case of a repeated type, the parameter can be
// repeated in the URL, as in `...?param=A&param=B`.
//
// For HTTP method kinds which allow a request body, the `body` field
// specifies the mapping. Consider a REST update method on the
// message resource collection:
//
// ```proto
// service Messaging {
// rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
// option (google.api.http) = {
// put: "/v1/messages/{message_id}"
// body: "message"
// };
// }
// }
// message UpdateMessageRequest {
// string message_id = 1; // mapped to the URL
// Message message = 2; // mapped to the body
// }
// ```
//
// The following HTTP JSON to RPC mapping is enabled, where the
// representation of the JSON in the request body is determined by
// protos JSON encoding:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
//
// The special name `*` can be used in the body mapping to define that
// every field not bound by the path template should be mapped to the
// request body. This enables the following alternative definition of
// the update method:
//
// ```proto
// service Messaging {
// rpc UpdateMessage(Message) returns (Message) {
// option (google.api.http) = {
// put: "/v1/messages/{message_id}"
// body: "*"
// };
// }
// }
// message Message {
// string message_id = 1;
// string text = 2;
// }
// ```
//
// The following HTTP JSON to RPC mapping is enabled:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")`
//
// Note that when using `*` in the body mapping, it is not possible to
// have HTTP parameters, as all fields not bound by the path end in
// the body. This makes this option more rarely used in practice of
// defining REST APIs. The common usage of `*` is in custom methods
// which don't use the URL at all for transferring data.
//
// It is possible to define multiple HTTP methods for one RPC by using
// the `additional_bindings` option. Example:
//
// ```proto
// service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http) = {
// get: "/v1/messages/{message_id}"
// additional_bindings {
// get: "/v1/users/{user_id}/messages/{message_id}"
// }
// };
// }
// }
// message GetMessageRequest {
// string message_id = 1;
// string user_id = 2;
// }
// ```
//
// This enables the following two alternative HTTP JSON to RPC
// mappings:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")`
//
// # Rules for HTTP mapping
//
// The rules for mapping HTTP path, query parameters, and body fields
// to the request message are as follows:
//
// 1. The `body` field specifies either `*` or a field path, or is
// omitted. If omitted, it assumes there is no HTTP body.
// 2. Leaf fields (recursive expansion of nested messages in the
// request) can be classified into three types:
// (a) Matched in the URL template.
// (b) Covered by body (if body is `*`, everything except (a) fields;
// else everything under the body field)
// (c) All other fields.
// 3. URL query parameters found in the HTTP request are mapped to (c) fields.
// 4. Any body sent with an HTTP request can contain only (b) fields.
//
// The syntax of the path template is as follows:
//
// Template = "/" Segments [ Verb ] ;
// Segments = Segment { "/" Segment } ;
// Segment = "*" | "**" | LITERAL | Variable ;
// Variable = "{" FieldPath [ "=" Segments ] "}" ;
// FieldPath = IDENT { "." IDENT } ;
// Verb = ":" LITERAL ;
//
// The syntax `*` matches a single path segment. It follows the semantics of
// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String
// Expansion.
//
// The syntax `**` matches zero or more path segments. It follows the semantics
// of [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.3 Reserved
// Expansion.
//
// The syntax `LITERAL` matches literal text in the URL path.
//
// The syntax `Variable` matches the entire path as specified by its template;
// this nested template must not contain further variables. If a variable
// matches a single path segment, its template may be omitted, e.g. `{var}`
// is equivalent to `{var=*}`.
//
// NOTE: the field paths in variables and in the `body` must not refer to
// repeated fields or map fields.
//
// Use CustomHttpPattern to specify any HTTP method that is not included in the
// `pattern` field, such as HEAD, or "*" to leave the HTTP method unspecified for
// a given URL path rule. The wild-card rule is useful for services that provide
// content to Web (HTML) clients.
message HttpRule {
// Selects methods to which this rule applies.
//
// Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
string selector = 1;
// Determines the URL pattern is matched by this rules. This pattern can be
// used with any of the {get|put|post|delete|patch} methods. A custom method
// can be defined using the 'custom' field.
oneof pattern {
// Used for listing and getting information about resources.
string get = 2;
// Used for updating a resource.
string put = 3;
// Used for creating a resource.
string post = 4;
// Used for deleting a resource.
string delete = 5;
// Used for updating a resource.
string patch = 6;
// Custom pattern is used for defining custom verbs.
CustomHttpPattern custom = 8;
}
// The name of the request field whose value is mapped to the HTTP body, or
// `*` for mapping all fields not captured by the path pattern to the HTTP
// body. NOTE: the referred field must not be a repeated field.
string body = 7;
// Additional HTTP bindings for the selector. Nested bindings must
// not contain an `additional_bindings` field themselves (that is,
// the nesting may only be one level deep).
repeated HttpRule additional_bindings = 11;
}
// A custom pattern is used for defining custom HTTP verb.
message CustomHttpPattern {
// The name of this custom HTTP verb.
string kind = 1;
// The path matched by this custom verb.
string path = 2;
}
syntax = "proto3";
package pb;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
}
\ No newline at end of file
syntax = "proto3";
package pb;
//import "u-proto/google/api/annotations.proto";
import "github.com/mwitkow/go-proto-validators/validator.proto";
//用户鉴权
message AuthRequest {
string AppId = 1[(validator.field) = {string_not_empty: true}];
string Accid = 2[(validator.field) = {string_not_empty: true}];
string Token = 3[(validator.field) = {string_not_empty: true}];
string DeviceType = 4[(validator.field) = {string_not_empty: true}];
}
//鉴权返回
message AuthReply {
int64 Code = 1;
string Msg = 2;
}
service ImAuthService {
rpc ImAuth (AuthRequest) returns(AuthReply) {}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment