WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久化的连接,允许服务器主动向客户端推送数据,同时也允许客户端向服务器发送数据,实现了实时的双向通信。 这部分直接说你可能听不懂;我举个例子说他的功能(
下面先说一下为什么会出现WebSocket?
平时我们用java或者go等语言去写一些接口,然后前端调用这些接口就能实现数据获取展示等功能,也就是写出来了一个web页面比如:xx书城。但经过观察就发现这种普通的http接口都是要:当前端点击某个位置的时候,主动的发送http请求去后端接口,才能够拿到数据。也可以理解为http如果想知道服务器是否有内容更新就必须一直发请求到服务端去确认,如果服务器没有更新,那这些通信就都是徒劳的。
所以想要实现http协议能够及时探知服务器上是否有内容更新,以下这些http标准就会成为瓶颈
后来提出了一种Commet的解决方法,即当客户端发送服务端是否有内容更新的查看请求的时候,服务端就先不回应,当服务器端内有内容更新时,再返回该响应。这是一种通过延迟应答,实现服务器端向客户端推送的功能。但是一次连接持续时间边长会消耗更多的资源,同时 http 的瓶颈也没解决。
后来又提出了SPDY的设计,能实现功能但有一些缺点过于明显
最后后来Websocket就出现了。因为不论用什么技术,只要通信使用的是HTTP协议,那就无法彻底解决瓶颈问题。WebSocket网络技术正实为解决这些问题而实现的一套新协议及API。
一旦建立了WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行,通信过程可以发json、xml、图片等任意格式的数据。
由于是建立在HTTP基础之上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
websocket有推送功能且是长久连接,它的首部信息也小,连接开销以及通信量都减小了很多。
接下来就简单实现以下 前端用js,后端用go 语言怎么实现建立websocket连接的,前端和后端使用相同的 URL 来建立 WebSocket 连接是最常见的方式
因为想建立连接要先开启服务端做好准备监听,然后等待客户端去发起请求
package main import ( "fmt" "log" "net/http" "github.com/gorilla/websocket" ) // 创建一个 websocket.Upgrader 对象 var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { // CheckOrigin 函数用于检查请求的来源是否合法,即允许跨域访问 return true }, } func websocketHandler(w http.ResponseWriter, r *http.Request) { // 将 HTTP 连接升级为 WebSocket 连接 //request 参数包含了客户端发起连接时提供的 URL 信息ws://localhost:8088/userid conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("升级为 WebSocket 连接失败:", err) return } // 读取客户端发送的消息 for { //阻塞式的操作。当调用这个方法时,如果没有接收到新的消息,它将一直阻塞等待,直到收到新的消息或发生错误。 messageType, p, err := conn.ReadMessage() if err != nil { log.Println("读取消息失败:", err) break } // 在控制台打印接收到的消息 log.Printf("接收到消息: %s", p) // 构建回复消息 response := []byte(fmt.Sprintf("接收到消息: %s", p)) // 通过websocket推送,去回复客户端消息,客户端会及时接收到这份信息 err = conn.WriteMessage(messageType, response) if err != nil { log.Println("发送消息失败:", err) break } } // 关闭 WebSocket 连接 err = conn.Close() if err != nil { log.Println("关闭连接失败:", err) } } func main() { http.HandleFunc("/ws", websocketHandler) log.Println("WebSocket 服务器运行在 http://localhost:8000/ws") err := http.ListenAndServe(":8088", nil) if err != nil { log.Fatal("启动服务器失败:", err) } }
前端通过websocket发送给后端的信息就会打印到控制台了
前端页面就这样,打开的时候就会自动运行js部分,然后发起连接请求了
Document
同样,服务端通过websocket推送到前端的控制台中展示
上一篇:LNMP 环境下 Nginx 1.26.0 开启 HTTP/3 QUIC 支持
下一篇:麒麟v10 curl报错:SSLv3_client_method version OPENSSL_1_1_0 not define