首页 > 其他分享 >Go语言开发Web网站实现流媒体,Web视频网站的关键技能

Go语言开发Web网站实现流媒体,Web视频网站的关键技能

时间:2023-11-09 11:34:29浏览次数:33  
标签:Web http err 视频 网站 gin Go return id

Go语言开发Web网站实现流媒体,Web视频网站的关键技能

一,流媒体直播框架分析

Golang 是一门高并发、高性能的编程语言,非常适合用于流媒体直播等实时场景。下面是几个比较常用的 Golang 流媒体直播框架:

  1. go-rtmp:一个基于 Go 的 RTMP 服务器和客户端库,支持 RTMP 直播推流和拉流。
  2. Ant Media Server:一个开源的流媒体服务器,使用 Java 开发,但提供了 Golang 版本的 SDK,可以方便地与 Go 应用集成。
  3. flv.js:一个基于浏览器 HTML5 实现的 FLV 播放器库,支持 HTTP-FLV 和 WebSocket-FLV 协议,并提供了 Golang 版本的服务端代码。
  4. Pion WebRTC:一个 WebRTC 客户端/服务端库,使用 Golang 开发。可以实现点对点音视频通信、多人会议等功能。

这些框架都有其特点和优缺点,在选择时需要根据具体需求进行评估。同时也要注意不同框架之间的兼容性问题。

二,前后端分离设计

Golang 作为一门高并发、高性能的编程语言,非常适合用于前后端分离的设计。下面是一个简单的 Golang 前后端分离设计方案:

  1. 前端采用 Vue.js 等流行的前端框架进行开发,通过 AJAX 或 WebSocket 技术与后端通信。
  2. 后端采用 Golang 进行开发,提供 RESTful API 或 WebSocket 接口等服务。可以使用 Gin、Echo 等 Web 框架来快速搭建 HTTP 服务器。
  3. 数据库采用 MySQL、MongoDB 等数据库管理系统进行存储和管理数据。可以使用 GORM、mgo 等 ORM 工具来简化数据库操作。
  4. 缓存采用 Redis、Memcached 等内存数据库进行缓存数据。可以使用 go-redis、gomemcache 等客户端库来访问缓存服务器。
  5. 消息队列采用 RabbitMQ、Kafka 等消息队列服务进行消息传输和处理。可以使用 amqp、sarama 等客户端库来访问消息队列服务。
  6. 部署可以选择 Docker 容器化部署方式,结合 Kubernetes 调度器实现自动化部署和扩容,以提升应用的可靠性和可伸缩性。

以上仅是一个简单的设计方案,具体实现还需要根据实际需求进行调整和优化。同时,也需要注意前后端的安全性问题,例如 XSS、CSRF 等攻击

三,RESET API设计,包括用户、视频、评论处理

下面是一个简单的 Golang REST API 设计方案,包括用户、视频、评论处理:

  1. 用户处理
  • 获取用户列表:GET /users
  • 获取指定用户信息:GET /users/{id}
  • 创建新用户:POST /users
  • 更新指定用户信息:PUT /users/{id}
  • 删除指定用户:DELETE /users/{id}
  1. 视频处理
  • 获取视频列表:GET /videos
  • 获取指定视频信息:GET /videos/{id}
  • 创建新视频:POST /videos
  • 更新指定视频信息:PUT /videos/{id}
  • 删除指定视频:DELETE /videos/{id}
  1. 评论处理
  • 获取评论列表:GET /comments
  • 获取指定评论信息:GET /comments/{id}
  • 创建新评论:POST /comments
  • 更新指定评论信息:PUT /comments/{id}
  • 删除指定评论:DELETE /comments/{id}

在上述 API 设计中,{id} 表示对应实体的唯一标识符。HTTP 方法表示对该实体执行的操作。例如,使用 GET 方法获取视频列表时,服务器会返回包含所有视频的 JSON 数组。

另外,在这个设计中需要考虑到请求和响应的数据格式。可以使用 JSON 格式来传输数据,并使用 Golang 的编码/解码库进行序列化和反序列化操作。此外还要注意身份验证、访问控制等安全性问题。

四,用户、评论、会话、待删除视频数据库设计

以下是一个简单的 Golang 数据库设计方案,包括用户、评论、会话和待删除视频:

  1. 用户表(User)
字段类型描述
id int 主键,自增
username string 用户名
password string 密码
email string 邮箱
  1. 评论表(Comment)
