【发布时间】:2020-04-29 14:10:40
【问题描述】:
我使用 gorilla websocket 制作了一个小型聊天应用程序。当只有一个客户端时,速度很快,正如预期的那样。但是当我与另一个客户端连接时,更新聊天可能需要 3 秒钟,即使是在我的本地计算机上托管。
websocket 代码:
var clients = make(map[*websocket.Conn]bool)
var broadcast = make(chan Message)
var upgrader = websocket.Upgrader{}
func main() {
router.HandleFunc("/ws", handleConnections)
err := http.ListenAndServe(":80", router)
}
func handleConnections(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Fatal(err)
}
defer ws.Close()
clients[ws] = true
for {
var msg Message
err := ws.ReadJSON(&msg)
if err != nil {
log.Printf("error: %v", err)
delete(clients, ws)
break
}
broadcast <- msg
}
}
func handleMessages() {
for {
msg := <-broadcast
log.Println(msg)
database, _ := sql.Open("sqlite3", "./database.db")
statement, _ := database.Prepare("CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY, username TEXT, message TEXT, timestamp INTEGER)")
statement.Exec()
statement, _ = database.Prepare("INSERT INTO messages (username, message, timestamp) VALUES (?, ?, ?)")
statement.Exec(&msg.Username, &msg.Message, &msg.Timestamp)
for client := range clients {
err := client.WriteJSON(msg)
if err != nil {
log.Printf("error: %v", err)
client.Close()
delete(clients, client)
}
}
}
}
【问题讨论】:
-
应用程序中要修复的问题: 1) 打开数据库,创建表并在消息循环之外准备语句。从 main 调用的 setup 函数是放置此代码的好地方。 2) 修复
clients上的数据竞争。 -
我修复了 1 但问题仍然存在。我不知道您所说的客户数据竞赛是什么意思。完整代码:github.com/mismaah-abdulla/Chatapp-Backend/blob/…
-
数据库写入
handleMessages慢吗?handleMessages中的循环是否卡在慢速客户端上?数据竞争:句柄连接中对clients的写入与handleMessages中的读取是并发的。我建议从gorilla's chat example 开始。它处理了问题中的代码没有处理的几个问题。只需在数据库中添加一些内容,您就可以开始使用了。 -
我刚刚检查了在handleMessages中运行数据库写入所需的时间。它需要 0 或 5 秒。新客户端连接到 websocket 后需要 5 秒,但几分钟 (1-3) 后,它是随机的 0 或 5 秒。很奇怪。
-
这个问题是关于为什么数据库写入慢,而不是为什么 websockets 慢?如果是这样,请编辑或删除问题。