我正在使用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)
}
}
答案 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)
}
}