当前位置: 首页 > news >正文

动态ip做网站影响seo吗网络营销的方式有哪些

动态ip做网站影响seo吗,网络营销的方式有哪些,计算机学习网站,ssm网站开发实例分别实现了redigo中自动加前缀和session中自动加前缀 等有空了整理一个demo放到github上,到时候求个小星星 在gin-contrib/sessions/redis库中redis的前缀是被封装起来了,所以自定义前缀没有内部方法在这里我们自己实现一下NewStoreWithDBPrefix方法配…

分别实现了redigo中自动加前缀和session中自动加前缀

等有空了整理一个demo放到github上,到时候求个小星星

  1. 在gin-contrib/sessions/redis库中redis的前缀是被封装起来了,所以自定义前缀没有内部方法
  2. 在这里我们自己实现一下NewStoreWithDBPrefix方法
  3. 配置文件可以看到引用的redis配置
  4. 这样方面多个项目在同一个redis中方便管理
  5. 也方便做单点登录

项目目录

app/
├── common/
│   ├── global/
│   ├────  global.go
├── config/
│   ├── application.yaml
├── initialize/
│   ├── config.go
│   ├── initialize.go
│   ├── redis.go
│   ├── store.go
├── middleware/
│   ├── middleware.go
├── router/
│   ├── router.go
├── main.go

下面是代码实现

配置文件:config/application.yaml

redis: &redisConfigaddr: 127.0.0.1port: 6379password: 123456db: 3size: 20max-idle: 24active: 10auth: trueprefix: demotimeout: 180
store:size: 10redis: *redisConfigkey-pairs: sessionKey

全局变量:common/global/global.go

package globalimport ("demo/config""github.com/gin-contrib/sessions""github.com/robfig/cron/v3""github.com/garyburd/redigo/redis"ut "github.com/go-playground/universal-translator""github.com/jordan-wright/email""go.uber.org/zap""gorm.io/gorm"
)var (CONFIG    config.ConfigDB        *gorm.DBTrans     *ut.TranslatorREDISPoll *redis.PoolRootDir   stringEmailPool *email.PoolStore     *sessions.StoreLogger    *zap.SugaredLoggerCron      *cron.Cron
)

配置文件初始化:initialize/config.go

package initializeimport ("fmt""io/ioutil""log""os""path/filepath""strings""demo/common/global""demo/config""github.com/joho/godotenv""gopkg.in/yaml.v2"
)/*** 读取配置文件,最先被初始化*/func InitilizeConfig() {// 获取当前工作目录rootDir, err := os.Getwd()if err != nil {log.Fatalf("Failed to get current working directory: %s", err)}// 这是单元测试if strings.HasSuffix(rootDir, "service") || strings.HasSuffix(rootDir, "command") || strings.HasSuffix(rootDir, "util") || strings.HasSuffix(rootDir, "model") {rootDir = filepath.Dir(rootDir)}if strings.HasSuffix(rootDir, "oss") {rootDir = filepath.Dir(filepath.Dir(rootDir))}// rootDir = "/Users/dupeisheng.vendor/go/src/gitlab.bj.sensetime.com/entry_manage"// 设置工作目录if err := os.Chdir(rootDir); err != nil {log.Fatalf("Failed to change working directory: %s", err)}fmt.Println("工作目录:", rootDir)// 加载.envgodotenv.Load(".env")// 设置当前环境mode := os.Getenv("Mode")fmt.Println("当前环境:", mode)if mode != "" {mode = "-" + mode}// 加载配置文件configPath := rootDir + "/config/application" + mode + ".yaml"yamlFile, err := ioutil.ReadFile(configPath)if err != nil {log.Panicf("Failed to read file , cause is %s", err.Error())}config := config.Config{}err = yaml.Unmarshal(yamlFile, &config)global.CONFIG = configif err != nil {fmt.Println(err.Error())}
}

session初始化:initialize/store.go