字段类型描述
id int 主键,自增
user_id int 外键,对应 User 表 id 字段
video_id int 视频 id
content string 评论内容
  1. 会话表(Session)
字段类型描述
id int 主键,自增  
user_id int外键,对应 User 表 id 字段  
token string 会话 token
  1. 待删除视频表(DeletedVideo)
字段类型描述
id int主键,自增  
user_id int外键,对应 User 表 id 字段  
video_id int待删除视频的 id  

在上述数据库设计中,User 表存储用户信息;Comment 表存储评论信息,并通过 user_id 和 video_id 与 User 和 Video 表进行关联;Session 表用于存储用户登录状态;DeletedVideo 表用于存储待删除的视频。

注意,在实际开发过程中还需要考虑数据模型优化、索引设计等问题,并根据具体业务需求进行调整。

五,meddleware handler机制

在 Golang 中,Middleware 和 Handler 是两个概念。

Handler 用于处理请求,可以看作是业务逻辑的实现。在 http 包中,Handler 接口如下:

  1.   type Handler interface {
  2.   ServeHTTP(ResponseWriter, *Request)
  3.   }

Middleware 则是对请求进行一些预处理或者后置处理的过程。它本身也实现了 Handler 接口,因此 Middleware 可以通过组合多个 Middleware 来形成一个完整的请求处理链。常见的 Middleware 操作包括记录日志、验证权限、解析 body 等。

下面我们来看一个例子,说明如何使用 Middleware 和 Handler 组成一个完整的 HTTP 处理流程:

  1.   package main
  2.    
  3.   import (
  4.   "fmt"
  5.   "net/http"
  6.   )
  7.    
  8.   // Middleware1 记录日志
  9.   func Middleware1(next http.Handler) http.Handler {
  10.   return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  11.   fmt.Println("log request:", r.URL.Path)
  12.   next.ServeHTTP(w, r)
  13.   })
  14.   }
  15.    
  16.   // Middleware2 验证权限
  17.   func Middleware2(next http.Handler) http.Handler {
  18.   return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  19.   // TODO: 验证用户权限
  20.   next.ServeHTTP(w, r)
  21.   })
  22.   }
  23.    
  24.   // HelloHandler 处理请求
  25.   func HelloHandler(w http.ResponseWriter, r *http.Request) {
  26.   fmt.Fprintln(w, "Hello World!")
  27.   }
  28.    
  29.   func main() {
  30.   // 创建路由器并注册路由规则和对应的 Handler 函数
  31.   router := http.NewServeMux()
  32.   router.HandleFunc("/", HelloHandler)
  33.    
  34.   // 使用中间件包装 Handler
  35.   handler := Middleware2(Middleware1(router))
  36.    
  37.   // 启动 HTTP 服务并监听端口
  38.   http.ListenAndServe(":8080", handler)
  39.   }

在上面的例子中,我们使用了两个 Middleware(Middleware1 和 Middleware2),它们分别用于记录日志和验证用户权限。然后将路由器包装成一个完整的 Handler(handler 变量),最后通过 ListenAndServe 方法启动 HTTP 服务。

当客户端向服务器发送请求时,请求会先经过 Middleware1 处理,然后再经过 Middleware2 处理,最终交给 HelloHandler 函数处理,并将结果返回给客户端。这样就形成了一个完整的请求处理链。

Golang云原生学习路线图、教学视频、文档资料、面试题资料(资料包括C/C++、K8s、golang项目实战、gRPC、Docker、DevOps等)免费分享 有需要的可以加qun:793221798领取

 

六,登录注册

在 Golang 中开发流媒体网站的登录注册功能,可以使用第三方库如 gin、gorm 等。

  1. 创建用户表

首先需要创建一个用户表,用于存储用户信息。可以定义一个 User 结构体,并通过 gorm 来创建对应的数据表:

  1.   type User struct {
  2.   ID uint `gorm:"primary_key"`
  3.   Username string `gorm:"unique;not null"`
  4.   Password string `gorm:"not null"`
  5.   }
  1. 注册路由

然后需要注册登录和注册相关的路由规则,以便客户端能够访问相应的接口。例如,可以使用 gin 框架来实现以下路由:

  1.   router := gin.Default()
  2.    
  3.   // 注册
  4.   router.POST("/register", handleRegister)
  5.    
  6.   // 登录
  7.   router.POST("/login", handleLogin)
  1. 实现业务逻辑

