标签 websocket 下的文章

golang websocket并发


WsConn *websocket.Conn 并发不安全 不能同时写
panic: concurrent write to websocket connection

package cws
 
import (
    "errors"
    "github.com/gorilla/websocket"
    "sync"
)
 
//封装websocket并发读写操作
 
type Connection struct {
    WsConn    *websocket.Conn
    InChan    chan []byte
    OutChan   chan models.BayDataS
    CloseChan chan byte
    Mutex     sync.Mutex
    IsClosed  bool
}
 
func InitConnection(wsConn *websocket.Conn) (conn *Connection, err error) {
    conn = &Connection{
        WsConn:    wsConn,
        InChan:    make(chan []byte, 1000),
        OutChan:   make(chan []byte, 1000),
        CloseChan: make(chan byte, 1),
    }
    //读协程
    go conn.ReadLoop()
    //写协程
    go conn.WriteLoop()
    return
}
 
func (conn *Connection) ReadMess() (data []byte, err error) {
    select {
    case data = <-conn.InChan:
    case <-conn.CloseChan:
        err = errors.New("connection is closed")
    }
    return
}
 
func (conn *Connection) WriteMes(data []byte) (err error) {
    select {
    case conn.OutChan <- data:
    case <-conn.CloseChan:
        err = errors.New("connection is closed")
    }
    return
}
 
func (conn *Connection) Close() {
    conn.WsConn.Close() //本身线程安全,可重入
    //加锁,只能执行一次
    conn.Mutex.Lock()
    if !conn.IsClosed {
        close(conn.CloseChan)
        conn.IsClosed = true
    }
}
 
//具体实现读消息
func (conn *Connection) ReadLoop() {
    var (
        data []byte
        err  error
    )
    for {
        if _, data, err = conn.WsConn.ReadMessage(); err != nil {
            goto ERR
        }
        select {
        case conn.InChan <- data:
        case <-conn.CloseChan:
            goto ERR
        }
    }
ERR:
    conn.Close()
}
 
//具体实现写消息
func (conn *Connection) WriteLoop() {
    var (
        data models.BayDataS
        err  error
    )
    for {
        select {
        case data = <-conn.OutChan:
        case <-conn.CloseChan:
            goto ERR
        }
        if err = conn.WsConn.WriteMessage(websocket.TextMessage, data); err != nil {
            goto ERR
        }
    }
ERR:
    conn.Close()
}

JavaScript使用Websocket


<script>
  function WebSocketTest() {
    if ("WebSocket" in window) {
      alert("您的浏览器支持 WebSocket!");

      // 打开一个 web socket
      var ws = new WebSocket("ws://localhost:8080/");

      ws.onopen = function () {
        // Web Socket 已连接上,使用 send() 方法发送数据
        ws.send(`{"Data":"sadddddddddd"}`);
      };

      ws.onmessage = function (evt) {
        var received_msg = evt.data;
        console.log(received_msg)
      };

      ws.onclose = function () {
        // 关闭 websocket
        alert("连接已关闭...");
      };
      
    }else {
      // 浏览器不支持 WebSocket
      alert("您的浏览器不支持 WebSocket!");
    }
  }

  WebSocketTest()
</script>

webScoket测试工具

https://www.52bd.net/usr/uploads/2020/04/751993603.html

2020-04-28T07:47:20.png
WebSocketTest.html


微信小程序怎么使用websocket


    let _this = this
    //创建websocket 连接
    let wxWebsocket = wx.connectSocket({
      url: 'ws://127.0.0.1:8080/',
      header:{
        'content-type': 'application/json',
      },
      timeout:5000,//超时时间,单位为毫秒
      success:(e)=>{//接口调用成功的回调函数
        console.log(e)
      },
      fail:(e)=>{//接口调用失败的回调函数
        console.log(e)
      },
      complete:(e)=>{//接口调用结束的回调函数(调用成功、失败都会执行)
        console.log(e)
      }
    })

    //接受消息
    wxWebsocket.onMessage((e) =>{
      console.log(e)
      _this.setData({
        testWebsocket:JSON.parse(e.data).data
      })
    })

    //监听 WebSocket 连接关闭事件
    wxWebsocket.onClose((e) =>{

    })

    //监听 WebSocket 错误事件
    wxWebsocket.onError((e) =>{

    })

    //连接打开事件
    wxWebsocket.onOpen(()=>{
      wxWebsocket.send({
        data:`{"Data":"我发送消息给你"}`,//需要发送的内容
        success:(e)=>{//接口调用成功的回调函数
          console.log(e)
        },
        fail:(e)=>{//接口调用失败的回调函数
          console.log(e)
        },
        complete:(e)=>{//接口调用结束的回调函数(调用成功、失败都会执行)
          console.log(e)
        }
      })
    })

    wxWebsocket.close({
      code:1000,//一个数字值表示关闭连接的状态号,表示连接被关闭的原因。1000(表示正常关闭连接)
      reason:"",//一个可读的字符串,表示连接被关闭的原因。这个字符串必须是不长于 123 字节的 UTF-8 文本(不是字符)。
      success:(e)=>{//接口调用成功的回调函数
        console.log(e)
      },
      fail:(e)=>{//接口调用失败的回调函数
        console.log(e)
      },
      complete:(e)=>{//接口调用结束的回调函数(调用成功、失败都会执行)
        console.log(e)
      }
    })

ant design pro 怎么使用websocket 推送消息


namespace: 'global',

state: {
  collapsed: false,
  notices: [],
},

reducers: {
     saveNoticesWebsock(state, { payload }): GlobalModelState {//此处可以根据自己的业务写
      let dd=[...payload,...state.notices];
      console.log(dd,"saveNoticesWebsock")
      return {
        collapsed: false,
        ...state,
        notices: dd,
      };
    },
},

subscriptions: {
    setup({ dispatch,history }): void {
      
      // Subscribe history(url) change, trigger `load` action if pathname is `/`
      history.listen(({ pathname, search }): void => {
        if (typeof window.ga !== 'undefined') {
          window.ga('send', 'pageview', pathname + search);
        }
        if (!pathname.indexOf('/welcome')) {
          const ws = new WebSocket('ws://127.0.0.1:1234/websocket');
          ws.onmessage = function(msg) { 
            console.log('接收服务端发过来的消息', msg); 
            // result += msg.data + '\n'; 
            dispatch({
              type: 'saveNoticesWebsock', 
              payload: JSON.parse(msg.data),
            });
          }; 
          ws.onclose = function (e) {
              console.log('ws 连接关闭了');
          }
        }
      });
    }
  },