ws
CI / changes (push) Successful in 1m31s
CI / ad (push) Successful in 32s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 19s
CI / chore (push) Successful in 18s
CI / equipment (push) Successful in 19s
CI / express (push) Successful in 18s
CI / factory (push) Successful in 17s
CI / message (push) Successful in 18s
CI / order (push) Successful in 17s
CI / payment (push) Successful in 17s
CI / percutaneous (push) Successful in 17s
CI / product (push) Successful in 17s
CI / record (push) Successful in 9m26s
CI / sale (push) Successful in 45s
CI / support (push) Successful in 3m8s
CI / task (push) Successful in 27s
CI / user (push) Successful in 21s
CI / wecom (push) Successful in 19s
CI / changes (push) Successful in 1m31s
CI / ad (push) Successful in 32s
CI / admin (push) Successful in 22s
CI / bff (push) Successful in 19s
CI / chore (push) Successful in 18s
CI / equipment (push) Successful in 19s
CI / express (push) Successful in 18s
CI / factory (push) Successful in 17s
CI / message (push) Successful in 18s
CI / order (push) Successful in 17s
CI / payment (push) Successful in 17s
CI / percutaneous (push) Successful in 17s
CI / product (push) Successful in 17s
CI / record (push) Successful in 9m26s
CI / sale (push) Successful in 45s
CI / support (push) Successful in 3m8s
CI / task (push) Successful in 27s
CI / user (push) Successful in 21s
CI / wecom (push) Successful in 19s
This commit is contained in:
@@ -41,9 +41,10 @@ func (l *AddUserLogic) AddUser(in *percutaneous.AddUserRequest) (*percutaneous.R
|
||||
}
|
||||
w := modelbase.Params{Eq: map[string]string{
|
||||
"host_code": in.HostCode,
|
||||
"host_user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen),
|
||||
"user_id": strconv.FormatInt(in.UserId, utils.NumberTen),
|
||||
"host_user_id": strconv.FormatInt(in.UserId, utils.NumberTen),
|
||||
"user_id": strconv.FormatInt(adminInfo.ID, utils.NumberTen),
|
||||
}}
|
||||
|
||||
var info dao.Group
|
||||
err := model.GroupModel{}.Init().GetOne(w, &info)
|
||||
if err != nil {
|
||||
@@ -61,5 +62,13 @@ func (l *AddUserLogic) AddUser(in *percutaneous.AddUserRequest) (*percutaneous.R
|
||||
}
|
||||
}
|
||||
|
||||
// 取出等待中的ws会话
|
||||
sess := l.svcCtx.SessionMgr.Pop(in.HostCode)
|
||||
if sess == nil {
|
||||
l.Logger.Error("no waiting ws session code is = ", in.HostCode)
|
||||
return l.ok(utils.NumberOne)
|
||||
}
|
||||
|
||||
sess.MsgCh <- []byte(strconv.FormatInt(adminInfo.ID, utils.NumberTen))
|
||||
return l.ok(utils.NumberOne)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package logic
|
||||
import (
|
||||
"context"
|
||||
"lone-services/pkg/utils"
|
||||
user "lone-services/rpc/user/pb"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"lone-services/rpc/percutaneous/pb"
|
||||
@@ -13,12 +15,29 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type grpcStreamWrapper struct {
|
||||
stream percutaneous.Percutaneous_WsAddUserStreamServer
|
||||
}
|
||||
|
||||
func (w *grpcStreamWrapper) Send(payload []byte) error {
|
||||
frame := &percutaneous.WsStreamRequest{
|
||||
RawBody: payload,
|
||||
}
|
||||
return w.stream.Send(frame)
|
||||
}
|
||||
|
||||
type WsAddUserStreamLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
type userInfo struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
func NewWsAddUserStreamLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WsAddUserStreamLogic {
|
||||
return &WsAddUserStreamLogic{
|
||||
ctx: ctx,
|
||||
@@ -29,50 +48,85 @@ func NewWsAddUserStreamLogic(ctx context.Context, svcCtx *svc.ServiceContext) *W
|
||||
|
||||
// 添加用户
|
||||
func (l *WsAddUserStreamLogic) WsAddUserStream(stream percutaneous.Percutaneous_WsAddUserStreamServer) error {
|
||||
l.Logger.Error("in coming ws tunnel stream")
|
||||
l.Logger.Info("in coming ws tunnel stream")
|
||||
ctx := stream.Context()
|
||||
// 扫码超时30s
|
||||
timeout := 30 * time.Second
|
||||
timeout := time.Duration(utils.GetConfigInt("ws.out_time")) * time.Second
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
defer func() {
|
||||
cancel()
|
||||
}()
|
||||
|
||||
for {
|
||||
// 先判断上下文是否已经结束
|
||||
if err := ctx.Err(); err != nil {
|
||||
if err == context.DeadlineExceeded {
|
||||
return status.Errorf(codes.DeadlineExceeded, "扫码超时")
|
||||
}
|
||||
// BFF自动发来第一条消息,读取host_code
|
||||
recvFrame, err := stream.Recv()
|
||||
if err != nil {
|
||||
l.Logger.Errorf("recv host_code failed: %v", err)
|
||||
return err
|
||||
}
|
||||
var hostCode struct {
|
||||
Code string `json:"host_code"`
|
||||
}
|
||||
l.Logger.Errorf(" host_code raw msg is: %v", string(recvFrame.RawBody))
|
||||
// 保留你确认的 !err 判断
|
||||
if ok := utils.JsonStringToStruct(string(recvFrame.RawBody), &hostCode); !ok {
|
||||
return status.Errorf(codes.InvalidArgument, "device code parse error")
|
||||
}
|
||||
l.Logger.Infof("device connected, code=%s", hostCode.Code)
|
||||
|
||||
msgCh := make(chan []byte, 1)
|
||||
wrapper := &grpcStreamWrapper{stream: stream}
|
||||
sess := &utils.WaitingSession{
|
||||
Stream: wrapper,
|
||||
Ctx: ctx,
|
||||
Cancel: cancel,
|
||||
MsgCh: msgCh,
|
||||
}
|
||||
l.svcCtx.SessionMgr.Register(hostCode.Code, sess)
|
||||
defer l.svcCtx.SessionMgr.Remove(hostCode.Code)
|
||||
l.Logger.Info("session register success, waiting for scan event")
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return status.Errorf(codes.DeadlineExceeded, "扫码等待超时")
|
||||
}
|
||||
return ctx.Err()
|
||||
case payload := <-msgCh:
|
||||
id, _ := strconv.Atoi(string(payload))
|
||||
info := l.getUserInfo(int64(id))
|
||||
jsonData := utils.StructToJson(info)
|
||||
if err := sess.Stream.Send([]byte(jsonData)); err != nil {
|
||||
l.Logger.Errorf("send to device err: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 阻塞等待客户端上报扫码消息
|
||||
recvFrame, err := stream.Recv()
|
||||
if err != nil {
|
||||
// 客户端主动关闭流
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析扫码payload
|
||||
type res struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
var resData res
|
||||
if err := utils.JsonStringToStruct(string(recvFrame.RawBody), &resData); !err {
|
||||
l.Logger.Errorf("parse scan payload failed: %v", err)
|
||||
return status.Errorf(codes.InvalidArgument, "解析扫码数据失败")
|
||||
}
|
||||
l.Logger.Errorf("receive scan success data: %+v", resData)
|
||||
|
||||
// 下发结果给ws客户端(同步设备)
|
||||
sendFrame := &percutaneous.WsStreamRequest{
|
||||
RawBody: []byte(utils.StructToJson(resData)),
|
||||
}
|
||||
if err := stream.Send(sendFrame); err != nil {
|
||||
l.Logger.Errorf("send result frame failed: %v", err)
|
||||
return err
|
||||
}
|
||||
// 收发完成,直接关闭grpc双向流(ws连接随之断开)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *WsAddUserStreamLogic) getUserInfo(id int64) *userInfo {
|
||||
if id == utils.NumberZero {
|
||||
return nil
|
||||
}
|
||||
logx.Errorf("get user id: %v", id)
|
||||
cli, err := svc.GetRpcClient(l.svcCtx.UserName)
|
||||
if err != nil {
|
||||
logx.Errorf("get user err: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
client := user.NewUserClient(cli.Conn())
|
||||
|
||||
data := user.InternalGetUserInfoReq{
|
||||
UserId: id,
|
||||
}
|
||||
res, err := client.InternalGetUserInfo(context.Background(), &data)
|
||||
if err != nil {
|
||||
logx.Errorf("get user err: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return &userInfo{
|
||||
Id: res.Id,
|
||||
Name: res.Name,
|
||||
Avatar: res.Avatar,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user