蒸汽网络插座保持与数据库的连接

时间:2018-03-01 17:30:00

标签: swift postgresql heroku vapor

我正在使用Steam代码创建一个Web套接字,并将发送到该套接字的数据保存到PostgreSQL数据库中。数据库和代码都在heroku上托管。 Heroku只允许20个连接到数据库。使用steam创建一个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)
        }
}

1 个答案:

答案 0 :(得分:1)

看起来这是一个较晚的答复,我一直在做与您一样的事情:我们想使用vapor的websockets(最新的蒸气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)

        }
    }