Commit ee471383 authored by 赵文静's avatar 赵文静

增加一个http的入口

parent 9f03e311
package app
import (
"fmt"
"net/http"
"speech-nlu-parse/pkg/util"
"time"
"github.com/gin-gonic/gin"
)
type Response struct {
ctx *gin.Context
}
func NewResponse(ctx *gin.Context) *Response {
response := &Response{
ctx: ctx,
}
response.ctx.Header("Content-Type", "application/json;charset=utf-8")
return response
}
func (r *Response) ToResponse(v interface{}) {
if r.ctx.Writer.Written() {
return
}
data := v
r.ctx.JSON(http.StatusOK, data)
}
func (r *Response) ToFormatErrResponse(errStr string) {
fmt.Println(r.ctx.Writer.Written(), time.Now().Unix())
if r.ctx.Writer.Written() {
return
}
data := gin.H{
"code": 401,
"errorType": "request data error, check it and try again![" + errStr + "]",
}
r.ctx.JSON(http.StatusOK, data)
}
func (r *Response) ToByteResponse(data []byte) {
if r.ctx.Writer.Written() {
return
}
// 直接返回原始字节数据(确保data已经是合法的JSON字符串)
//r.ctx.Data(http.StatusOK, "application/json", data)
//r.ctx.JSON(http.StatusOK, data)
//r.ctx.Data(http.StatusOK, "application/json;charset=utf-8", data)
r.ctx.JSON(http.StatusOK, util.GetJsonTool().Get(data).GetInterface())
}
POST http://localhost:19990/semantic/unisoundc2c/speech-nlu-parse
Content-Type: application/json
{
"ip": "14.215.222.17",
"mac": "ece154a865eb",
"mid": "11011",
"query":"今天星期几",
"requestId": "123456111"
}
###
#POST https://nlu.gree.com/semantic/unisoundc2c/querys
POST https://testnlu.gree.com/semantic/unisoundc2c/querys
#POST http://172.28.124.216:9999/semantic/unisoundc2c/querys
......@@ -33,7 +45,7 @@ Content-Type: application/json
},
"nluRet": {
"asr_recongize": "",
"text": "讲个笑话"
"text": "今天星期几"
}
},
"version": "v0"
......
......@@ -7,6 +7,8 @@ Server:
ConsulAddr: 172.28.124.105:8500 #consul的地址
Interval: 10 #健康检查间隔,单位:秒
Deregister: 1 #注销时间,相当于过期时间,单位:分钟
HttpPort: 19990
UriPath: /semantic/unisoundc2c/speech-nlu-parse
RabbitMq:
Url: amqp://iot:qwe!23@172.28.124.106:5672/voice
......
......@@ -3,30 +3,43 @@ module speech-nlu-parse
go 1.18
require (
github.com/gin-gonic/gin v1.10.1
github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.7.1
github.com/golang/protobuf v1.5.3
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/hashicorp/consul/api v1.21.0
github.com/jinzhu/gorm v1.9.16
github.com/json-iterator/go v1.1.12
github.com/parnurzeal/gorequest v0.2.16
github.com/rabbitmq/amqp091-go v1.10.0
github.com/spf13/viper v1.16.0
github.com/tidwall/gjson v1.14.4
go.uber.org/zap v1.24.0
google.golang.org/grpc v1.56.0
google.golang.org/protobuf v1.30.0
google.golang.org/protobuf v1.34.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
require (
github.com/armon/go-metrics v0.4.0 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
......@@ -35,16 +48,17 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
github.com/smartystreets/goconvey v1.8.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
......@@ -53,11 +67,15 @@ require (
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
......
This diff is collapsed.
package main
import (
"context"
"errors"
"flag"
"fmt"
"github.com/gin-gonic/gin"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"google.golang.org/grpc"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"
"log"
"net"
"net/http"
"net/url"
"os"
"os/signal"
......@@ -17,6 +20,7 @@ import (
"speech-nlu-parse/middleware"
"speech-nlu-parse/pkg/database"
"speech-nlu-parse/pkg/proto"
"speech-nlu-parse/router"
"speech-nlu-parse/service"
"speech-nlu-parse/service/speechNlu"
"strings"
......@@ -138,6 +142,26 @@ func main() {
}
}()
// 初始化并启动 HTTP 服务
gin.SetMode(global.ServerSetting.RunMode)
engine := router.InitRouter()
_ = engine.SetTrustedProxies(nil) //不使用信任代理功能,即不使用gin策略再对来源过滤
s := http.Server{
Addr: ":" + global.ServerSetting.HttpPort,
Handler: engine,
//ReadTimeout: global.ServerSetting.ReadTimeout, //设置连接的最大读取时间
//WriteTimeout: global.ServerSetting.WriteTimeout, //设置连接的最大写入时间
MaxHeaderBytes: 1 << 20,
}
go func() {
global.Logger.Infof("HTTP service is running on port %s", "global.ServerSetting.HttpPort")
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("[FATAL] HTTP serve error: %v", err)
}
}()
// 阻塞等待信号
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
......@@ -145,6 +169,16 @@ func main() {
// 优雅关闭
log.Println("[INFO] Shutting down...")
// 创建上下文用于优雅关闭
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 先关闭HTTP服务
if err := s.Shutdown(ctx); err != nil {
log.Printf("[WARN] HTTP server shutdown error: %v", err)
}
server.GracefulStop()
log.Println("[INFO] Server stopped")
}
......
......@@ -18,6 +18,11 @@ type ConsulSettingS struct {
ConsulToken string
Interval time.Duration
Deregister time.Duration
HttpPort string
UriPath string
ReadTimeout time.Duration
WriteTimeout time.Duration
//DefaultContextTimeout time.Duration
}
func RegisterService(cs *ConsulSettingS) error {
......
package util
import (
"crypto/md5"
"encoding/hex"
"strconv"
"strings"
"time"
jsoniter "github.com/json-iterator/go"
)
// ConfigCompatibleWithStandardLibrary 尝试100%与标准库行为兼容
var jsonT = jsoniter.ConfigCompatibleWithStandardLibrary // 更换日志工具包---转入全局公共类,方便所有包调用
// Interface2String interface{} 对象转换成 string 字符串
func Interface2String(inter interface{}) string {
switch inter.(type) {
case string:
return inter.(string)
case int:
return strconv.Itoa(inter.(int))
case float64:
return strconv.FormatFloat(inter.(float64), 'f', 0, 64)
case []uint8:
return string(inter.([]uint8))
case int64:
return strconv.Itoa(int(inter.(int64)))
case time.Time:
return inter.(time.Time).Format("2006-01-02 15:04:05")
case nil:
return ""
default:
var str string
str, _ = jsonT.MarshalToString(inter)
return str
}
}
// ParseToInterface 将 []byte 转化为 interface{}
func ParseToInterface(bs []byte) interface{} {
return jsonT.Get(bs).GetInterface()
}
func GetJsonTool() jsoniter.API {
return jsonT
}
// StringBuilderAppend 字符串高效拼接,bytes.Builder 也有类似效果
// 大量才有优化效果,如果小量不如使用 + 直接拼
func StringBuilderAppend(s ...string) string {
var res strings.Builder
for i := 0; i < len(s); i++ {
res.WriteString(s[i])
}
return res.String()
}
func MD5WithSalt(text, salt string) string {
// 盐值拼接方式可自定义(如 salt + text + salt)
hash := md5.Sum([]byte(text + salt))
return hex.EncodeToString(hash[:])
}
package router
import (
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/tidwall/gjson"
"speech-nlu-parse/app"
"speech-nlu-parse/global"
"speech-nlu-parse/model"
"speech-nlu-parse/pkg/logger"
"speech-nlu-parse/pkg/proto"
"speech-nlu-parse/service/speechNlu"
"strings"
)
func InitRouter() (engine *gin.Engine) {
// 获取并增加日志与恢复中间件
//engine = gin.Default()
engine = gin.New()
engine.Use(gin.Recovery())
// 超时限制测试
//engine.Use(middleware.TimeLimitMiddleware(time.Second * 5))
engine.POST(global.ServerSetting.UriPath, Controller)
return
}
type SnpReq struct {
Ip string `json:"ip"`
Mac string `json:"mac"`
Mid string `json:"mid"`
Query string `json:"query"`
RequestId string `json:"requestId"`
}
func Controller(ctx *gin.Context) {
req := SnpReq{}
response := app.NewResponse(ctx)
if err := ctx.ShouldBind(&req); err != nil {
global.Logger.Errorf("redis.ShouldBind err: %v ", err)
response.ToFormatErrResponse(err.Error())
return
}
if strings.TrimSpace(req.Query) == "" || strings.TrimSpace(req.Mac) == "" {
response.ToFormatErrResponse("请求格式错误")
return
}
if req.Ip == "" {
req.Ip = ctx.ClientIP()
}
if req.RequestId == "" {
req.RequestId = uuid.New().String()
}
global.Logger.WithFields(logger.Fields{"query": req.Query, "mac": req.Mac, "mid": req.Mid, "requestId": req.RequestId, "ip": req.Ip}).Info("speech-nlu-parse-http request")
semanticReq := SpeechNluParseSemanticRequest(req)
jsonStr, code := speechNlu.SpeechNlu(semanticReq)
responseText := gjson.Get(jsonStr, "response_text").String()
response1 := &proto.SemanticResponse{Status: &proto.Status{Code: code.Code(), Msg: code.Msg()}, Data: &proto.SemanticData{SemanticRespJsonData: jsonStr}}
responseBody, _ := json.Marshal(response1)
defer global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"responseBody": string(responseBody), "query": req.Query, "responseText": responseText}, "mac": req.Mac, "mid": req.Mid, "requestId": req.RequestId, "ip": req.Ip}).Info("speech-nlu-parse-http response")
// 直接返回 semanticRespJsonData 的原始内容(已经是JSON字符串)
//ctx.Data(http.StatusOK, "application/json", []byte(jsonStr))
response.ToByteResponse([]byte(jsonStr))
return
}
func SpeechNluParseSemanticRequest(req SnpReq) *model.SemanticReq {
semanticReq := &model.SemanticReq{
MacWifi: req.Mac,
MacVoice: req.Mac,
Query: req.Query,
Ip: req.Ip,
OriginQuery: req.Query,
Mid: req.Mid,
RequestId: req.RequestId,
}
return semanticReq
}
......@@ -507,7 +507,7 @@ func GetSemanticReq(md map[string][]string) (*model.TencentNluParseStreamMetaDat
func (this TencentNlu) TencentNluParse(ctx context.Context, r *proto.SemanticRequest) (*proto.SemanticResponse, error) {
requestBody, _ := json.Marshal(r)
global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"requestBody": string(requestBody), "query": r.GetQuery()}, "mac": r.GetMacWifi(), "mid": r.GetMid(), "vender": r.GetVender(), "requestId": r.RequestId}).Info("tencent-nlu-parse-grpc request")
global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"requestBody": string(requestBody), "query": r.GetQuery()}, "mac": r.GetMacWifi(), "mid": r.GetMid(), "vender": r.GetVender(), "requestId": r.RequestId, "ip": r.Ip}).Info("speech-nlu-parse-grpc request")
semanticReq := TencentNluParseSemanticRequest2ModelSemanticReq(r)
fmt.Println(semanticReq)
......@@ -515,7 +515,7 @@ func (this TencentNlu) TencentNluParse(ctx context.Context, r *proto.SemanticReq
responseText := gjson.Get(jsonStr, "response_text").String()
response := &proto.SemanticResponse{Status: &proto.Status{Code: code.Code(), Msg: code.Msg()}, Data: &proto.SemanticData{SemanticRespJsonData: jsonStr}}
responseBody, _ := json.Marshal(response)
defer global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"responseBody": string(responseBody), "query": r.GetQuery(), "responseText": responseText}, "mac": r.GetMacWifi(), "mid": r.GetMid(), "vender": r.GetVender(), "requestId": r.RequestId}).Info("tencent-nlu-parse-grpc response")
defer global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"responseBody": string(responseBody), "query": r.GetQuery(), "responseText": responseText}, "mac": r.GetMacWifi(), "mid": r.GetMid(), "vender": r.GetVender(), "requestId": r.RequestId, "ip": r.Ip}).Info("speech-nlu-parse-grpc response")
return response, nil
}
......@@ -654,7 +654,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream websocket closed.")
}).Info("SpeechNluParseStream websocket closed.")
} else {
global.Logger.WithFields(logger.Fields{
"requestId": requestId,
......@@ -662,7 +662,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Errorf("TencentNluParseStream tencentNluWs.Recv error. %v", err)
}).Errorf("SpeechNluParseStream speechNluWs.Recv error. %v", err)
}
nlpWsConn.Close()
cancel()
......@@ -675,7 +675,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream tencentNluWs.Recv.")
}).Info("SpeechNluParseStream speechNluWs.Recv.")
// 解析
// tencentNluWs := tencentNlu.TencentNlpWs{}
res := speechNluWs.ParseSpeechNluData(data, requestId, sessionId)
......@@ -691,7 +691,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
responseBody, _ := json.Marshal(resp)
global.Logger.WithFields(logger.Fields{
"data": map[string]interface{}{
"tencentNluParseStreamBody": string(responseBody),
"speechNluParseStreamBody": string(responseBody),
"responseText": responseText,
},
"requestId": requestId,
......@@ -699,7 +699,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream stream.Send.")
}).Info("SpeechNluParseStream stream.Send.")
responseType := gjson.GetBytes(res, "header.semantic.ResponseType").String()
if responseType == "semantic.close" {
nlpWsConn.Close()
......@@ -722,7 +722,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream stream is canceled.")
}).Info("SpeechNluParseStream stream is canceled.")
cancel()
return nil
}
......@@ -734,7 +734,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream stream closed.")
}).Info("SpeechNluParseStream stream closed.")
// 客户端关闭
} else {
global.Logger.WithFields(logger.Fields{
......@@ -743,7 +743,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Errorf("TencentNluParseStream stream.Recv error. %v", err)
}).Errorf("SpeechNluParseStream stream.Recv error. %v", err)
}
cancel()
return nil
......@@ -751,7 +751,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
requestBody, _ := json.Marshal(data)
global.Logger.WithFields(logger.Fields{
"data": map[string]interface{}{
"tencentNluParseStreamBody": string(requestBody),
"speechNluParseStreamBody": string(requestBody),
"query": data.Query,
},
"requestId": requestId,
......@@ -759,7 +759,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream stream.Recv.")
}).Info("SpeechNluParseStream stream.Recv.")
select {
case <-cancelCtx.Done():
// 腾讯 ws 关闭了
......@@ -771,7 +771,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
tRequestBody, _ := json.Marshal(data)
global.Logger.WithFields(logger.Fields{
"data": map[string]interface{}{
"tencentNluParseStreamBody": string(tRequestBody),
"speechNluParseStreamBody": string(tRequestBody),
"query": data.Query,
},
"requestId": requestId,
......@@ -779,7 +779,7 @@ func (TencentNlu) TencentNluParseStream(stream proto.TencentNlu_TencentNluParseS
"mid": mid,
"vender": vender,
"sessionId": sessionId,
}).Info("TencentNluParseStream tencentNluWs.Send.")
}).Info("SpeechNluParseStream speechNluWs.Send.")
}
}
}
......@@ -46,7 +46,7 @@ func (s *SpeechNlpWs) SpeechWs(ip, deviceId string) (*websocket.Conn, error) {
}
global.Logger.WithFields(logger.Fields{
"url": SpeechUrl,
}).Errorf("[SpeechWs] Connect")
}).Info("[SpeechWs] Connect")
return conn, nil
}
......
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