Golang如何实现websocket成功建立WS连接
前端
package main
import (
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"net/http"
)
var upGrader = websocket.Upgrader{
CheckOrigin: func (r *http.Request) bool {
return true
},
}
//webSocket请求ping 返回pong
func ping(c *gin.Context) {
//升级get请求为webSocket协议
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
return
}
//延迟关闭ws连接
defer ws.Close()
for {
//读取ws中的数据
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
//如果发送的信息是ping则返回pong
if string(message) == "ping" {
message = []byte("pong")
}
//写入ws数据 向前端返回数据
err = ws.WriteMessage(mt, message)
if err != nil {
break
}
}
}
func main() {
r := gin.Default()
r.GET("/ping/", ping)
r.Run(":8000")
}
后端
<template>
<div>
<van-button type="primary" @click="ws_connect">建立连接</van-button>
<van-field type="text" label="请输入信息" placeholder="" v-model="message"/>
<van-button type="primary" @click="send">发送信息</van-button>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
message:'',
websock: null, //建立的连接
lockReconnect: false, //是否真正建立连接
timeout: 3 * 1000, //30秒一次心跳
timeoutObj: null, //外层心跳倒计时
serverTimeoutObj: null, //内层心跳检测
timeoutnum: null, //断开 重连倒计时
}
},
methods: {
send:function(){
if (this.websock==null){
console.log("请建立连接")
return false
}
this.websock.send(this.message);
},
//连接go ws
ws_connect:function(){
this.initWebSocket()
},
initWebSocket() {
//初始化weosocket
const wsuri = "ws://localhost:8000/ping/";
if (this.websock !== null){
console.log('你已经建立了连接')
return false
}
this.websock = new WebSocket(wsuri);
this.lockReconnect = false
this.websock.onopen = this.websocketonopen;
this.websock.onmessage = this.websocketonmessage;
this.websock.onerror = this.websocketonerror;
this.websock.onclose = this.websocketclose;
},
reconnect() {
//重新连接
var that = this;
if (that.lockReconnect) {
// 是否真正建立连接
return;
}
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
that.timeoutnum && clearTimeout(that.timeoutnum);
// 如果到了这里断开重连的倒计时还有值的话就清除掉
that.timeoutnum = setTimeout(function() {
//然后新连接
that.initWebSocket();
that.lockReconnect = false;
}, 5000);
},
reset() {
//重置心跳
var that = this;
//清除时间(清除内外两个心跳计时)
clearTimeout(that.timeoutObj);
clearTimeout(that.serverTimeoutObj);
//重启心跳
that.start();
},
start() {
//开启心跳
var self = this;
self.timeoutObj && clearTimeout(self.timeoutObj);
// 如果外层心跳倒计时存在的话,清除掉
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
// 如果内层心跳检测倒计时存在的话,清除掉
self.timeoutObj = setTimeout(function() {
// 重新赋值重新发送 进行心跳检测
//这里发送一个心跳,后端收到后,返回一个心跳消息,
if (self.websock.readyState == 1) {
//如果连接正常
// self.websock.send("heartCheck");
} else {
//否则重连
self.reconnect();
}
self.serverTimeoutObj = setTimeout(function() {
// 在三秒一次的心跳检测中如果某个值3秒没响应就关掉这次连接
//超时关闭
self.websock.close();
}, self.timeout);
}, self.timeout);
// 3s一次
},
websocketonopen(e) {
console.log("Connection open ...");
this.websocketsend('helloword');
},
websocketonerror() {
//连接建立失败重连
console.log("失败");
this.initWebSocket();
},
//接收数据
websocketonmessage(e) {
console.log(e.data)
},
websocketsend(Data) {
//数据发送
this.websock.send(Data);
},
websocketclose(e) {
//关闭
this.reconnect()
},
// 关闭websocket连接
close_websocket(){
this.websock.close()
this.websock = null
this.lockReconnect = 1
}
},
mounted() {
},
created() {
}
}
</script>
<style scoped>
</style>
本章节只是简单使用gin框架搭配gorilla工具实现websocket连接,如果想实现IM实时通讯系统,可以使用go结构体变、channel管道、redisPubsub等功能实现。
|