1、err:go net bind: address already in use
//服务端设置端口复用+客户端绑定固定端口号
import(
"syscall"
"context"
"golang.org/x/sys/unix" //仅限于Linux
)
cfg := net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEADDR, 1)
syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1)
})
},
}
tcp, err := cfg.Listen(context.Background(), "tcp", "127.0.0.1:1234")
2、websocket多客户端管理
通过map保存客户端信息,通过ws.RemoteAddr().String()作为key区分不同的websocket连接;再为每一个客户端连接建立一个消息通道;
import (
"sync"
"github.com/gorilla/websocket"
)
type Msg struct {
Data chan []byte
...
Times int64
}
var (
Mmessage = make(map[string]Msg)
Mclient = make(map[string]*websocket.Conn)
Mmux sync.Mutex
)
3、日志按时间(24h)分割zap+file-rotatelogs
import (
"io"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func getLogWriter() zapcore.WriteSyncer {
hook, err := rotatelogs.New(
"./logs/log"+"_%Y-%m-%d %H:%M:%S.log",
rotatelogs.WithLinkName("./logs/log"),
rotatelogs.WithMaxAge(time.Hour*24*30),
rotatelogs.WithRotationTime(time.Hour*24),
rotatelogs.WithRotationSize(int64(10*1024*1024)),
)
if err != nil {
panic(err)
}
return zapcore.AddSync(hook)
}
4、 将401重定向到首页
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
router.LoadHTMLGlob("www/index.html") //加载html模板文件
router.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusNotFound, "index.html", nil)
})
err := router.Run(":8080")
if err != nil {
log.Fatalln(err)
}
}
5、sqlite模式设置
import (
"log"
"os"
"time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func NewDB() (*gorm.DB) {
var err error
file, error := os.OpenFile("./logs/db.log", os.O_RDWR|os.O_CREATE, 0766)
if error != nil {
log.Println(error)
}
MyLog := logger.New(log.New(file, "\r\n", log.LstdFlags), logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Warn,
IgnoreRecordNotFoundError: true,
Colorful: false,
})
mydb, err := gorm.Open(sqlite.Open("mydb.db"), &gorm.Config{
Logger: MyLog,
NowFunc: func() time.Time {
return time.Now().Local()
},
})
if err != nil {
log.Println("db open err:" + err.Error())
} else {
// 启用 WAL 模式
mydb.Exec("PRAGMA journal_mode=WAL;")
}
sqlDB, dbError := mydb.DB()
if dbError != nil {
log.Println("failed to create sqlDB", dbError.Error())
}
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
log.Println("db open success")
return mydb
}