19 changed files with 809 additions and 30 deletions
@ -1,3 +1,71 @@ |
|||||
# laic-backend |
# laic-backend |
||||
|
|
||||
低空智控平台 后端go |
|
||||
|
低空智控平台 后端 Go 服务。 |
||||
|
|
||||
|
## 生产部署 |
||||
|
|
||||
|
部署脚本参考 `D:/GoProject/roller-service/roller-manage/publish-prod.sh`,使用 Supervisor 管理服务。 |
||||
|
|
||||
|
### 服务器准备 |
||||
|
|
||||
|
在生产服务器安装 Supervisor。生产配置保存在仓库根目录的 `config-prod.yaml`,部署脚本会将它上传为服务器部署目录中的 `config.yaml`: |
||||
|
|
||||
|
```bash |
||||
|
sudo apt update |
||||
|
sudo apt install supervisor -y |
||||
|
sudo systemctl enable --now supervisor |
||||
|
``` |
||||
|
|
||||
|
生产配置至少包含: |
||||
|
|
||||
|
```yaml |
||||
|
oss: |
||||
|
endpoint: https://obs.cn-east-2.myhuaweicloud.com |
||||
|
access-key: 实际的华为云 OBS AK |
||||
|
secret-key: 实际的华为云 OBS SK |
||||
|
bucket: gcs-edu |
||||
|
region: cn-east-2 |
||||
|
use-ssl: true |
||||
|
``` |
||||
|
|
||||
|
后端启动时直接读取部署目录下的 `config.yaml`。本地开发不设置 `LAIC_CONFIG_FILE` 时读取本地 `config.yaml`;Supervisor 显式设置 `LAIC_CONFIG_FILE=config.yaml`。 |
||||
|
|
||||
|
### 执行部署 |
||||
|
|
||||
|
修改 `publish-prod.sh` 顶部的 `REMOTE`、`REMOTE_DIR` 和服务参数,然后执行: |
||||
|
|
||||
|
```bash |
||||
|
chmod +x publish-prod.sh |
||||
|
./publish-prod.sh |
||||
|
``` |
||||
|
|
||||
|
脚本会完成: |
||||
|
|
||||
|
1. 交叉编译 Linux amd64 二进制。 |
||||
|
2. 创建远程部署目录、日志目录和备份目录。 |
||||
|
3. 备份旧二进制和 `config.yaml`(首次部署没有旧文件时跳过)。 |
||||
|
4. 将本地 `config-prod.yaml` 上传为远程 `config.yaml`。 |
||||
|
5. 更新 Supervisor 配置、重启服务并检查状态。 |
||||
|
6. 启动失败时自动恢复最近的旧二进制。 |
||||
|
|
||||
|
首次部署前确认远程服务器已安装并运行 Supervisor: |
||||
|
|
||||
|
```bash |
||||
|
sudo apt update |
||||
|
sudo apt install supervisor -y |
||||
|
sudo systemctl enable --now supervisor |
||||
|
``` |
||||
|
|
||||
|
查看状态和日志: |
||||
|
|
||||
|
```bash |
||||
|
sudo supervisorctl status laic-backend-prod |
||||
|
sudo tail -f /usr/local/laic-backend-prod/log/info.log |
||||
|
sudo tail -f /usr/local/laic-backend-prod/log/err.log |
||||
|
``` |
||||
|
|
||||
|
部署目录和服务名可以在 `publish-prod.sh` 顶部调整。回滚时,脚本会使用远程 `backup/` 目录中最近的二进制备份;也可以手工恢复后执行: |
||||
|
|
||||
|
```bash |
||||
|
sudo supervisorctl restart laic-backend-prod |
||||
|
``` |
||||
|
|||||
@ -0,0 +1,48 @@ |
|||||
|
api-port: 9913 |
||||
|
sms-url: 192.168.1.195:21001 |
||||
|
mysql: |
||||
|
url: "root:jiagu^2058@tcp(192.168.0.111:3306)/laic?charset=utf8&parseTime=true&loc=Asia%2FShanghai" |
||||
|
idle: 10 |
||||
|
max-conn: 100 |
||||
|
max-wait: 30 |
||||
|
tdengine: |
||||
|
dsn: "root:taosdata@ws(172.16.0.216:6041)/laic_track" |
||||
|
redis: "redis://:Test123@192.168.1.13:6379/7" |
||||
|
mqtt: |
||||
|
broker: "tcp://192.168.0.6:1883" |
||||
|
client-id: laic-backend-prod |
||||
|
username: laic |
||||
|
password: "" |
||||
|
jwt: |
||||
|
secret: laic-backend-production-secret-change-me |
||||
|
access-expire-hours: 168 |
||||
|
refresh-expire-hours: 720 |
||||
|
oss: |
||||
|
endpoint: https://obs.cn-east-2.myhuaweicloud.com |
||||
|
access-key: 7TGDNNPBKVOPQ66JQNRU |
||||
|
secret-key: MMW9OSFChH7haJmTXoN4m8roCfIc22ffG5zrt2zT |
||||
|
bucket: gcs-edu |
||||
|
region: cn-east-2 |
||||
|
use-ssl: true |
||||
|
live: |
||||
|
mode: fake |
||||
|
provider: fake |
||||
|
push-domain: local-push |
||||
|
play-domain: local-play |
||||
|
app-name: dock-live |
||||
|
auth-expire-seconds: 7200 |
||||
|
play-url-ttl-seconds: 300 |
||||
|
protocol: srt |
||||
|
srt-port: 1105 |
||||
|
max-session-seconds: 7200 |
||||
|
viewer-lease-seconds: 30 |
||||
|
stop-grace-seconds: 15 |
||||
|
reconcile-interval-seconds: 10 |
||||
|
record-policy: disabled |
||||
|
allow-real-cloud: false |
||||
|
heartbeat: |
||||
|
timeout-seconds: 30 |
||||
|
scan-seconds: 5 |
||||
|
log: |
||||
|
level: info |
||||
|
path: ./logs/ |
||||
@ -0,0 +1,12 @@ |
|||||
|
[program:laic-backend-prod] |
||||
|
command=/usr/local/laic-backend-prod/laic-backend-prod.srv |
||||
|
directory=/usr/local/laic-backend-prod/ |
||||
|
autostart=true |
||||
|
autorestart=true |
||||
|
startsecs=3 |
||||
|
environment=LAIC_CONFIG_FILE="config.yaml" |
||||
|
stopasgroup=true |
||||
|
killasgroup=true |
||||
|
stderr_logfile=/usr/local/laic-backend-prod/log/err.log |
||||
|
stdout_logfile=/usr/local/laic-backend-prod/log/info.log |
||||
|
user=root |
||||
@ -0,0 +1,133 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
TARGET="laic-backend-prod.srv" |
||||
|
REMOTE="root@jg-serv1" |
||||
|
REMOTE_DIR="/usr/local/laic-backend-prod" |
||||
|
SERVICE_NAME="laic-backend-prod" |
||||
|
SUPERVISOR_CONF_DIR="/etc/supervisor/conf.d" |
||||
|
WAIT_TIME=3 |
||||
|
BACKUP_DIR="$REMOTE_DIR/backup" |
||||
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" |
||||
|
LOCAL_CONF="$SCRIPT_DIR/config/$SERVICE_NAME.conf" |
||||
|
LOCAL_CONFIG="$SCRIPT_DIR/config-prod.yaml" |
||||
|
LOCAL_ARTIFACT="$SCRIPT_DIR/$TARGET" |
||||
|
|
||||
|
cleanup() { |
||||
|
rm -f -- "$LOCAL_ARTIFACT" |
||||
|
} |
||||
|
trap cleanup EXIT |
||||
|
|
||||
|
remote_cmd() { |
||||
|
ssh "$REMOTE" "$@" </dev/null |
||||
|
} |
||||
|
|
||||
|
require_command() { |
||||
|
command -v "$1" >/dev/null 2>&1 || { |
||||
|
printf 'Missing required command: %s\n' "$1" >&2 |
||||
|
exit 1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
check_inputs() { |
||||
|
require_command go |
||||
|
require_command ssh |
||||
|
require_command scp |
||||
|
require_command diff |
||||
|
[[ -f "$LOCAL_CONF" ]] || { printf 'Missing Supervisor config: %s\n' "$LOCAL_CONF" >&2; exit 1; } |
||||
|
[[ -f "$LOCAL_CONFIG" ]] || { printf 'Missing production config: %s\n' "$LOCAL_CONFIG" >&2; exit 1; } |
||||
|
if [[ "$REMOTE" == *your-production-host* ]]; then |
||||
|
printf 'Set REMOTE in publish-prod.sh before deploying.\n' >&2 |
||||
|
exit 1 |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
build_local() { |
||||
|
printf 'Building Linux amd64 binary...\n' |
||||
|
(cd "$SCRIPT_DIR" && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o "$LOCAL_ARTIFACT" .) |
||||
|
} |
||||
|
|
||||
|
ensure_remote_dirs() { |
||||
|
remote_cmd "mkdir -p '$REMOTE_DIR' '$REMOTE_DIR/config' '$REMOTE_DIR/log' '$BACKUP_DIR'" |
||||
|
} |
||||
|
|
||||
|
check_remote_config() { |
||||
|
if ! remote_cmd "test -s '$REMOTE_DIR/config.yaml'"; then |
||||
|
printf 'Remote config.yaml is missing or empty: %s/config.yaml\n' "$REMOTE_DIR" >&2 |
||||
|
printf 'Upload config.yaml with OBS credentials before deploying.\n' >&2 |
||||
|
exit 1 |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
backup_old() { |
||||
|
remote_cmd " |
||||
|
if [ -f '$REMOTE_DIR/$TARGET' ]; then |
||||
|
timestamp=\$(date +'%Y%m%d%H%M%S') |
||||
|
cp '$REMOTE_DIR/$TARGET' '$BACKUP_DIR/$TARGET.'\$timestamp |
||||
|
echo 'Previous binary backed up.' |
||||
|
fi |
||||
|
if [ -f '$REMOTE_DIR/config.yaml' ]; then |
||||
|
timestamp=\$(date +'%Y%m%d%H%M%S') |
||||
|
cp '$REMOTE_DIR/config.yaml' '$BACKUP_DIR/config.yaml.'\$timestamp |
||||
|
fi |
||||
|
" |
||||
|
} |
||||
|
|
||||
|
upload_files() { |
||||
|
scp "$LOCAL_ARTIFACT" "$REMOTE:$REMOTE_DIR/$TARGET.new" |
||||
|
remote_cmd "mv -f '$REMOTE_DIR/$TARGET.new' '$REMOTE_DIR/$TARGET' && chmod 755 '$REMOTE_DIR/$TARGET'" |
||||
|
|
||||
|
scp "$LOCAL_CONFIG" "$REMOTE:$REMOTE_DIR/config.yaml.new" |
||||
|
remote_cmd "mv -f '$REMOTE_DIR/config.yaml.new' '$REMOTE_DIR/config.yaml' && chmod 640 '$REMOTE_DIR/config.yaml'" |
||||
|
} |
||||
|
|
||||
|
upload_supervisor_conf() { |
||||
|
local remote_conf="$SUPERVISOR_CONF_DIR/$SERVICE_NAME.conf" |
||||
|
if remote_cmd "test -f '$remote_conf'"; then |
||||
|
if diff -q "$LOCAL_CONF" <(ssh "$REMOTE" "cat '$remote_conf'") >/dev/null; then |
||||
|
printf 'Supervisor config unchanged.\n' |
||||
|
return |
||||
|
fi |
||||
|
fi |
||||
|
scp "$LOCAL_CONF" "$REMOTE:$remote_conf" |
||||
|
remote_cmd "supervisorctl reread && supervisorctl update" |
||||
|
} |
||||
|
|
||||
|
restart_service() { |
||||
|
local status |
||||
|
status="$(remote_cmd "supervisorctl status '$SERVICE_NAME' 2>/dev/null | awk '{print \$2}'" || true)" |
||||
|
if [[ "$status" == RUNNING ]]; then |
||||
|
remote_cmd "supervisorctl restart '$SERVICE_NAME'" |
||||
|
else |
||||
|
remote_cmd "supervisorctl start '$SERVICE_NAME'" |
||||
|
fi |
||||
|
sleep "$WAIT_TIME" |
||||
|
if remote_cmd "supervisorctl status '$SERVICE_NAME' | grep -q RUNNING"; then |
||||
|
printf 'Service is running.\n' |
||||
|
remote_cmd "tail -n 20 '$REMOTE_DIR/log/info.log'" || true |
||||
|
return |
||||
|
fi |
||||
|
printf 'Service failed to start; rolling back binary.\n' >&2 |
||||
|
rollback |
||||
|
exit 1 |
||||
|
} |
||||
|
|
||||
|
rollback() { |
||||
|
local latest_backup |
||||
|
latest_backup="$(remote_cmd "ls -t '$BACKUP_DIR/$TARGET.'* 2>/dev/null | head -n 1" || true)" |
||||
|
[[ -n "$latest_backup" ]] || { printf 'No binary backup available.\n' >&2; return 1; } |
||||
|
remote_cmd "cp '$latest_backup' '$REMOTE_DIR/$TARGET' && chmod 755 '$REMOTE_DIR/$TARGET' && supervisorctl restart '$SERVICE_NAME'" |
||||
|
} |
||||
|
|
||||
|
main() { |
||||
|
check_inputs |
||||
|
build_local |
||||
|
ensure_remote_dirs |
||||
|
backup_old |
||||
|
upload_files |
||||
|
upload_supervisor_conf |
||||
|
restart_service |
||||
|
printf 'Deployment complete.\n' |
||||
|
} |
||||
|
|
||||
|
main "$@" |
||||
@ -0,0 +1,86 @@ |
|||||
|
package service |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"errors" |
||||
|
"sync" |
||||
|
"time" |
||||
|
|
||||
|
"google.golang.org/grpc" |
||||
|
"google.golang.org/grpc/credentials/insecure" |
||||
|
|
||||
|
"laic-backend/service/smsrpc" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
smsRequestTimeout = time.Second |
||||
|
smsLoginTemplateID = "SMS_73670083" |
||||
|
smsRegisterTemplate = "SMS_73670081" |
||||
|
) |
||||
|
|
||||
|
type smsTemplate struct { |
||||
|
verifyType int32 |
||||
|
id string |
||||
|
} |
||||
|
|
||||
|
var smsTemplates = map[string]smsTemplate{ |
||||
|
"login": {verifyType: 1, id: smsLoginTemplateID}, |
||||
|
"register": {verifyType: 2, id: smsRegisterTemplate}, |
||||
|
"reset": {verifyType: 1, id: smsLoginTemplateID}, |
||||
|
} |
||||
|
|
||||
|
type smsRPCClient struct { |
||||
|
mu sync.Mutex |
||||
|
url string |
||||
|
conn *grpc.ClientConn |
||||
|
close func() error |
||||
|
} |
||||
|
|
||||
|
var defaultSMSRPCClient smsRPCClient |
||||
|
|
||||
|
func sendSMS(url, scene, phone, code string) error { |
||||
|
template, ok := smsTemplates[scene] |
||||
|
if !ok || url == "" { |
||||
|
return errors.New("短信服务配置错误") |
||||
|
} |
||||
|
|
||||
|
client, err := defaultSMSRPCClient.client(url) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
ctx, cancel := context.WithTimeout(context.Background(), smsRequestTimeout) |
||||
|
defer cancel() |
||||
|
|
||||
|
result, err := client.SendSms(ctx, &message.SmsRequest{ |
||||
|
VerifyCode: code, |
||||
|
VerifyType: template.verifyType, |
||||
|
SmsId: template.id, |
||||
|
Phone: phone, |
||||
|
}) |
||||
|
if err != nil || result == nil || !result.Value { |
||||
|
return errors.New("短信发送失败") |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (c *smsRPCClient) client(url string) (message.SmsClient, error) { |
||||
|
c.mu.Lock() |
||||
|
defer c.mu.Unlock() |
||||
|
|
||||
|
if c.conn != nil && c.url == url { |
||||
|
return message.NewSmsClient(c.conn), nil |
||||
|
} |
||||
|
if c.close != nil { |
||||
|
_ = c.close() |
||||
|
} |
||||
|
|
||||
|
conn, err := grpc.NewClient(url, grpc.WithTransportCredentials(insecure.NewCredentials())) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
c.url = url |
||||
|
c.conn = conn |
||||
|
c.close = conn.Close |
||||
|
return message.NewSmsClient(conn), nil |
||||
|
} |
||||
@ -0,0 +1,205 @@ |
|||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
|
// versions:
|
||||
|
// protoc-gen-go v1.28.1
|
||||
|
// protoc v4.25.3
|
||||
|
// source: sms.proto
|
||||
|
|
||||
|
package message |
||||
|
|
||||
|
import ( |
||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
|
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" |
||||
|
reflect "reflect" |
||||
|
sync "sync" |
||||
|
) |
||||
|
|
||||
|
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) |
||||
|
) |
||||
|
|
||||
|
type SmsRequest struct { |
||||
|
state protoimpl.MessageState |
||||
|
sizeCache protoimpl.SizeCache |
||||
|
unknownFields protoimpl.UnknownFields |
||||
|
|
||||
|
VerifyCode string `protobuf:"bytes,1,opt,name=verify_code,json=verifyCode,proto3" json:"verify_code,omitempty"` |
||||
|
VerifyType int32 `protobuf:"varint,2,opt,name=verify_type,json=verifyType,proto3" json:"verify_type,omitempty"` |
||||
|
SmsId string `protobuf:"bytes,3,opt,name=sms_id,json=smsId,proto3" json:"sms_id,omitempty"` |
||||
|
Phone string `protobuf:"bytes,4,opt,name=phone,proto3" json:"phone,omitempty"` |
||||
|
Sender string `protobuf:"bytes,5,opt,name=sender,proto3" json:"sender,omitempty"` |
||||
|
Email string `protobuf:"bytes,6,opt,name=email,proto3" json:"email,omitempty"` |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) Reset() { |
||||
|
*x = SmsRequest{} |
||||
|
if protoimpl.UnsafeEnabled { |
||||
|
mi := &file_sms_proto_msgTypes[0] |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) String() string { |
||||
|
return protoimpl.X.MessageStringOf(x) |
||||
|
} |
||||
|
|
||||
|
func (*SmsRequest) ProtoMessage() {} |
||||
|
|
||||
|
func (x *SmsRequest) ProtoReflect() protoreflect.Message { |
||||
|
mi := &file_sms_proto_msgTypes[0] |
||||
|
if protoimpl.UnsafeEnabled && x != nil { |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
if ms.LoadMessageInfo() == nil { |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
return ms |
||||
|
} |
||||
|
return mi.MessageOf(x) |
||||
|
} |
||||
|
|
||||
|
// Deprecated: Use SmsRequest.ProtoReflect.Descriptor instead.
|
||||
|
func (*SmsRequest) Descriptor() ([]byte, []int) { |
||||
|
return file_sms_proto_rawDescGZIP(), []int{0} |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetVerifyCode() string { |
||||
|
if x != nil { |
||||
|
return x.VerifyCode |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetVerifyType() int32 { |
||||
|
if x != nil { |
||||
|
return x.VerifyType |
||||
|
} |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetSmsId() string { |
||||
|
if x != nil { |
||||
|
return x.SmsId |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetPhone() string { |
||||
|
if x != nil { |
||||
|
return x.Phone |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetSender() string { |
||||
|
if x != nil { |
||||
|
return x.Sender |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *SmsRequest) GetEmail() string { |
||||
|
if x != nil { |
||||
|
return x.Email |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
var File_sms_proto protoreflect.FileDescriptor |
||||
|
|
||||
|
var file_sms_proto_rawDesc = []byte{ |
||||
|
0x0a, 0x09, 0x73, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, |
||||
|
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, |
||||
|
0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa9, 0x01, 0x0a, 0x0a, |
||||
|
0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x65, |
||||
|
0x72, 0x69, 0x66, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, |
||||
|
0x0a, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, |
||||
|
0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, |
||||
|
0x52, 0x0a, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x06, |
||||
|
0x73, 0x6d, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x6d, |
||||
|
0x73, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, |
||||
|
0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, |
||||
|
0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, |
||||
|
0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, |
||||
|
0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x32, 0x73, 0x0a, 0x03, 0x73, 0x6d, 0x73, 0x12, 0x34, |
||||
|
0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x6d, 0x73, 0x12, 0x0b, 0x2e, 0x53, 0x6d, 0x73, 0x52, |
||||
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, |
||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, |
||||
|
0x75, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, |
||||
|
0x6c, 0x12, 0x0b, 0x2e, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, |
||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, |
||||
|
0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, |
||||
|
0x2e, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, |
||||
|
0x33, |
||||
|
} |
||||
|
|
||||
|
var ( |
||||
|
file_sms_proto_rawDescOnce sync.Once |
||||
|
file_sms_proto_rawDescData = file_sms_proto_rawDesc |
||||
|
) |
||||
|
|
||||
|
func file_sms_proto_rawDescGZIP() []byte { |
||||
|
file_sms_proto_rawDescOnce.Do(func() { |
||||
|
file_sms_proto_rawDescData = protoimpl.X.CompressGZIP(file_sms_proto_rawDescData) |
||||
|
}) |
||||
|
return file_sms_proto_rawDescData |
||||
|
} |
||||
|
|
||||
|
var file_sms_proto_msgTypes = make([]protoimpl.MessageInfo, 1) |
||||
|
var file_sms_proto_goTypes = []interface{}{ |
||||
|
(*SmsRequest)(nil), // 0: SmsRequest
|
||||
|
(*wrapperspb.BoolValue)(nil), // 1: google.protobuf.BoolValue
|
||||
|
} |
||||
|
var file_sms_proto_depIdxs = []int32{ |
||||
|
0, // 0: sms.SendSms:input_type -> SmsRequest
|
||||
|
0, // 1: sms.SendEmail:input_type -> SmsRequest
|
||||
|
1, // 2: sms.SendSms:output_type -> google.protobuf.BoolValue
|
||||
|
1, // 3: sms.SendEmail:output_type -> google.protobuf.BoolValue
|
||||
|
2, // [2:4] is the sub-list for method output_type
|
||||
|
0, // [0:2] is the sub-list for method input_type
|
||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||
|
0, // [0:0] is the sub-list for field type_name
|
||||
|
} |
||||
|
|
||||
|
func init() { file_sms_proto_init() } |
||||
|
func file_sms_proto_init() { |
||||
|
if File_sms_proto != nil { |
||||
|
return |
||||
|
} |
||||
|
if !protoimpl.UnsafeEnabled { |
||||
|
file_sms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { |
||||
|
switch v := v.(*SmsRequest); i { |
||||
|
case 0: |
||||
|
return &v.state |
||||
|
case 1: |
||||
|
return &v.sizeCache |
||||
|
case 2: |
||||
|
return &v.unknownFields |
||||
|
default: |
||||
|
return nil |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
type x struct{} |
||||
|
out := protoimpl.TypeBuilder{ |
||||
|
File: protoimpl.DescBuilder{ |
||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), |
||||
|
RawDescriptor: file_sms_proto_rawDesc, |
||||
|
NumEnums: 0, |
||||
|
NumMessages: 1, |
||||
|
NumExtensions: 0, |
||||
|
NumServices: 1, |
||||
|
}, |
||||
|
GoTypes: file_sms_proto_goTypes, |
||||
|
DependencyIndexes: file_sms_proto_depIdxs, |
||||
|
MessageInfos: file_sms_proto_msgTypes, |
||||
|
}.Build() |
||||
|
File_sms_proto = out.File |
||||
|
file_sms_proto_rawDesc = nil |
||||
|
file_sms_proto_goTypes = nil |
||||
|
file_sms_proto_depIdxs = nil |
||||
|
} |
||||
@ -0,0 +1,147 @@ |
|||||
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
// versions:
|
||||
|
// - protoc-gen-go-grpc v1.3.0
|
||||
|
// - protoc v4.25.3
|
||||
|
// source: sms.proto
|
||||
|
|
||||
|
package message |
||||
|
|
||||
|
import ( |
||||
|
context "context" |
||||
|
grpc "google.golang.org/grpc" |
||||
|
codes "google.golang.org/grpc/codes" |
||||
|
status "google.golang.org/grpc/status" |
||||
|
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" |
||||
|
) |
||||
|
|
||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||
|
// is compatible with the grpc package it is being compiled against.
|
||||
|
// Requires gRPC-Go v1.32.0 or later.
|
||||
|
const _ = grpc.SupportPackageIsVersion7 |
||||
|
|
||||
|
const ( |
||||
|
Sms_SendSms_FullMethodName = "/sms/SendSms" |
||||
|
Sms_SendEmail_FullMethodName = "/sms/SendEmail" |
||||
|
) |
||||
|
|
||||
|
// SmsClient is the client API for Sms service.
|
||||
|
//
|
||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
|
type SmsClient interface { |
||||
|
SendSms(ctx context.Context, in *SmsRequest, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) |
||||
|
SendEmail(ctx context.Context, in *SmsRequest, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) |
||||
|
} |
||||
|
|
||||
|
type smsClient struct { |
||||
|
cc grpc.ClientConnInterface |
||||
|
} |
||||
|
|
||||
|
func NewSmsClient(cc grpc.ClientConnInterface) SmsClient { |
||||
|
return &smsClient{cc} |
||||
|
} |
||||
|
|
||||
|
func (c *smsClient) SendSms(ctx context.Context, in *SmsRequest, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { |
||||
|
out := new(wrapperspb.BoolValue) |
||||
|
err := c.cc.Invoke(ctx, Sms_SendSms_FullMethodName, in, out, opts...) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
return out, nil |
||||
|
} |
||||
|
|
||||
|
func (c *smsClient) SendEmail(ctx context.Context, in *SmsRequest, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { |
||||
|
out := new(wrapperspb.BoolValue) |
||||
|
err := c.cc.Invoke(ctx, Sms_SendEmail_FullMethodName, in, out, opts...) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
return out, nil |
||||
|
} |
||||
|
|
||||
|
// SmsServer is the server API for Sms service.
|
||||
|
// All implementations must embed UnimplementedSmsServer
|
||||
|
// for forward compatibility
|
||||
|
type SmsServer interface { |
||||
|
SendSms(context.Context, *SmsRequest) (*wrapperspb.BoolValue, error) |
||||
|
SendEmail(context.Context, *SmsRequest) (*wrapperspb.BoolValue, error) |
||||
|
mustEmbedUnimplementedSmsServer() |
||||
|
} |
||||
|
|
||||
|
// UnimplementedSmsServer must be embedded to have forward compatible implementations.
|
||||
|
type UnimplementedSmsServer struct { |
||||
|
} |
||||
|
|
||||
|
func (UnimplementedSmsServer) SendSms(context.Context, *SmsRequest) (*wrapperspb.BoolValue, error) { |
||||
|
return nil, status.Errorf(codes.Unimplemented, "method SendSms not implemented") |
||||
|
} |
||||
|
func (UnimplementedSmsServer) SendEmail(context.Context, *SmsRequest) (*wrapperspb.BoolValue, error) { |
||||
|
return nil, status.Errorf(codes.Unimplemented, "method SendEmail not implemented") |
||||
|
} |
||||
|
func (UnimplementedSmsServer) mustEmbedUnimplementedSmsServer() {} |
||||
|
|
||||
|
// UnsafeSmsServer may be embedded to opt out of forward compatibility for this service.
|
||||
|
// Use of this interface is not recommended, as added methods to SmsServer will
|
||||
|
// result in compilation errors.
|
||||
|
type UnsafeSmsServer interface { |
||||
|
mustEmbedUnimplementedSmsServer() |
||||
|
} |
||||
|
|
||||
|
func RegisterSmsServer(s grpc.ServiceRegistrar, srv SmsServer) { |
||||
|
s.RegisterService(&Sms_ServiceDesc, srv) |
||||
|
} |
||||
|
|
||||
|
func _Sms_SendSms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { |
||||
|
in := new(SmsRequest) |
||||
|
if err := dec(in); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
if interceptor == nil { |
||||
|
return srv.(SmsServer).SendSms(ctx, in) |
||||
|
} |
||||
|
info := &grpc.UnaryServerInfo{ |
||||
|
Server: srv, |
||||
|
FullMethod: Sms_SendSms_FullMethodName, |
||||
|
} |
||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) { |
||||
|
return srv.(SmsServer).SendSms(ctx, req.(*SmsRequest)) |
||||
|
} |
||||
|
return interceptor(ctx, in, info, handler) |
||||
|
} |
||||
|
|
||||
|
func _Sms_SendEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { |
||||
|
in := new(SmsRequest) |
||||
|
if err := dec(in); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
if interceptor == nil { |
||||
|
return srv.(SmsServer).SendEmail(ctx, in) |
||||
|
} |
||||
|
info := &grpc.UnaryServerInfo{ |
||||
|
Server: srv, |
||||
|
FullMethod: Sms_SendEmail_FullMethodName, |
||||
|
} |
||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) { |
||||
|
return srv.(SmsServer).SendEmail(ctx, req.(*SmsRequest)) |
||||
|
} |
||||
|
return interceptor(ctx, in, info, handler) |
||||
|
} |
||||
|
|
||||
|
// Sms_ServiceDesc is the grpc.ServiceDesc for Sms service.
|
||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||
|
// and not to be introspected or modified (even as a copy)
|
||||
|
var Sms_ServiceDesc = grpc.ServiceDesc{ |
||||
|
ServiceName: "sms", |
||||
|
HandlerType: (*SmsServer)(nil), |
||||
|
Methods: []grpc.MethodDesc{ |
||||
|
{ |
||||
|
MethodName: "SendSms", |
||||
|
Handler: _Sms_SendSms_Handler, |
||||
|
}, |
||||
|
{ |
||||
|
MethodName: "SendEmail", |
||||
|
Handler: _Sms_SendEmail_Handler, |
||||
|
}, |
||||
|
}, |
||||
|
Streams: []grpc.StreamDesc{}, |
||||
|
Metadata: "sms.proto", |
||||
|
} |
||||
Loading…
Reference in new issue