SocketOneee
SocketOneee
项目中有一个实施数据显示到前端,当然是websocket,找到一个业界star最多的包起步
代码结构
hm-socket2
--main.go
--mclient
|--mclient.go
--mserver
|--mserver.go
main.go
package main
import (
"hm-socket2/my/mclient"
"hm-socket2/my/mserver"
"time"
)
func my_easy() {
//c := make(chan int, 1)
go mclient.Mclient()
time.Sleep(time.Second)
go mserver.Mserver()
}
// 就是defer conn.close坑
func main() {
my_easy()
//stand()
time.Sleep(6 * time.Second)
}
mclient.go
package mclient
// 假设我数据传输的都是字符串
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/url"
)
// 从客户端server读取数据
func ReadData(c *websocket.Conn, msgChan chan []byte) {
// 需要一直监听
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("读取数据出错", err)
}
fmt.Println("mclient数据读取成功:", string(message))
msgChan<- message
}
}
// 写入数据
func WriteData(c *websocket.Conn, msgChan chan []byte, msgCount int) {
for {
select {
case msg := <-msgChan:
data := "mclient写数据 =====" + string(msg)
fmt.Println(msgCount, "<-----写数据条数")
msgCount++
c.WriteMessage(websocket.TextMessage, []byte(data))
}
}
}
func Mclient() {
var (
msgChan chan []byte
msgCount int
)
msgCount = 0
msgChan = make(chan []byte, 0)
// 创建c 可以看见 这个C还是TCP
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/hello"}
log.Printf("connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
// 到这退出了 所以读取数据不要用 go关键字
defer c.Close()
// 监听数据过来 也就是到这个服务器
go WriteData(c, msgChan, msgCount)
ReadData(c, msgChan)
}
mserver.go
package mserver
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
"time"
)
func hello(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
go func() {
// 写数据
for {
err = conn.WriteMessage(websocket.TextMessage, []byte("ni_ma"))
if err != nil {
log.Println(err)
}
time.Sleep(time.Second)
}
}()
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Println(err)
}
fmt.Println("mserver读取数据为:", string(message))
}
}
var upgrader = websocket.Upgrader{} // use default options
// 写数据给客户啊
func WriteDataToClient(c *websocket.Conn) {
// 下面的未年检你格式一定和客户啊短沟通好
for {
err := c.WriteMessage(websocket.TextMessage, []byte("ni_ma"))
if err != nil {
log.Println(err)
}
time.Sleep(3 * time.Second)
}
}
// 从服务端读取数据
func ReadDataFromClient(c *websocket.Conn) {
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println(err)
}
fmt.Println("读取数据为:", message)
}
}
func Mserver() {
http.HandleFunc("/hello", hello)
http.ListenAndServe("localhost:8080", nil)
}
代码测试输出
2020/11/18 15:27:21 connecting to ws://localhost:8080/hello
mclient数据读取成功: ni_ma
0 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
mclient数据读取成功: ni_ma
1 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
mclient数据读取成功: ni_ma
2 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
mclient数据读取成功: ni_ma
3 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
mclient数据读取成功: ni_ma
4 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
mclient数据读取成功: ni_ma
5 <-----写数据条数
mserver读取数据为: mclient写数据ni_ma
解析
mclient.go
服务端,一般用于后端项目mserver.go
客户端,用于点断vue,只不过这里面用后端测试连接一下
踩坑
在defer c.close()。 用go时候,必须有一个不用的。阻塞defer
未解决
如何优雅关闭socket.conn