【发布时间】:2021-03-15 06:38:42
【问题描述】:
我需要扩展this tutorial 的代码以运行常规休息进程和WebSocket 服务器作为go 例程的一部分。
这是 Go 部分:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
var WS = websocket.Conn{}
func reader(conn *websocket.Conn) {
for {
// read in a message
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
// print out that message for clarity
fmt.Println(string(p))
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home Page")
}
func restResponsePage(w http.ResponseWriter, r *http.Request) {
text := []byte("rest response")
if err := WS.WriteMessage(websocket.TextMessage, text); err != nil {
log.Println(err)
}
fmt.Fprintf(w, "rest response")
}
func wsEndpoint(w http.ResponseWriter, r *http.Request) {
upgrader.CheckOrigin = func(r *http.Request) bool { return true }
// upgrade this connection to a WebSocket
// connection
WS, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
}
log.Println("Client Connected")
err = WS.WriteMessage(1, []byte("Hi from server!"))
if err != nil {
log.Println(err)
}
reader(WS)
}
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/restRequest", restResponsePage)
}
func setupWsRoute() {
http.HandleFunc("/ws", wsEndpoint)
}
func main() {
fmt.Println("Hello World")
go func() {
setupWsRoute()
log.Fatal(http.ListenAndServe(":8081", nil))
}()
setupRoutes()
log.Fatal(http.ListenAndServe(":8080", nil))
}
和客户端index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Go WebSocket Tutorial</title>
</head>
<body>
<h2>Hello World</h2>
<script>
let socket = new WebSocket("ws://127.0.0.1:8081/ws");
console.log("Attempting Connection...");
socket.onopen = () => {
console.log("Successfully Connected");
socket.send("Hi From the Client!")
};
socket.onmessage = (event) => {
console.log("message from Server: ", event.data);
};
socket.onclose = event => {
console.log("Socket Closed Connection: ", event);
socket.send("Client Closed!")
};
socket.onerror = error => {
console.log("Socket Error: ", error);
};
</script>
</body>
</html>
当我点击 restRequest 端点时,在写入 restResponsePage 响应编写器 w 之前,我想向我声明为全局 var WS 并在升级连接时在读取器方法中初始化的 websocket 写入一条消息。
这在某种程度上不起作用,相反,有一个异常,我不知道如何解决它。
【问题讨论】:
-
程序将 websocket 连接分配给用 short variable declaration 声明的局部变量。 Assign 到包级变量,而不是声明局部变量。
-
我以为我已经在代码中这样做了...分配给包级别 var 是什么意思?
-
包级变量就是所谓的全局变量。请注意 short variable declaration 和 assignment 之间的语法差异:
:=与=。 -
程序现在正在使用这两个更改,谢谢 :) var WS *websocket.Conn 和 WS, _ = upgrader.Upgrade(w, r, nil)
标签: go design-patterns websocket gorilla