簡體   English   中英

Vapor Web 套接字保持與數據庫的連接

[英]Vapor web socket retaining connection to database

我正在我的蒸氣代碼中創建一個網絡套接字並將發送到該套接字的數據保存到 PostgreSQL 數據庫中。 數據庫和代碼都托管在 heroku 上。 Heroku 只允許 20 個連接到數據庫。 使用蒸氣創建網絡套接字需要一個閉包,即使套接字關閉,該閉包也會保留與我的 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類已設置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)
        }
}

看起來這是一個遲到的回復,我一直在做和你一樣的事情:我們想使用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)

        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM