我想在 Revel 框架中创建一对一聊天,但出现错误。最初按照demo在revel chat中工作,但是刷新页面不起作用,所以我尝试了这种方法,但不知道如何处理单个聊天。
这是一个错误:
app server.go:2848: http: panic serving 127.0.0.1:50420: interface conversion: interface is nil, not io.Writer goroutine 166 [running]: net/http.(*conn).serve.func1(0xc4201d03c0)
我的 go 代码是我处理 ws root 的地方,单用户聊天需要数据库连接。我正在为此使用 posgres
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var clients = make(map[*websocket.Conn]bool) // connected clients
var broadcast = make(chan Message) // broadcast channel
// Configure the upgrader
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// Define our message object
type Message struct {
Email string `json:"email"`
Username string `json:"username"`
Message string `json:"message"`
Created string `json:"created"`
}
func main() {
// Create a simple file server
fs := http.FileServer(http.Dir("public"))
http.Handle("/", fs)
// Configure websocket route
http.HandleFunc("/ws", handleConnections)
// Start listening for incoming chat messages
go handleMessages()
// Start the server on localhost port 8000 and log any errors
log.Println("http server started on :8090")
err := http.ListenAndServe(":8090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func handleConnections(w http.ResponseWriter, r *http.Request) {
// Upgrade initial GET request to a websocket
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Fatal(err)
}
// Make sure we close the connection when the function returns
defer ws.Close()
// Register our new client
clients[ws] = true
for {
var msg Message
// Read in a new message as JSON and map it to a Message object
err := ws.ReadJSON(&msg)
if err != nil {
log.Printf("error: %v", err)
delete(clients, ws)
break
}
// Send the newly received message to the broadcast channel
broadcast <- msg
}
}
func handleMessages() {
for {
// Grab the next message from the broadcast channel
msg := <-broadcast
// Send it out to every client that is currently connected
for client := range clients {
err := client.WriteJSON(msg)
if err != nil {
log.Printf("error: %v", err)
client.Close()
delete(clients, client)
}
}
}
}
最佳答案
我认为您错误地使用了 gorilla/websocket
API。您复制了 echo
示例,它是一个基本演示,预计只能处理单个 ws 连接。从 chat
示例开始。特别要注意 serveWs
是一个非阻塞调用,而您的 handleConnections
是阻塞的,即它永远不会返回。在此处查看 gorilla/websocket
API 使用的完整示例:
https://github.com/tinode/chat/blob/master/server/wshandler.go
正如 Cerise L 正确指出的那样,您的 clients
肯定有一场比赛,尽管我认为这不太可能产生 panic 。我认为最可能的 panic 来源是在关闭的 http 连接上调用 Upgrade
。不可能准确地说,因为您没有发布 panic 的完整输出。
关于go - 在 golang 中一对一聊天,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47280162/