接下来需要实现具体的业务逻辑。对于注册功能,可以从请求参数中获取用户名和密码,并将其加密后保存到数据库中:

  1.   func handleRegister(c *gin.Context) {
  2.   // 从请求参数中获取用户名和密码
  3.   username := c.PostForm("username")
  4.   password := c.PostForm("password")
  5.    
  6.   // 将密码加密后保存到数据库中
  7.   hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
  8.   if err != nil {
  9.   c.AbortWithStatus(http.StatusInternalServerError)
  10.   return
  11.   }
  12.    
  13.   user := &User{
  14.   Username: username,
  15.   Password: string(hashedPassword),
  16.   }
  17.    
  18.   db.Create(user)
  19.    
  20.   c.JSON(http.StatusOK, gin.H{"message": "Register success!"})
  21.   }

对于登录功能,可以从请求参数中获取用户名和密码,并通过 gorm 查询数据库中是否存在该用户。如果存在则比对密码是否正确:

  1.   func handleLogin(c *gin.Context) {
  2.   // 从请求参数中获取用户名和密码
  3.   username := c.PostForm("username")
  4.   password := c.PostForm("password")
  5.    
  6.   // 查询数据库中是否存在该用户
  7.   var user User
  8.   if err := db.Where(&User{Username: username}).First(&user).Error; err != nil {
  9.   c.AbortWithStatus(http.StatusUnauthorized)
  10.   return
  11.   }
  12.    
  13.   // 比对密码是否正确
  14.   if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
  15.   c.AbortWithStatus(http.StatusUnauthorized)
  16.   return
  17.   }
  18.    
  19.   // 登录成功,返回 token 等信息给客户端
  20.   token, _ := createToken(user.ID)
  21.    
  22.   c.JSON(http.StatusOK, gin.H{
  23.   "message": "Login success!",
  24.   "token": token,
  25.   "user_id": user.ID,
  26.   })
  27.   }

在这个例子中,使用了 bcrypt 包来加密和比对密码。同时还需要实现一个生成 Token 的函数(createToken),用于登录成功后将用户标识存储到客户端。

  1. 实现 Token 鉴权

最后还需要实现 Token 鉴权机制,以确保只有已登录的用户才能访问流媒体网站的资源。可以使用 gin 提供的 JWT 中间件来实现 Token 鉴权:

  1.   // 使用 JWT 中间件进行鉴权
  2.   router.Use(authMiddleware())
  3.    
  4.   // JWT 鉴权中间件
  5.   func authMiddleware() gin.HandlerFunc {
  6.   return func(c *gin.Context) {
  7.   tokenString := c.GetHeader("Authorization")
  8.   if tokenString == "" {
  9.   c.AbortWithStatus(http.StatusUnauthorized)
  10.   return
  11.   }
  12.    
  13.   // 解析 Token 并获取用户 ID
  14.   claims, err := parseToken(tokenString)
  15.   if err != nil {
  16.   c.AbortWithStatus(http.StatusUnauthorized)
  17.   return
  18.   }
  19.    
  20.   userID := claims["user_id"].(float64)
  21.    
  22.   // 将用户 ID 存储到 Context 中,以便在后续处理函数中使用
  23.   c.Set("user_id", uint(userID))
  24.    
  25.   c.Next()
  26.   }
  27.   }
  28.    
  29.   // 生成 Token 的函数
  30.   func createToken(userID uint) (string, error) {
  31.   claims := jwt.MapClaims{
  32.   "user_id": userID,
  33.   }
  34.    
  35.   token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  36.    
  37.   return token.SignedString([]byte("secret"))
  38.   }
  39.    
  40.   // 解析 Token 的函数
  41.   func parseToken(tokenString string) (jwt.MapClaims, error) {
  42.   token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  43.   if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  44.   return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
  45.   }
  46.    
  47.   return []byte("secret"), nil
  48.   })
  49.    
  50.   if err != nil {
  51.   return nil, err
  52.   }
  53.    
  54.   claims, ok := token.Claims.(jwt.MapClaims)
  55.   if !ok || !token.Valid {
  56.   return nil, fmt.Errorf("invalid token")
  57.   }
  58.    
  59.   return claims, nil
  60.   }

在这个例子中,使用了 JWT 中间件来进行 Token 鉴权。在注册和登录成功后,会返回一个 Token 给客户端,客户端每次请求时需要将该 Token 放在请求头中(Authorization 字段),服务器则通过解析该 Token 来获取用户标识。

