【问题标题】:Vapor web socket retaining connection to databaseVapor Web 套接字保持与数据库的连接
【发布时间】:2018-08-09 20:42:26
【问题描述】:

我正在我的 vapor 代码中创建一个 Web 套接字,并将发送到该套接字的数据保存到 PostgreSQL 数据库中。数据库和代码都托管在 heroku 上。 Heroku 只允许与数据库建立 20 个连接。使用 vapor 创建一个 web 套接字需要一个闭包,即使套接字关闭,该闭包也会保留与我的 heroku 数据库的连接。我不知道为什么。这是我的代码。

func setupRoutes() throws {
    socket("log") { req, ws in
        background {
            while ws.state == .open {
                try? ws.ping()
                self.console.wait(seconds: 10) // every 10 seconds
            }
        }

        ws.onText = { ws, text in
            //print ("log is \(text)")
            let logMessage = try JSON(bytes: text.utf8.array)
            guard let instanceId = logMessage!["serverPlatformId"]?.string else {try ws.send("no platform sent"); return}
            guard let date = logMessage!["date"]?.double else {print ("no date sent"); try ws.send("no date sent");return}
            guard let percent = logMessage!["percent"]?.double else {print ("no percent sent"); try ws.send("no percent sent");return}


            let incoming = LogAnalytics(instanceId: instanceId, date: date, percent: percent)
            try incoming.save()
        }

        ws.onClose = { ws, _, _, _ in
            print ("log sokcet closeing")
            try ws.send("log socket closed")
        }
    }
}

我需要以某种方式关闭与数据库的连接或在套接字关闭时释放连接。我不断达到数据库连接数的限制,因此我必须删除所有连接并允许服务器重新连接。如何在套接字关闭时释放与数据库的连接,甚至在代码中手动释放?

现在LogAnalytics 类已设置完毕。

final class LogAnalytics:Model, Preparation, RowRepresentable, JSONRepresentable, NodeRepresentable {

        var instanceId:String
        var date:Double
        var percent:Double

        var id: Node?

        let storage = Storage()

        init(row: Row) throws {
            id = try row.get("id")
            instanceId = try row.get("instanceId")
            percent = try row.get("percent")
            date = try row.get("date")
        }

        func makeRow() throws -> Row {
            var row = Row()
            try row.set("id", id)
            try row.set("instanceId", instanceId)
            try row.set("percent", percent)
            try row.set("date", date)
            return row
        }

        static func prepare(_ database: Database) throws {
            try database.create(self, closure: { (log) in
                log.id()
                log.string("instanceId")
                log.double("date")
                log.double("percent")
            })
        }

        static func revert(_ database: Database) throws {
            try database.delete(self)
        }
}

【问题讨论】:

    标签: swift postgresql heroku vapor


    【解决方案1】:

    看起来这是一个迟到的回复,我一直在做和你一样的事情:我们想使用 vapor 的 websockets(最新的 Vapor 3.2.0)构建一个聊天应用程序。但是,当数据库连接用完时,系统无法为更多用户提供服务。解决方案是尝试手动管理池化数据库连接,而不是使用req 对象提供的默认连接。这是我们最后要做的事情(我以更改您的代码为例):

        ws.onText = { ws, text in
            //print ("log is \(text)")
            let logMessage = try JSON(bytes: text.utf8.array)
            guard let instanceId = logMessage!["serverPlatformId"]?.string else {try ws.send("no platform sent"); return}
            guard let date = logMessage!["date"]?.double else {print ("no date sent"); try ws.send("no date sent");return}
            guard let percent = logMessage!["percent"]?.double else {print ("no percent sent"); try ws.send("no percent sent");return}
            app.requestPooledConnection(to: .mysql).flatMap { connection -> EventLoopFuture<Void> in
                        defer{try? app.releasePooledConnection(connection, to: .mysql)}
                        let incoming = LogAnalytics(instanceId: instanceId, date: date, percent: percent)
                        try incoming.save(on: connection)
    
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-04-13
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 2019-06-22
      • 2010-12-01
      • 2018-11-08
      相关资源
      最近更新 更多