
go--------gin+mysql+redis+websocket搭建聊天
这里需要注意的就是redis启动后期可能需要记录数据到redis,记录到redis有个好处可以设置国企时间自动清除,不用链接mysql数据库。2.untils目录下负责链接redis,mysql,kafak等操作,地址untils/system_init.go。避坑主要在于测试webscoket的地方可能会跨域需要加入如下代码解决跨域问题。1.在根目录下新建config/config.yml如下。
·
一、.环境准备
首先安装gin框架,官网根据文档安装操作
2.安装mysql驱动
go get -u gorm.io/driver/mysql
3.安装redis依赖
go get -u github.com/go-redis/redis/v8
4安装websocket依赖
go get github.com/gorilla/websocket
二、链接MySQL和redis
1.在根目录下新建config/config.yml如下
mysql:
localhost: 127.0.0.1
port: 3306
username: root
password: admin123
database: ginchat
redis:
host: 127.0.0.1
port: 6379
password:
selectDb: 5
polSize: 30
minIdleConn: 30
2.untils目录下负责链接redis,mysql,kafak等操作,地址untils/system_init.go
/**
* Created by GoLand
* User: lingm
* Date: 2023/5/28
* Time: 下午 05:02
* Author: 现在的努力是为了小时候吹过的NB
* Atom: 小白从不写注释!!!
*/
package untils
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/spf13/viper"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"os"
"time"
"gorm.io/driver/mysql"
)
//声明全局数据库链接
var DB *gorm.DB
var Red *redis.Client
// 读取mysql连接的配置参数
func InitConfig() (host string, database string, port string, username string, password string) {
viper.SetConfigName("app")
viper.AddConfigPath("config")
err := viper.ReadInConfig()
if err != nil {
fmt.Printf("读取配置文件错误", err)
}
host = viper.GetString("mysql.localhost")
database = viper.GetString("mysql.database")
port = viper.GetString("mysql.port")
username = viper.GetString("mysql.username")
password = viper.GetString("mysql.password")
return host, database, port, username, password
}
// 初始化连接mysql
func InitMySQL() {
//自定义日志打印sql语句
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags),
logger.Config{
SlowThreshold: time.Second, //慢SQL阈值
LogLevel: logger.Info, //级别
Colorful: true, //彩色
},
)
host, database, port, username, password := InitConfig()
urlList := username + ":" + password + "@tcp(" + host + ":" + port + ")/" + database + "?charset=utf8mb4&parseTime=true&loc=Local"
DB, _ = gorm.Open(mysql.Open(urlList), &gorm.Config{Logger: newLogger})
fmt.Println(" MySQL inited 。。。。")
}
// 读取redis配置文件
func RedisConfig() (host string, selectDb int, port string, password string, polSize int, minIdleConn int) {
viper.SetConfigName("app")
viper.AddConfigPath("config")
err := viper.ReadInConfig()
if err != nil {
fmt.Printf("读取redis配置文件错误", err)
}
host = viper.GetString("redis.host")
selectDb = viper.GetInt("redis.selectDb")
port = viper.GetString("redis.port")
password = viper.GetString("redis.password")
polSize = viper.GetInt("redis.polSize")
minIdleConn = viper.GetInt("redis.minIdleConn")
return host, selectDb, port, password, polSize, minIdleConn
}
// 初始化连接redis
func InitRedis() {
host, selectDb, port, password, polSize, minIdleConn := RedisConfig()
localhost := host + ":" + port
fmt.Println("地址打印==:", localhost)
Red = redis.NewClient(&redis.Options{
Addr: localhost,
Password: password,
DB: selectDb,
PoolSize: polSize,
MinIdleConns: minIdleConn,
})
fmt.Println(" Redis inited 。。。。")
}
const (
PublishKey = "websocket"
)
// 发起Publish 发消息到redis
func Publish(c context.Context, channel string, msg string) error {
var err error
err = Red.Publish(c, channel, msg).Err()
return err
}
// Subscribe订阅redis消息
func Subscribe(c context.Context, channel string) (string, error) {
sub := Red.PSubscribe(c, channel)
fmt.Println("Subscribe。。。", sub)
msg, err := sub.ReceiveMessage(c)
return msg.Payload, err
}
3.main.go文件引用untils链接
package main
import (
"fmt"
"go-study/router"
"go-study/untils"
)
func main() {
//引用untils下的mysql和redis
untils.InitMySQL()
untils.InitRedis()
r := router.Router()
r.Run(":8081")
}
三、搭建websocket骨架
1.在控制器层新建如下
// 防止跨域站点为找请求
var upGrade = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
//消息发送
func SendMsg(c *gin.Context) {
ws, err := upGrade.Upgrade(c.Writer, c.Request, nil)
if err != nil {
fmt.Println("ws数据打印", err)
return
}
defer func(ws *websocket.Conn) {
err = ws.Close()
if err != nil {
fmt.Println("错误的ws日志打印")
}
}(ws)
MsgHandler(ws, c)
}
// 消息中间件
func MsgHandler(ws *websocket.Conn, c context.Context) {
msg, err := untils.Subscribe(c, untils.PublishKey)
if err != nil {
fmt.Println("错误打印", err)
}
tm := time.Now().Format("2006-01-02 15:04:05")
m := fmt.Sprintf("[ws][%s]:%s", tm, msg)
err = ws.WriteMessage(1, []byte(m))
if err != nil {
fmt.Println("消息异常打印", err)
}
}
3.将控制器层加入到路由
/**
* Created by GoLand
* User: lingm
* Date: 2023/5/28
* Time: 下午 04:24
* Author: 现在的努力是为了小时候吹过的NB
* Atom: 小白从不写注释!!!
*/
package router
func Router() *gin.Engine {
r := gin.Default()
docs.SwaggerInfo.BasePath = ""
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
r.GET("/user/sendMsg", controller.SendMsg)
return r
}
4.启动项目如下
5.调试websocket地址
这里推荐可以使用WebSocket在线测试工具如果网站失效大家可以自行百度一下
如下图
这里需要注意的就是redis启动后期可能需要记录数据到redis,记录到redis有个好处可以设置国企时间自动清除,不用链接mysql数据库。
避坑主要在于测试webscoket的地方可能会跨域需要加入如下代码解决跨域问题
// 防止跨域站点为找请求
var upGrade = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
fmt.Println("控制台打印数据")
return true
},
}
本期就到这里,谢谢大家支持
更多推荐
所有评论(0)