package initializeimport ("fmt""demo/common/global""github.com/boj/redistore""github.com/gin-contrib/sessions""github.com/gin-contrib/sessions/redis""github.com/spf13/cast"
)const SessionMaxAge = 8 * 3600func InitilizeStore() {var Store sessions.StoreStore, err := NewStoreWithDBPrefix(global.CONFIG.Store.Size,"tcp",global.CONFIG.Store.Redis.Addr+":"+global.CONFIG.Store.Redis.Port,global.CONFIG.Store.Redis.Password,cast.ToString(global.CONFIG.Store.Redis.Db),// []byte(global.CONFIG.Store.Redis.Prefix),[]byte(global.CONFIG.Store.KeyPairs),)if err != nil {fmt.Println("创建Session-Redis存储失败" + err.Error())}Store.Options(sessions.Options{MaxAge: SessionMaxAge,})global.Store = &Store
}type store struct {*redistore.RediStore
}func NewStoreWithDBPrefix(size int, network, address, password, DB string, keyPairs ...[]byte) (redis.Store, error) {s, err := redistore.NewRediStoreWithDB(size, network, address, password, DB, keyPairs...)if err != nil {return nil, err}// 这里设置前缀s.SetKeyPrefix(global.CONFIG.Store.Redis.Prefix + ":session:")return &store{s}, nil
}func (c *store) Options(options sessions.Options) {c.RediStore.Options = options.ToGorillaOptions()
}

redis初始化:initialize/redis.go

package initializeimport ("fmt""log""strings""time""demo/common/global""demo/config""github.com/garyburd/redigo/redis""github.com/samber/lo""github.com/spf13/cast"
)/*** 初始化redis,并赋值给全局变量*/func InitilizeRedis() {// 创建redis连接池global.REDISPoll = GetRedisPool(global.CONFIG)
}func GetRedisPool(config config.Config) *redis.Pool {return &redis.Pool{MaxIdle:     config.Redis.MaxIdle, // 最大空闲连接数MaxActive:   config.Redis.Active,  // 最大连接数IdleTimeout: time.Duration(config.Redis.Timeout) * time.Second,Wait:        true, // 超过连接数后是否等待Dial: func() (redis.Conn, error) {redisUri := fmt.Sprintf("%s:%s", config.Redis.Addr, config.Redis.Port)var redisConn redis.Connvar err errorif config.Redis.Auth {redisConn, err = redis.Dial("tcp", redisUri, redis.DialPassword(config.Redis.Password))} else {redisConn, err = redis.Dial("tcp", redisUri)}if err != nil {log.Println("获取连接失败:" + err.Error())return nil, err}// 添加 Redis 前缀if config.Redis.Prefix != "" {redisConn = &PrefixedConn{Conn: redisConn, config: config.Redis}}return redisConn, nil},TestOnBorrow: func(c redis.Conn, t time.Time) error {if time.Since(t) < time.Minute {return nil}_, err := c.Do("PING")return err},}
}// PrefixedConn 是一个实现了 redis.Conn 接口的自定义结构体,它在键名前添加了前缀
type PrefixedConn struct {redis.Connconfig config.Redis
}// 允许适配前缀的命令
var commandsWithPrefix = []string{"GET", "SET", "EXISTS", "DEL", "TYPE","RPUSH", "LPOP", "RPOP", "LLEN", "LRANGE","SADD", "SREM", "SISMEMBER", "SMEMBERS", "SCARD","HSET", "HMSET", "HGET", "HGETALL","ZADD", "ZRANGE", "ZRANGEBYSCORE", "ZREVRANGEBYSCORE", "ZREM","INCR", "INCRBY","WATCH", "MULTI", "EXEC", "EXPIRE",
}// Do 实现了 redis.Conn 接口的 Do 方法
func (c *PrefixedConn) Do(command string, args ...any) (any, error) {// 执行命令前切换到数据库if _, err := c.Conn.Do("SELECT", c.config.Db); err != nil {return nil, err}command = strings.ToUpper(command)// 判断是不是单独实现了命令 不用反射吧-性能问题switch command {case "MGET":return c.MGET(args...)case "MSET":return c.MSET(args...)}// 加前缀if len(args) > 0 {key := args[0].(string)if lo.IndexOf[string](commandsWithPrefix, command) != -1 && key != "" {args[0] = c.config.Prefix + ":" + key}}return c.Conn.Do(command, args...)
}// MGET 实现了批量获取命令
func (c *PrefixedConn) MGET(args ...any) (interface{}, error) {for i := range args {args[i] = c.config.Prefix + ":" + cast.ToString(args[i])}return c.Conn.Do("MGET", args...)
}// MSET 实现了批量设置命令
func (c *PrefixedConn) MSET(args ...any) (interface{}, error) {for i := range args {if i%2 == 0 {args[i] = c.config.Prefix + ":" + cast.ToString(args[i])}}return c.Conn.Do("MSET", args...)
}

gin路由:router/router.go

package routerimport ("github.com/gin-contrib/cors""github.com/gin-contrib/sessions""github.com/gin-gonic/gin"
)
// InitRouters 初始化路由
func InitRouters() *gin.Engine {// 创建默认带中间件的路由 Logger、Recoveryr := gin.Default()// 允许跨域r.Use(cors.Default())r.Use(sessions.Sessions("sessionID", *global.Store))
}

下面是单点登录实现逻辑

middleware/middleware.go

package middlewareimport ("encoding/json""net/http"myerror "demo/common/error""demo/common/global""demo/model""demo/util""github.com/gin-contrib/sessions""github.com/gin-gonic/gin""github.com/gomodule/redigo/redis""github.com/spf13/cast"
)const UserSessionExpireDuration = 8 * 3600
const UserSessionMapPrefix = "session:user:"type SessionData struct {Member model.Member `json:"member"`
}// 保存登录信息
func GenerateSession(c *gin.Context, sessionData SessionData) error {c.Request.Header.Set("Cookie", "")redisConn := global.REDISPoll.Get()defer redisConn.Close()sessionKey := UserSessionMapPrefix + cast.ToString(sessionData.Member.ID)// 单点登录删除旧的登录态oldSessionID, err := redis.String(redisConn.Do("get", sessionKey))if err != nil && err != redis.ErrNil {return err}_, err = redisConn.Do("del", oldSessionID)if err != nil {return err}// 保存用户相关token := cast.ToString(sessionData.Member.ID) + sessionData.Member.Name + util.Md5(util.GetUUID()+util.RandString(20))session := sessions.Default(c)by, err := json.Marshal(sessionData)if err != nil {return err}session.Set("authenticated", true)session.Set("data", by)session.Set("member_id", sessionData.Member.ID)session.Set("member_name", sessionData.Member.Name)session.Set("token", token)session.Save()sessionVal := "session:" + session.ID()_, err = redisConn.Do("set", sessionKey, sessionVal, "EX", UserSessionExpireDuration)return err
}// 身份验证
func Authentication(ctx *gin.Context) {session := sessions.Default(ctx)if auth, ok := session.Get("authenticated").(bool); !ok || !auth {ctx.JSON(http.StatusUnauthorized, gin.H{"code": myerror.SERVER_UNAUTHORIZED_ERROR,"msg":  myerror.SERVER_UNAUTHORIZED_ERROR.String(),})ctx.Abort()return}session.Save()// 保存用户相关信息到ctxmemberId := session.Get("member_id")memberName := session.Get("member_name")data := session.Get("data")var sessionData SessionDataif data != nil {by := data.([]byte)err := json.Unmarshal(by, &sessionData)if err != nil {ctx.JSON(http.StatusUnauthorized, gin.H{"code": myerror.SERVER_SYSTEM_ERROR,"msg":  myerror.SERVER_SYSTEM_ERROR.String(),})ctx.Abort()return}}ctx.Set("member_id", memberId)ctx.Set("member_name", memberName)ctx.Set("member_info", sessionData.Member)ctx.Set("data", data)// 登录续时redisConn := global.REDISPoll.Get()defer redisConn.Close()sessionKey := UserSessionMapPrefix + cast.ToString(memberId)sessionVal := "session:" + session.ID()redisConn.Do("set", sessionKey, sessionVal, "EX", UserSessionExpireDuration)ctx.Next()
}

文章转载自:
http://trepan.rqjL.cn
http://blowout.rqjL.cn
http://spheric.rqjL.cn
http://nebulosity.rqjL.cn
http://asserted.rqjL.cn
http://cycladic.rqjL.cn
http://yugoslavic.rqjL.cn
http://amplitudinous.rqjL.cn
http://besiege.rqjL.cn
http://hebephrenia.rqjL.cn
http://vanilline.rqjL.cn
http://gigot.rqjL.cn
http://uselessly.rqjL.cn
http://microprogramming.rqjL.cn
http://opopanax.rqjL.cn
http://strapper.rqjL.cn
http://brachyurous.rqjL.cn
http://maracca.rqjL.cn
http://soundness.rqjL.cn
http://chuvash.rqjL.cn
http://totalitarianize.rqjL.cn
http://laptev.rqjL.cn
http://copyist.rqjL.cn
http://goosegog.rqjL.cn
http://zirconate.rqjL.cn
http://cosmea.rqjL.cn
http://choicely.rqjL.cn
http://flocculus.rqjL.cn
http://technologize.rqjL.cn
http://phronesis.rqjL.cn
http://punjabi.rqjL.cn
http://campanulaceous.rqjL.cn
http://unzipped.rqjL.cn
http://unrepealed.rqjL.cn
http://dehors.rqjL.cn
http://teenage.rqjL.cn
http://rateable.rqjL.cn
http://harmonize.rqjL.cn
http://leucocytosis.rqjL.cn
http://space.rqjL.cn
http://hyperlipidemia.rqjL.cn
http://superphosphate.rqjL.cn
http://grayly.rqjL.cn
http://countermand.rqjL.cn
http://silvicide.rqjL.cn
http://voyageur.rqjL.cn
http://thru.rqjL.cn
http://nudp.rqjL.cn
http://compages.rqjL.cn
http://atergo.rqjL.cn
http://idioplasm.rqjL.cn
http://raccoon.rqjL.cn
http://functionalist.rqjL.cn
http://larrikinism.rqjL.cn
http://isotron.rqjL.cn
http://harmfully.rqjL.cn
http://displode.rqjL.cn
http://numbly.rqjL.cn
http://systematizer.rqjL.cn
http://boswellize.rqjL.cn
http://phonetic.rqjL.cn
http://anthroposophy.rqjL.cn
http://dalailama.rqjL.cn
http://pantagraph.rqjL.cn
http://jazzophile.rqjL.cn
http://japanology.rqjL.cn
http://epidermal.rqjL.cn
http://ceterisparibus.rqjL.cn
http://theologise.rqjL.cn
http://annually.rqjL.cn
http://bushido.rqjL.cn
http://schitzy.rqjL.cn
http://digamous.rqjL.cn
http://labourwallah.rqjL.cn
http://loanshift.rqjL.cn
http://etruscan.rqjL.cn
http://transmissibility.rqjL.cn
http://pinteresque.rqjL.cn
http://karyogamy.rqjL.cn
http://newshen.rqjL.cn
http://algonquian.rqjL.cn
http://norseland.rqjL.cn
http://cysted.rqjL.cn
http://democratize.rqjL.cn
http://unreduced.rqjL.cn
http://cyclandelate.rqjL.cn
http://privatism.rqjL.cn
http://crypt.rqjL.cn
http://trochili.rqjL.cn
http://frogfish.rqjL.cn
http://panterer.rqjL.cn
http://bathythermograph.rqjL.cn
http://turves.rqjL.cn
http://ncna.rqjL.cn
http://sootiness.rqjL.cn
http://hydroairplane.rqjL.cn
http://instillation.rqjL.cn
http://praetorian.rqjL.cn
http://lizardite.rqjL.cn
http://tree.rqjL.cn
http://www.dt0577.cn/news/104075.html

相关文章:

  • 外贸网站建设是什么培训机构需要什么资质
  • 拍摄宣传片的流程简要兰州快速seo整站优化招商
  • c++后端开发需要学什么宁波seo的公司联系方式
  • 不需要iis的网站开发河北seo基础教程
  • 用python做网站不常见网站建设公司哪个好呀
  • 用vb做网站导航栏数据分析师资格证书怎么考
  • 网站做代理需要空间是多少钱成人技能培训
  • 做调查靠谱的网站有哪些全网关键词云怎么查
  • 添加书签网站代码百度指数数据分析平台入口
  • 网站建设管理指导意见秦皇岛百度推广
  • 微商手机网站制作公司哪家好百度收录提交申请
  • 三门峡做网站优化视频号直播推广二维码
  • 做期货财经网站需要哪些资质优化大师win7
  • 微信扫一扫登录网站如何做软文推广渠道主要有
  • android开发和网站开发百度推广的优势
  • 电商网站建设的重要性郑州模板建站代理
  • 重庆做网站那里好网络营销渠道有哪三类
  • 简述设计web站点的一般步骤站长资源平台
  • 网站制作.com语言googlechrome
  • 做买鞋网站的论文牛排seo系统
  • 古交市住房和城乡建设局网站卖链接的网站
  • 网站建设的目的友情链接购买
  • 安监网站安全建设信息抖音seo排名软件
  • 南宁建站免费模板网站运营主要做什么
  • 郑州专业手机网站制作百度知道官网入口
  • 网络推广外包哪家靠谱seo零基础教学
  • 网站开发项目案例seo发外链的网站
  • php网站后台管理系统星力游戏源码
  • 开发公司副总经理岗位职责seo推广外包
  • 怎么做体育直播网站谷歌seo推广