package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
package router
import (
"gin_grpc/app/controller"
"github.com/gin-gonic/gin"
)
// UserRouter 用户模块的路由
func UserRouter(r *gin.Engine) {
r.GET("/index", controller.User.Index)
}
// InitRouter 路由注册
func InitRouter(r *gin.Engine) {
// 用户相关的路由注册
UserRouter(r)
}
package controller
import (
"github.com/gin-gonic/gin"
)
// Controller controller基类
type Controller struct{}
// UserController 继承controller的user
type UserController struct {
Controller
}
// User UserController的变量
var User=UserController{
}
func (t *UserController)Index(c *gin.Context){
c.JSON(200, gin.H{
"message": "pong",
})
return
}
package main
import (
"gin_grpc/app/router"
"github.com/gin-gonic/gin"
)
func main() {
//r:=gin.New()//启动gin服务
r := gin.Default()//Default returns an Engine instance with the Logger and Recovery middleware already attached.
router.InitRouter(r)//注册路由
r.Run("127.0.0.1:8089") // listen and serve on 0.0.0.0:8080
}
我们读取mysql,读取redis配置,肯定少不了配置文件
这里,我们使用viper来读取配置文件
相关参考文档
安装vipergo get github.com/spf13/viper
在项目根目录下创建config文件夹,在config下创建base.yaml,因为yaml文件相对来说比json更轻量级
#项目相关配置
app:
name: gin_grpc
debug: true
#数据库相关配置
database:
driver: mysql
host: 127.0.0.1
port: 3306
username: acurd_com
dbname: cms
password: acurd_com
#redis相关配置
redis:
host: 127.0.0.1
port: 6379
package config
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
// InitConfig 初始化配置文件
func InitConfig() {
viper.AddConfigPath("./config")
viper.AddConfigPath(".")//多路径查找
viper.SetConfigName("base")
viper.SetConfigType("yaml")
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
//监控并重新读取配置文件
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
// 配置文件发生变更之后会调用的回调函数
fmt.Println("Config file changed:", e.Name)
})
}
package main
import (
"gin_grpc/app/router"
"gin_grpc/config"
"github.com/gin-gonic/gin"
)
//初始化配置文件
func init() {
config.InitConfig()
}
func main() {
//r:=gin.New()//启动gin服务
r := gin.Default()//Default returns an Engine instance with the Logger and Recovery middleware already attached.
router.InitRouter(r)//注册路由
r.Run("127.0.0.1:8089") // listen and serve on 0.0.0.0:8080
}
package model
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
"github.com/spf13/viper"
"log"
)
// Db 用来承接db变量
var Db *gorm.DB
// InitDb 初始化数据库连接
func InitDb()*gorm.DB{
var (
Username = viper.GetString("database.username")
Password = viper.GetString("database.password")
Host = viper.GetString("database.host")
Port = viper.GetInt("database.port")
DbName = viper.GetString("database.dbname")
)
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", Username, Password, Host, Port, DbName)
fmt.Println(Username)
db, err := gorm.Open("mysql", dsn)
if err != nil {
log.Fatal("数据库连接失败,报错信息"+err.Error())
}
// 设置连接池,空闲连接
db.DB().SetMaxIdleConns(50)
// 打开链接
db.DB().SetMaxOpenConns(100)
// 表明禁用后缀加s
db.SingularTable(true)
// 启用Logger,显示详细日志
db.LogMode(viper.GetBool("app.debug"))
return db
}
package model
// Blog 定义博文结构体
type Blog struct {
AutoID uint `gorm:"column:auto_id;primary_key;AUTO_INCREMENT"` // ID
ID string `gorm:"column:id;NOT NULL"` // 业务id
Title string `gorm:"column:title;NOT NULL"` // 标题
TitleStyle string `gorm:"column:title_style;NOT NULL"` // 标题样式
Thumb string `gorm:"column:thumb;NOT NULL"` // 缩略图
Keywords string `gorm:"column:keywords;NOT NULL"` // 关键词
Description string `gorm:"column:description;NOT NULL"` // 描述
Content string `gorm:"column:content;NOT NULL"` // 内容
CreateTime uint `gorm:"column:create_time;default:0;NOT NULL"` // 创建时间
UpdateTime uint `gorm:"column:update_time;default:0;NOT NULL"` // 更新时间
Author string `gorm:"column:author;NOT NULL"` // 作者
Source string `gorm:"column:source;NOT NULL"` // 来源
Summary string `gorm:"column:summary;NOT NULL"` // 摘要
}
// TableName 标记Blog结构体使用的表名
func (m *Blog) TableName() string {
return "cms_blog"
}
// BlogModel 用来继承model
type BlogModel struct{
}
// GetOne 获取一篇文章
func (m *BlogModel)GetOne(i int)Blog{
var blog Blog
Db.First(&blog,i)
return blog
}
// BlogRouter 博客相关路由
func BlogRouter(r *gin.Engine) {
r.GET("/blog/:id", controller.Blog.GetOne)
}
func main() {
//r:=gin.New()//启动gin服务
r := gin.Default()//Default returns an Engine instance with the Logger and Recovery middleware already attached.
model.Db=model.InitDb()
defer model.Db.Close()
router.InitRouter(r)//注册路由
r.Run("127.0.0.1:8089") // listen and serve on 0.0.0.0:8080
}
grpc的入门的例子,我再之前的文章golang入门微服务
中详细的讲过,这里简单记录一下步骤
//我们定义一个博文的数据结构,
syntax="proto3";
package blog;
option go_package="/Users/zhangguofu/website/gin_grpc/app/proto/gen/go;blog";//生成的go文件存放目录在哪;包名叫什么
message Blog {
uint32 auto_id = 1; // ID
string id = 2; // 业务id
string title = 4; // 标题
string title_style = 5; // 标题样式
string thumb = 6; // 缩略图
string keywords = 7; // 关键词
string description = 8; // 描述
string content = 9; // 内容
uint32 create_time = 14; // 创建时间
uint32 update_time = 15; // 更新时间
string author = 16; // 作者
string source = 17; // 来源
string summary = 18; // 摘要
}
// 定义blog服务
service BlogInfo{
//定义方法
rpc getBlog(Id) returns(Blog);
}
//定义id的消息类型
message Id{
int64 value=1;
}
│ ├── proto
│ │ ├── blog.proto
│ │ └── gen
│ │ └── go
│ │ └── blog
│ │ ├── blog.pb.go
│ │ └── blog_grpc.pb.go
func (t *BlogController) RpcGetOne(c *gin.Context) {
id := c.Param("id")
id_int, _ := strconv.Atoi(id)
//监听端口
conn, err := grpc.Dial("localhost:9988", grpc.WithInsecure())
if err!=nil {
log.Fatal(err)
}
defer conn.Close()
//取到客户端连接
client:=blog2.NewBlogInfoClient(conn)
//组装结构体
blogId:=new(blog2.Id)
blogId.Value=int64(id_int)
info, _ :=client.GetBlog(context.Background(),blogId)
fmt.Println(id)
c.JSON(200, gin.H{
"message": "success",
"data": info,
})
return
}
package main
import (
"context"
"fmt"
"github.com/blog-server/proto/gen/go/blog"
"google.golang.org/grpc"
"log"
"net"
"strconv"
)
type Server struct{
}
/**
* @Description
* @Author 老a技术联盟
* @Date 2023/2/6 11:48
**/
func main() {
listen, err := net.Listen("tcp", "localhost:9988")
if err != nil {
return
}
//创建grpc服务
s:=grpc.NewServer()
blog.RegisterBlogInfoServer(s,Server{})
if err := s.Serve(listen); err != nil {
log.Println("failed to serve...", err)
return
}
}
//继承接口
func (s Server)GetBlog(c context.Context,b *blog.Id) (*blog.Blog, error) {
//从mysql中取数据的过程忽略,直接返回结果
blog:=new(blog.Blog)
blog.Id= strconv.Itoa(int(b.Value))
fmt.Printf("接收到的id是:%d",b.Value)
blog.Author="grpc返回"
return blog,nil
}