Go 如何實現長連接
科普
長連接,也被稱爲持久連接,是對同一個服務器的多次請求,使用相同的 TCP 連接來發送。這與短連接(每一個請求建立一個新的 TCP 連接)形成對比。長連接可以減少建立和關閉連接的時間開銷,提升網絡通信效率。
例如在 HTTP/1.1 中,默認就是採用長連接的方式,大大提高了 web 頁面的加載速度。客戶端和服務器之間建立的 TCP 連接在傳輸完數據之後並不立即斷開,而是可以繼續被用來傳輸之後的數據。
長連接特別適用於需要頻繁通信或實時交互的場景,例如數據庫連接、消息推送、Websocket 通信等。
如何實現長連接
1、HTTP 長連接
HTTP 長連接:在 HTTP1.1 中,默認都是長連接,也就是 Connection: keep-alive。Go 的 net/http 包默認也支持這個,所以你不需要做任何設置。
示例代碼:
http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
// 處理邏輯
fmt.Fprintf(w, "This is a persistent connection")
})
http.ListenAndServe(":8080", nil)
客戶端可以複用連接多次進行請求,節省了創建和關閉連接的開銷。
2、WebSocket
WebSocket 提供了一種在單個 TCP 連接上進行全雙工通訊的協議。Go 語言中的 gorilla/websocket 庫可以用來處理 WebSocket 連接。
下面我來用 websocket 技術來實現一個簡單的聊天室功能
安裝擴展庫
go get github.com/gorilla/websocket
下面是服務端的代碼
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
log.Println(string(message))
var amessage = "返回內容是"+string(message)
if err = conn.WriteMessage(messageType, []byte(amessage)); err != nil {
log.Println(err)
return
}
}
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("server starting on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
這個簡單的聊天室將任何從客戶端接收到的消息都發回到客戶端。
然後,需要創建一個 Web 頁面作爲客戶端頁面,與 WebSocket 服務器通信:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Demo</title>
</head>
<body>
<textarea cols="30" rows="10"></textarea>
<br/>
<input type="text"/>
<button onclick="sendMsg()">發送</button>
<script>
let socket = new WebSocket("ws://localhost:8080");
socket.onmessage = function(event) {
document.getElementById('chat').value += event.data + '\n'
};
function sendMsg() {
let msg = document.getElementById('input').value;
socket.send(msg);
document.getElementById('input').value = '';
}
</script>
</body>
</html>
在這個簡單的示例裏,任何在文本框中輸入的消息都會被髮送到服務器,然後服務器將相同的消息添加額外處理然後發送回來並顯示在屏幕上。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/cgx8kuxWkQWVCZj_N80DXg