Websocket简介
WebSocket可以实现客户端与服务器间双向、基于消息的文本或二进制数据传输。它是浏览其中最靠近套接字的API。但WebSocket连接远远不是一个网络套接字,因为浏览器在这个简单的API之后隐藏了所有的复杂性,而且还提供了更多服务:
- 连接协商和同源策略;
- 与既有HTTP基础设施的互操作;
- 基于消息的通信和高效消息分帧;
- 的协议协商及可扩展能力。
WebSocket资源URL采用了自定义模式:ws表示纯文本通信(如ws://example.com/socket),wss表示使用加密信道通信(TCP TLS)。
长连接实现
本例用gin框架,引入
github.com/gorilla/websocket包,项目源码可到https://github.com/shidawuhen/asap/tree/feature_pzq_longconnect查看
服务端核心代码:
- ping函数,将请求升级为websocket。
- 只有Get请求才能进行升级,具体原因可以查看websocket源码
- 当客户端请求ping时,便建立了长连接,服务端读取客户端数据,如果数据为ping,则返回pong,如果不为ping,则把输入的内容返回。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
var upGrader = websocket.Upgrader{
CheckOrigin: func (r *http.Request) bool {
return true
},
}
func setupRouter() *gin.Engine {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
// Ping test
r.GET("/ping", ping)
r.GET("/longconnecthtml",longconnecthtml)
return r
}
func longconnecthtml(c *gin.Context) {
c.HTML(http.StatusOK, "longconnect.tmpl",gin.H{})
}
func ping(c *gin.Context) {
//c.String(http.StatusOK, "ok")
//升级get请求为webSocket协议
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
return
}
defer ws.Close()
for {
//读取ws中的数据
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
if string(message) == "ping" {
message = []byte("pong")
}
//写入ws数据
err = ws.WriteMessage(mt, message)
if err != nil {
break
}
}
}
func main() {
r := setupRouter()
// Listen and Server in 0.0.0.0:8080
r.Run(":9090")
}
客户端核心代码:
- 要使用websocket,客户端必须发起websocket请求
- websocket的建立和使用也很方便,主要涉及
- new WebSocket:创建websocket对象
- onopen:连接建立时触发
- onmessage:客户端接收服务端数据时触发
- onerror:通信发生错误时触发
- onclose:连接关闭时触发
该代码块的主要功能是和服务端建立连接,在文本框输入信息,将信息发送给服务端,并将服务端返回内容显示出来
HTML>
<html>
<head>
<meta charset="utf-8">
<title>长连接测试title>
<textarea id="inp_send" class="form-control" style="height:100px;" placeholder="发送的内容">textarea>
<button type="button" id="btn_send" class="btn btn-info" onclick="fun_sendto();">发送(ctrl 回车)button>
<script type="text/javascript" src="https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1-edb203c114.10.2.js">script>
<script type="text/javascript">
var ws = new WebSocket("ws://localhost:9090/ping");
//连接打开时触发
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
//接收到消息时触发
ws.onmessage = function(evt) {
console.log("Received Message: " evt.data);
};
//连接关闭时触发
ws.onclose = function(evt) {
console.log("Connection closed.");
};
function fun_sendto(){
var content = $("#inp_send").val();
ws.send(content);
}
script>
head>
<body>
body>
html>
服务端运行起来之后,请求
http://localhost:9090/longconnecthtml即可查看效果
长连接展示
- 浏览器,请求ping接口,便可看到该请求为websocket请求,而且为pending状态
- 也可以查看到在发起请求时,request header中有很多新的参数,具体含义大家可以看我提供的参考资料
- console中显示的是服务端推送到客户端的数据
注意事项
- 长连接可以实现双向通信,但是以占用连接为前提的,如果请求量较大,需要考虑资源问题
- 服务部署情况对效果影响很大。例如,如果只部署北京机房供全国使用,当服务端向客户端推送数据时,不同地区可能会有很大延迟。
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/22931.html