19 changed files with 809 additions and 30 deletions
@ -1,3 +1,71 @@ |
|||
# 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