zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SuperSocket框架中BinaryRequestInfo协议的使用
    UIImageView学习笔记
    UITextField学习小结
    Java数据结构相关类的实现原理
    Android 中把尺寸转换方法
    Win8 & WP8.1 轻型数据库
    隐私策略
    Windows 10(UWP)开发技巧
    【UWP】FFmpeg库的编译
    【UWP】拖拽列表项的排序功能实现
  • 原文地址:https://www.cnblogs.com/maomaomaoge/p/14126037.html
Copyright © 2011-2022 走看看