一、websocket是由长链接和轮询进化而来,当建立连接之后,不断开连接,开闭一个数据传输通道数据格式为[]byte。后端会一直保留这个进程。
1.WebSocket 和 HTTP 实际上都是一个TCP链接。http请求可以通过设置header的方式升级成websoket 长链接
二、具体代码
package websoket
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
"strconv"
"time"
)
//Conn类型表示WebSocket连接。服务器应用程序从HTTP请求处理程序调用Upgrader.Upgrade方法以获取* Conn:
// var upgrader = websocket.Upgrader{}
var (
upgrader = websocket.Upgrader {
// 读取存储空间大小
ReadBufferSize:1024,
// 写入存储空间大小
WriteBufferSize:1024,
// 允许跨域
CheckOrigin: func(r *http.Request) bool {
return true
},
}
)
func wsHandler(w http.ResponseWriter, r *http.Request) {
// 完成握手 升级为 WebSocket长连接,使用conn发送和接收消息。
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("upgrade:", err)
return
}
defer conn.Close()
go SendMsg(conn)
//调用连接的WriteMessage和ReadMessage方法以一片字节发送和接收消息。实现如何回显消息:
//p是一个[]字节,messageType是一个值为websocket.BinaryMessage或websocket.TextMessage的int。
for {
messageType, msg, err := conn.ReadMessage()
if err != nil {
log.Println("Reading error...",err)
return
}
log.Printf("Read from client msg:%s \n", msg)
str:="服务器返回的数据:"+string(msg)
if err := conn.WriteMessage(messageType, []byte(str)); err != nil {
log.Println("Writeing error...",err)
return
}
log.Println(messageType)
log.Printf("Write msg to client: recved: %s \n",str )
}
}
func SendMsg(conn *websocket.Conn) {
for i:=0;i<20;i++{
str:="服务器推送:"+strconv.Itoa(i)
if err := conn.WriteMessage(1, []byte(str)); err != nil {
log.Println("Writeing error...",err)
return
}
time.Sleep(3*time.Second)
fmt.Println(str)
}
}
func InitWebsocket() {
http.HandleFunc("/",wsHandler) // ws://127.0.0.1:8888
// 监听 地址 端口
err := http.ListenAndServe(":8888", nil)
if err != nil {
log.Fatal("ListenAndServe", err.Error())
}
}