Go: 客户端已断开连接

huangapple go评论121阅读模式
英文:

Go: client is disconnected

问题

我加入Gophers团队已经有几周了。到目前为止一切顺利。
我正在使用一个fiber网络框架来构建后端API。

我正在使用MongoDB作为我的数据库。

database/db.go

  1. package database
  2. import (
  3. "context"
  4. "log"
  5. "time"
  6. "go.mongodb.org/mongo-driver/mongo"
  7. "go.mongodb.org/mongo-driver/mongo/options"
  8. "go.mongodb.org/mongo-driver/mongo/readpref"
  9. )
  10. var DB *mongo.Database
  11. // InitMongo : 初始化mongodb...
  12. func connectToMongo() {
  13. log.Printf("初始化数据库")
  14. client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
  15. if err != nil {
  16. log.Fatal("无法连接到数据库,原因:", err)
  17. }
  18. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  19. err = client.Connect(ctx)
  20. if err != nil {
  21. log.Fatal("上下文错误,mongoDB:", err)
  22. }
  23. // 取消上下文以避免内存泄漏
  24. defer cancel()
  25. defer client.Disconnect(ctx)
  26. // 检查数据库连接
  27. err = client.Ping(context.Background(), readpref.Primary())
  28. if err != nil {
  29. log.Fatal("Ping, mongoDB:", err)
  30. }
  31. log.Printf("数据库已连接!")
  32. // 创建一个数据库
  33. DB = client.Database("golang-test")
  34. return
  35. }
  36. // 在Golang中,init()函数在调用包时总是初始化。
  37. // 因此,每当调用DB变量时,init()函数都会初始化
  38. func init() {
  39. connectToMongo()
  40. }

controllers/mongo.controller/mongo.controller.go

  1. package mongocontroller
  2. import (
  3. "log"
  4. "github.com/gofiber/fiber/v2"
  5. service "gitlab.com/.../services/mongoservice"
  6. )
  7. // GetPersons godoc
  8. // @Summary 获取人员信息。
  9. // @Description 获取人员信息
  10. // @Tags persons
  11. // @Produce json
  12. // @Success 200 {object} []service.Person
  13. // @Failure 400 {object} httputil.HTTPError
  14. // @Failure 404 {object} httputil.HTTPError
  15. // @Failure 500 {object} httputil.HTTPError
  16. // @Router /v1/persons [get]
  17. func GetPersons(c *fiber.Ctx) error {
  18. res, err := service.GetPersons()
  19. if err != nil {
  20. log.Fatal("ERROR: 在控制器中...", err)
  21. }
  22. return c.JSON(res)
  23. }

services/mongoservice/mongo.service.go

  1. package mongoservice
  2. import (
  3. "context"
  4. "log"
  5. database "gitlab.com/.../database"
  6. "go.mongodb.org/mongo-driver/bson"
  7. "go.mongodb.org/mongo-driver/bson/primitive"
  8. )
  9. // Person : ...
  10. type Person struct {
  11. ID primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
  12. Name string `bson:"name,omitempty" json:"name,omitempty"`
  13. Age int `bson:"age,omitempty" json:"age,omitempty"`
  14. }
  15. func GetPersons() ([]Person, error) {
  16. ctx := context.Background()
  17. persons := []Person{}
  18. log.Printf("mongo数据...", ctx)
  19. cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})
  20. if err != nil {
  21. log.Fatal(err)
  22. }
  23. // 遍历返回的游标。
  24. for cur.Next(ctx) {
  25. var person Person
  26. cur.Decode(&person)
  27. persons = append(persons, person)
  28. }
  29. defer cur.Close(ctx)
  30. return persons, err
  31. }

这是我存储在数据库中的数据:

Go: 客户端已断开连接

问题是,服务中的**cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})**这一行总是抛出Client is disconnected的错误。

感谢您的帮助!

谢谢。

英文:

It's been few weeks since I joined in Gophers team. So far so good.
I started a new project using a fiber web framework to build backend APIs.

I am using MongoDB as my database.

