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

解析

  1. mclient.go服务端,一般用于后端项目
  2. mserver.go客户端,用于点断vue,只不过这里面用后端测试连接一下

踩坑

在defer c.close()。 用go时候,必须有一个不用的。阻塞defer

未解决

如何优雅关闭socket.conn

posted @ 2020-12-12 19:29  maob  阅读(100)  评论(0编辑  收藏  举报