以上是一个简单的 Golang 流媒体网站开发登录注册的示例。实际开发中可能还需要加入更多的安全措施和优化处理逻辑。

七,视频上传

在 Golang 中开发流媒体网站的视频上传功能,可以使用第三方库如 gin、ffmpeg 等。

  1. 注册路由

首先需要注册视频上传相关的路由规则,以便客户端能够访问相应的接口。例如,可以使用 gin 框架来实现以下路由:

  1.   router := gin.Default()
  2.    
  3.   // 上传视频
  4.   router.POST("/upload", handleUpload)
  1. 实现业务逻辑

接下来需要实现具体的业务逻辑。对于视频上传功能,可以从请求参数中获取文件名和文件内容,并将其保存到本地磁盘上:

  1.   func handleUpload(c *gin.Context) {
  2.   // 从请求参数中获取文件名和文件内容
  3.   file, err := c.FormFile("file")
  4.   if err != nil {
  5.   c.AbortWithStatus(http.StatusBadRequest)
  6.   return
  7.   }
  8.    
  9.   // 将文件保存到本地磁盘上
  10.   filename := filepath.Base(file.Filename)
  11.   if err := c.SaveUploadedFile(file, "./videos/"+filename); err != nil {
  12.   c.AbortWithStatus(http.StatusInternalServerError)
  13.   return
  14.   }
  15.    
  16.   c.JSON(http.StatusOK, gin.H{"message": "Upload success!"})
  17.   }
  1. 转码处理

如果要支持更多格式或者更高清晰度的视频,还需要进行转码处理。可以使用 ffmpeg 来实现视频转码,并将转码后的视频保存到指定目录下。例如,以下代码演示了将 MP4 格式的视频转换为 HLS 格式:

  1.   func handleUpload(c *gin.Context) {
  2.   // 从请求参数中获取文件名和文件内容
  3.   file, err := c.FormFile("file")
  4.   if err != nil {
  5.   c.AbortWithStatus(http.StatusBadRequest)
  6.   return
  7.   }
  8.    
  9.   // 将文件保存到本地磁盘上
  10.   filename := filepath.Base(file.Filename)
  11.   if err := c.SaveUploadedFile(file, "./videos/"+filename); err != nil {
  12.   c.AbortWithStatus(http.StatusInternalServerError)
  13.   return
  14.   }
  15.    
  16.   // 转码为 HLS 格式
  17.   if err := transcodeToHLS("./videos/" + filename); err != nil {
  18.   c.AbortWithStatus(http.StatusInternalServerError)
  19.   return
  20.   }
  21.    
  22.   c.JSON(http.StatusOK, gin.H{"message": "Upload success!"})
  23.   }
  24.    
  25.   // 使用 ffmpeg 将视频转码为 HLS 格式
  26.   func transcodeToHLS(filepath string) error {
  27.   cmd := exec.Command("ffmpeg", "-i", filepath, "-c:v", "libx264", "-preset", "fast", "-profile:v", "baseline",
  28.   "-level", "3.0", "-s", "640x360", "-start_number", "0",
  29.   "-hls_time", "10", "-hls_list_size", "0",
  30.   "-f", "hls",
  31.   filepath+".m3u8")
  32.    
  33.   return cmd.Run()
  34.   }

在这个例子中,使用了 ffmpeg 来进行视频转码。通过调用 transcodeToHLS 函数,将 MP4 格式的视频转换为具有多码率支持的 HLS 格式。

以上是一个简单的 Golang 流媒体网站开发视频上传的示例。实际开发中可能还需要加入更多的安全措施和优化处理逻辑。

八,视频评论

在 Golang 中开发流媒体网站的视频评论功能,可以使用第三方库如 gin、gorm 等。

  1. 创建数据库

首先需要创建用于存储视频评论信息的数据库。可以使用 gorm 来实现数据库访问操作,例如:

  1.   type Comment struct {
  2.   gorm.Model
  3.   VideoID uint `json:"video_id"`
  4.   Username string `json:"username"`
  5.   Content string `json:"content"`
  6.   }
  7.    
  8.   func initDB() {
  9.   db, err := gorm.Open("sqlite3", "comments.db")
  10.   if err != nil {
  11.   panic("Failed to connect database!")
  12.   }
  13.    
  14.   // 自动迁移表结构
  15.   db.AutoMigrate(&Comment{})
  16.   }

以上代码演示了如何使用 sqlite3 数据库,并定义了一个 Comment 模型来表示视频评论信息。

  1. 注册路由