database/db.go

  1. package database
  2. import (
  3. "context"
  4. "log"
  5. "time"
  6. "go.mongodb.org/mongo-driver/mongo"
  7. "go.mongodb.org/mongo-driver/mongo/options"
  8. "go.mongodb.org/mongo-driver/mongo/readpref"
  9. )
  10. var DB *mongo.Database
  11. // InitMongo : Initialize mongodb...
  12. func connectToMongo() {
  13. log.Printf("Initializing database")
  14. client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
  15. if err != nil {
  16. log.Fatal("Could not able to connect to the database, Reason:", err)
  17. }
  18. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  19. err = client.Connect(ctx)
  20. if err != nil {
  21. log.Fatal("Context error, mongoDB:", err)
  22. }
  23. //Cancel context to avoid memory leak
  24. defer cancel()
  25. defer client.Disconnect(ctx)
  26. // Ping our db connection
  27. err = client.Ping(context.Background(), readpref.Primary())
  28. if err != nil {
  29. log.Fatal("Ping, mongoDB:", err)
  30. }
  31. log.Printf("Database connected!")
  32. // Create a database
  33. DB = client.Database("golang-test")
  34. return
  35. }
  36. // In Golang, init() functions always initialize whenever the package is called.
  37. // So, whenever DB variable called, the init() function initialized
  38. func init() {
  39. connectToMongo()
  40. }

controllers/mongo.controller/mongo.controller.go

  1. package mongocontroller
  2. import (
  3. "log"
  4. "github.com/gofiber/fiber/v2"
  5. service "gitlab.com/.../services/mongoservice"
  6. )
  7. // GetPersons godoc
  8. // @Summary Get persons.
  9. // @Description Get persons
  10. // @Tags persons
  11. // @Produce json
  12. // @Success 200 {object} []service.Person
  13. // @Failure 400 {object} httputil.HTTPError
  14. // @Failure 404 {object} httputil.HTTPError
  15. // @Failure 500 {object} httputil.HTTPError
  16. // @Router /v1/persons [get]
  17. func GetPersons(c *fiber.Ctx) error {
  18. res, err := service.GetPersons()
  19. if err != nil {
  20. log.Fatal("ERROR: in controller...", err)
  21. }
  22. return c.JSON(res)
  23. }

services/mongoservice/mongo.service.go

  1. package mongoservice
  2. import (
  3. "context"
  4. "log"
  5. database "gitlab.com/.../database"
  6. "go.mongodb.org/mongo-driver/bson"
  7. "go.mongodb.org/mongo-driver/bson/primitive"
  8. )
  9. // Person : ...
  10. type Person struct {
  11. ID primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
  12. Name string `bson:"name,omitempty" json:"name,omitempty"`
  13. Age int `bson:"age,omitempty" json:"age,omitempty"`
  14. }
  15. func GetPersons() ([]Person, error) {
  16. ctx := context.Background()
  17. persons := []Person{}
  18. log.Printf("mongo data...", ctx)
  19. cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})
  20. if err != nil {
  21. log.Fatal(err)
  22. }
  23. // Iterate through the returned cursor.
  24. for cur.Next(ctx) {
  25. var person Person
  26. cur.Decode(&person)
  27. persons = append(persons, person)
  28. }
  29. defer cur.Close(ctx)
  30. return persons, err
  31. }

Here is my data stored in the database:

Go: 客户端已断开连接

The problem is, the line cur, err := database.DB.Collection("persons").Find(ctx, bson.M{}) from service always throwing Client is disconnected.

Any help is appreciated!

Thank you.

答案1

得分: 8

你正在同一个函数中调用defer client.Disconnect(ctx),而这个函数是用来创建连接的(connectToMongo),所以在调用完函数后会关闭连接。你应该在完成任务后返回连接并关闭。我指的是这些部分:
defer cancel()
defer client.Disconnect(ctx)

英文:

You are calling defer client.Disconnect(ctx) in the same function which is creating the connection (connectToMongo ) so it will close the connection after calling the function. You should return the connection and close after finishing your task. I mean these parts:
defer cancel()
defer client.Disconnect(ctx)

huangapple
  • 本文由 发表于 2021年8月17日 20:09:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/68817123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定