尝试使用 webSocket 制作实时聊天应用程序,当尝试将连接升级到 webSocket 时出现此错误:“websocket:客户端未使用 websocket 协议:“连接”标头中未找到“升级”令牌
代码:
func chat(w http.ResponseWriter, r *http.Request) {
funcName := logger.GetFuncName()
logger.InfoHttp(r.URL.Path, r.Method, funcName)
token, err := auth.GetToken(r)
if err != nil {
http.Redirect(w, r, "/", 302)
return
}
userId, err := auth.ValidateToken(token)
if err != nil {
logger.Error("Couldn't validate token", err, funcName)
http.Redirect(w, r, "/", 302)
return
}
user, err := userController.GetUserById(userId)
if err != nil {
logger.Error(fmt.Sprintf("Couldn't get user by id(%v)", userId), err, funcName)
http.Redirect(w, r, "/", 302)
return
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logger.Error("Upgrade failed", err, funcName)
http.Error(w, err.Error(), 500)
}
Tmpl.ExecuteTemplate(w, "index.html", user)
defer func() {
conn.Close()
delete(websocketConn, conn)
}()
websocketMutex.Lock()
websocketConn[conn] = true
websocketMutex.Unlock()
for {
mt, message, err := conn.ReadMessage()
if err != nil || mt == websocket.CloseMessage {
logger.Error("Couldn't read message", err, funcName)
}
fmt.Println(message)
for conection := range websocketConn {
err = conection.WriteMessage(websocket.TextMessage, message)
if err != nil {
conection.Close()
logger.Error("Couldn't write massage to connection", err, funcName)
delete(websocketConn, conection)
return
}
}
}
}
func chat(w http.ResponseWriter, r *http.Request) {
funcName := logger.GetFuncName()
token, err := auth.GetToken(r)
if err != nil {
http.Redirect(w, r, "/", 302)
return
}
userId, err := auth.ValidateToken(token)
if err != nil {
logger.Error("Couldn't validate token", err, funcName)
http.Redirect(w, r, "/", 302)
return
}
user, err := userController.GetUserById(userId)
if err != nil {
logger.Error(fmt.Sprintf("Couldn't get user by id(%v)", userId), err, funcName)
http.Redirect(w, r, "/", 302)
return
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logger.Error("Upgrade failed", err, funcName)
http.Error(w, err.Error(), 500)
}
Tmpl.ExecuteTemplate(w, "index.html", user)
defer func() {
conn.Close()
delete(websocketConn, conn)
}()
websocketMutex.Lock()
websocketConn[conn] = true
websocketMutex.Unlock()
for {
mt, message, err := conn.ReadMessage()
if err != nil || mt == websocket.CloseMessage {
logger.Error("Couldn't read message", err, funcName)
}
fmt.Println(message)
for conection := range websocketConn {
err = conection.WriteMessage(websocket.TextMessage, message)
if err != nil {
conection.Close()
logger.Error("Couldn't write massage to connection", err, funcName)
delete(websocketConn, conection)
return
}
}
}
}
func StartServer() {
var err error
Tmpl, err = template.ParseGlob("templates/*.html")
if err != nil {
funcName := logger.GetFuncName()
logger.Error("Couldn't parse tamplate", err, funcName)
}
http.HandleFunc("/chat/", chat)
err = http.ListenAndServe(":8080", nil)
if err != nil {
funcName := logger.GetFuncName()
logger.Error("Couldn't start the server", err, funcName)
}
}
............................................... ..................................................... ..................................................... .........................
还有一个前端,我是用gpt生成的,不知道对不对:
<body>
<form>
<input type="text" id="message" placeholder="Type your message here" />
<button type="submit">Send</button>
</form>
<script>
const websocket = new WebSocket('ws://localhost:8080/chat');
const chat = document.getElementById('chat');
const form = document.querySelector('form');
const input = document.getElementById('message');
websocket.onopen = (event) => {
console.log('WebSocket connected');
};
websocket.onmessage = (event) => {
const message = JSON.parse(event.data);
chat.innerHTML += `<p>${message.username}: ${message.text}</p>`;
};
form.addEventListener('submit', (event) => {
event.preventDefault();
const message = input.value;
const username = 'Alice'; // Change this to the username of the logged-in user
const data = JSON.stringify({ username, text: message });
websocket.send(data);
input.value = '';
});
</script>