React中WebSocket使用以及服务端崩溃重连

我这是即时通知推送,服务端用的node中间件:

完整版demo 请狠狠的点这里 http://download.lllomh.com/cliect/#/product/JB06452810852671

创建 node端  index.js, node index.js  执行

我这是 去拿 接口的数据再转发给前端

var ws = require('nodejs-websocket');
var Axios =require('axios')
var server = ws.createServer(function(socket){
    try {
        // 事件名称为text(读取字符串时,就叫做text),读取客户端传来的字符串
        var count = 1;
        const token = '4jktytkUXJlvMurzs7nuE2M51b4hysvQ';
        socket.on('text', function(str) {
            // 在控制台输出前端传来的消息
            let tokens = JSON.parse(str)  
            Axios.post("http://127.0.0.1/api/api/?route=notice/check",
                {
                    'ws': 'send'
                },
                {
                    headers: {'Authorization':tokens.token}
                }
            ).then((res)=>{
                console.log(res.data)
                socket.sendText(JSON.stringify(res.data));    //向前端回复消息
            })
        });

        socket.on('error', function(code) { //一定要加异常处理的这个方法,不然前端刷新服务会崩掉
            console.log('异常关闭', code)
        })

    } catch(e) {
       console.log(e)
    }

}).listen(8185);

客户端发送数据以及断线重连:

定义方法:创建 ws 并复制全局

    constructor(props) {
        super(props);
        this.state={
            flag:false,
            webs:null,
            ws:{}
        }
    }

getNotiveCheck=()=>{
        // 打开一个 web socket 这里端口号和上面监听的需一致
     let webSockets = new WebSocket('ws://localhost:8185/');
      this.setState({
         ws:webSockets
       })

}

开始处理事件.正常如果服务器端服务重启 前端必须刷新才能继续链接.为了断线自动重连,.这里再链接成功之后,用flag变量标记:flag:true

也就是

          this.state.ws.onopen = ()=> {
                        this.setState({
                            flag:true
                        })
}

其实就是在触发服务器端服务关闭的时候

             this.state.ws.onclose = evt => {
                        console.log("webSocket连接关闭");
                        this.setState({
                            flag:false
                        })

                    };

以及在报错的时候

        this.state.ws.onerror = (evt,e) => {
                        this.setState({
                            flag:false
                        })
                        console.log(evt);
                    }

这里有个重点就是在 .onopne 中的发送的时候要判断一下 是 1  才发送,不然在报错的时候也发送会导致报错

     if(this.state.ws.readyState==1){
                                this.state.ws.send(prbles_str);
                            }

关闭的时候新建ws连接:

           this.state.ws.onclose = evt => {
                        console.log("webSocket连接关闭");
                        this.setState({
                            flag:false
                        },()=>{
                            if(!this.state.flag){
                                this.getNotiveCheck()
                            }else {
                                clearInterval(this.state.webs)
                            }
                        })

                    };

执行的时候用定时器:

    componentDidMount(){
        this.setState({
            webs:setInterval(()=>{
                if(!this.state.flag){
                    this.getNotiveCheck()
                }else {
                    clearInterval(this.state.webs)
                }
            },3000)
        })


    }

核心代码:

    constructor(props) {
        super(props);
        this.state={
            socket:null,
            flag:false,
            webs:null,
            ws:{}
        }
    }

   
 getNotiveCheck=()=>{

                    let token = localStorage.getItem('U_TOKEN')

                    // 打开一个 web socket 这里端口号和上面监听的需一致
                    let webSockets = new WebSocket('ws://localhost:8185/');
                    this.setState({
                        ws:webSockets,
                    })
                    // Web Socket 已连接上,使用 send() 方法发送数据
                    this.state.ws.onopen = ()=> {
                        this.setState({
                            flag:true
                        })
                        console.log('客户端(client):与服务器的连接已打开')
                        //          这里用一个延时器模拟事件
                        let cont=1;
                        setInterval(()=> {
                            let prbles={}
                            prbles.prble=cont+'probe'
                            prbles.token=token
                            let prbles_str=JSON.stringify(prbles)
                            console.log(prbles_str)
                            console.log(this.state.ws)
                            if(this.state.ws.readyState==1){
                                this.state.ws.send(prbles_str);
                            }
                            // ws.send(token);
                            cont++
                        },3000);
                    }

                    this.state.ws.onclose = evt => {
                        console.log("webSocket连接关闭");
                        this.setState({
                            flag:false
                        },()=>{
                            if(!this.state.flag){
                                this.getNotiveCheck()
                            }else {
                                clearInterval(this.state.webs)
                            }
                        })

                    };
                    // 这里接受服务器端发过来的消息
                    this.state.ws.onmessage = (e)=> {
                        let data=JSON.parse(e.data)
                        console.log(data) //处理事情
                       
                    }
                    this.state.ws.onerror = (evt,e) => {
                        this.setState({
                            flag:false
                        })
                        console.log(evt);
                    }
                }


            }

   
    }

    componentDidMount(){
        this.setState({
            webs:setInterval(()=>{
                if(!this.state.flag){
                    this.getNotiveCheck()
                }else {
                    clearInterval(this.state.webs)
                }
            },3000)
        })


    }

请求图:

当然,也还有更好的写法,请多多纠正啊

原文地址:https://www.cnblogs.com/lllomh/p/14478819.html