接下来需要注册视频评论相关的路由规则,以便客户端能够访问相应的接口。例如,可以使用 gin 框架来实现以下路由:

  1.   router := gin.Default()
  2.    
  3.   // 获取所有评论
  4.   router.GET("/comments", handleGetComments)
  5.    
  6.   // 添加新评论
  7.   router.POST("/comments", handleAddComment)
  1. 实现业务逻辑

对于获取所有评论和添加新评论两个功能,可以分别实现对应的业务逻辑。例如:

  1.   // 获取所有评论
  2.   func handleGetComments(c *gin.Context) {
  3.   var comments []Comment
  4.    
  5.   // 查询所有评论并返回给客户端
  6.   db.Find(&comments)
  7.   c.JSON(http.StatusOK, comments)
  8.   }
  9.    
  10.   // 添加新评论
  11.   func handleAddComment(c *gin.Context) {
  12.   var comment Comment
  13.    
  14.   // 从请求参数中获取评论信息并保存到数据库中
  15.   if err := c.ShouldBindJSON(&comment); err != nil {
  16.   c.AbortWithStatus(http.StatusBadRequest)
  17.   return
  18.   }
  19.   db.Create(&comment)
  20.    
  21.   c.JSON(http.StatusOK, gin.H{"message": "Comment added!"})
  22.   }

以上代码演示了如何使用 gorm 来进行数据库操作,并实现了获取所有评论和添加新评论两个功能。

  1. 客户端调用

最后,客户端可以通过发送 HTTP 请求来访问相应的接口,以实现视频评论功能。例如,以下代码演示了如何使用 axios 库来向服务器发送添加新评论的请求:

  1.   const addComment = (videoId, username, content) => {
  2.   const data = { video_id: videoId, username: username, content: content };
  3.   return axios.post("/comments", data);
  4.   };

以上是一个简单的 Golang 流媒体网站开发视频评论的示例。实际开发中可能还需要加入更多的安全措施和优化处理逻辑。

九,流控算法

在 Golang 中开发流媒体网站时,可以使用 Token Bucket 算法来实现流控。Token Bucket 算法是一种基于令牌的算法,用于限制请求的速率。

  1. 实现 TokenBucket 结构体

首先需要定义一个 TokenBucket 结构体,用于存储令牌桶相关信息,例如:

  1.   type TokenBucket struct {
  2.   capacity float64 // 桶容量
  3.   rate float64 // 令牌放入速率
  4.   tokens float64 // 当前剩余令牌数
  5.   lastCheck time.Time // 上次检查时间
  6.   }
  1. 初始化 TokenBucket

接下来需要初始化 TokenBucket 结构体,并设置容量和放入速率等参数。例如:

  1.   func NewTokenBucket(capacity, rate float64) *TokenBucket {
  2.   return &TokenBucket{
  3.   capacity: capacity,
  4.   rate: rate,
  5.   tokens: capacity,
  6.   lastCheck: time.Now(),
  7.   }
  8.   }

以上代码演示了如何创建一个新的 TokenBucket 对象,并设置桶容量和放入速率等参数。

  1. 实现 Take 方法

对于每个请求,在执行之前需要调用 Take 方法从令牌桶中获取一个或多个令牌。如果当前剩余的令牌数不足,则需等待一段时间直到有足够的令牌可用。例如:

  1.   func (tb *TokenBucket) Take(count float64) {
  2.   now := time.Now()
  3.   elapsed := now.Sub(tb.lastCheck).Seconds()
  4.   tb.tokens += elapsed * tb.rate
  5.   if tb.tokens > tb.capacity {
  6.   tb.tokens = tb.capacity
  7.   }
  8.   tb.lastCheck = now
  9.    
  10.   if count > tb.tokens {
  11.   wait := (count - tb.tokens) / tb.rate
  12.   time.Sleep(time.Duration(wait * float64(time.Second)))
  13.   tb.tokens = 0
  14.   } else {
  15.   tb.tokens -= count
  16.   }
  17.   }

以上代码演示了如何从 TokenBucket 中获取令牌。如果当前剩余的令牌数不足,则需等待一段时间直到有足够的令牌可用。

  1. 应用流控算法

最后,在每次处理请求时,需要调用 Take 方法来进行流控。例如:

  1.   func handleRequest(w http.ResponseWriter, r *http.Request) {
  2.   // 每秒钟放入 10 个令牌,容量为 20 个令牌的 TokenBucket 对象
  3.   bucket := NewTokenBucket(20, 10)
  4.    
  5.   // 获取一个令牌并处理请求
  6.   bucket.Take(1)
  7.    
  8.   // 处理具体业务逻辑...
  9.   }

以上代码演示了如何在 Golang 流媒体网站中应用 Token Bucket 算法进行流控。

需要注意的是,Token Bucket 算法只能限制请求的速率,而不能防止恶意攻击或大量并发访问等情况。因此,在实际开发中还需要加入其他安全措施和优化处理逻辑。

   

标签:Web,http,err,视频,网站,gin,Go,return,id
From: https://www.cnblogs.com/add1188/p/17819313.html

相关文章

  • Go语言实战开发一个WEB项目博客系统
    Go语言实战开发一个WEB项目博客系统beego个人博客系统功能介绍首页分页展示博客博客详情评论文章专栏分类导航资源分享时光轴点点滴滴关于本站后台管理登录系统设置分类添加修改删除管理博文添加修改删除管理基于Go语言和beego框架前端使用layui布局开发的个......
  • WEB_baby_exec解析
    打开环境发现明显php代码,代码意义为ping一次地址在后面加上/?ip=1.1.1.1发现可以执行,那就可以使用;来进行注入;是linux命令连续执行在ip基础上加上/?ip=1.1.1.1;cat/flag.txt得到flagflag{123124}......
  • 【从零开始学习Go语言】八.Go语言的数组切片引用类型与值类型(总结)
    【从零开始学习Go语言】Go语言的数组与切片引用类型与值类型一.数组二.多维数组三.切片四.值类型与引用类型一.数组go语言的数组在之前的一些例子中有引用过,go的数组在创建时需要声明存储数据的类型,长度,并且长度在确定后便不可增加,类似python中的元组数组的声明方式有多种:第一种......
  • WindowsMobile平台UCWEB6.3 Beta版发布啦
    新增功能:1、自动表单功能:支持保存帐号登录时的填表内容,可以选择是否保存2、光标停留在页面输入框上,右键菜单增加“长文本输入”功能3、下载文件,编辑文件名框增加复制粘贴功能4、网址输入适配加入对已有书签URL的适配5、SP版本在菜单导航中加入快捷菜单入口功能优化:1、......
  • IDEA 关闭SpringBoot启动Logo/图标
     一、环境1、SpringBoot2.6.4 MavenPOM格式<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/></par......
  • websocket的消息丢失处理,以及前端监听心跳处理方案
    消息丢失处理方案:1、后台通过websocket传输给前端消息,并且后台生成校验此消息的定时任务,设置每5秒重发2、前端接收到消息后将消息通过websocket传输给后台3、后台如接收到前端的消息则删除对应的发送消息定时任务,如未收到消息则继续发送,设置最多发送5次(超过5次默认认为此条消......
  • Django——增加自定义功能
    在Django中,增加一个自己的功能,并在Django运行中创建一个进程,单独运行。#如果需要在运行时,同时运行某个程序代码,那么在wsgi中添加即可。fromnetwork_configimporttestfrommultiprocessingimportProcessif__name__=='gb_netconf.wsgi':#windows中必须要写,如果不......
  • 分享2023全新GO工程师面试总攻略,助力快速斩获offer
    点击下崽:分享2023全新GO工程师面试总攻略,助力快速斩获offer  提取码:k8c8GO(Golang)是一种快速、高效、牢靠、平安的编程言语,被普遍应用于后端开发、云计算、人工智能等范畴。在GO工程师面试中,面试官通常会调查我们的编程才能、系统设计才能、算法和数据构造等方面的学问。本文将引......
  • c#操作mongodb数据库工具类
    新建c#项目,在nuget中引入MongoDB.Driver驱动,然后新建一个MongoDBToolHelper类,将下面代码复制进去usingMongoDB.Bson;usingMongoDB.Bson.Serialization;usingMongoDB.Driver;usingMongoDB.Driver.Builders;usingSystem;usingSystem.Collections.Generic;usingSystem......
  • Django 部署指南
    远程登录服务器sudosshroot@user_name#删除原来的ssh密钥命令ssh-keygen-f"/home/shimmer/.ssh/known_hosts"-R"117.72.9.46"延长服务器ssh超时自动断开时间,此处为30分钟#默认情况下,SSH配置文件位于/etc/ssh/sshd_config。ClientAliveInterval1800ClientAliveCountM......