• 5
  • 新人请关照

webSocket 频繁断开

生产环境中 websocket 频繁触发重连机制

image.png

本地运行没有问题, 感觉可能是网络原因

问:
如果是断网导致连接断开, 是不是就应该快速重连?

如果不是, 那又可能是哪的原因...?





下面是代码

js代码:

var will_exit = 0;
var last_time_check_ws;

function main() {
    if (!window["WebSocket"]) {
        alert("您的浏览器不支持 WebSocket, 程序无法正常运行!!!");
        return
    }
    setmousedown();
    var url = "ws://" + window.location.host + "/dev_ws?id=" + mac();
    createWS(url);
}
//断线重连
function sundyn_ws_check(s) {
    var obj = eval('(' + s + ')');
    if ("time" in obj) {        
        last_time_check_ws = new Date().getTime();
        setTimeout(function () {
            if ((new Date().getTime() - last_time_check_ws) > 25000) {
                app.RetryConn();
            }
        }, 30000);
    }
}

function mac() {
    var s = window.location.toString();
    s = s.substr(s.indexOf("/devices/") + 9);
    s = s.substr(0, s.indexOf("/"));
    return s;
}

var socket;
function createWS(url) {
    console.log("准备连接" + url);
    socket = new WebSocket(url);

    socket.onclose = function () {
        console.log("连接被断开");
        //重连
        app.RetryConn();
    };

    socket.onopen = function () {
        console.log("已连接");
        app.CaptureScr();
    };

    socket.onerror = function (e) {
        console.log("error:" + e);
    };

    socket.onmessage = function (e) {
        console.log("get json:" + e.data);
        var obj = eval('(' + e.data + ')');

        if (!("eventType" in obj)) {
            console.log("未找到 eventType, 该json格式不受支持");
            return
        }

        var s = obj.eventType;
        var jh = e.data + "";
        s = s + "('" + jh + "')";
        eval(s);
    };
}

main();


处理websocket请求的代码:

http.Handle("/dev_ws", websocket.Handler(DeviceRequestProc))


处理websocket连接的代码:

func DeviceRequestProc(ws *websocket.Conn) {
    defer ws.Close()
    defer ws.Request().Body.Close()
    _ = ws.Request().ParseForm()
    mac := ws.Request().Form.Get("id")
    log.Println("设备", ws.Request().RemoteAddr, "[", mac, "] websocket 连接建立")

    dev := devInfo.getDeviceByMac(mac)
    if dev == nil {
        _ = websocket.Message.Send(ws, "未找到对应设备配置")
        log.Println("设备", ws.Request().RemoteAddr, "[", mac, "] websocket 连接未找到对应设备")
        return
    }
    dev.online = true
    dev.ws = ws
    //发送心跳消息
    dev.WSCheck()

    reply := ""
    for {
        //此处阻塞,等待有数据可读
        err := websocket.Message.Receive(ws, &reply)
        if  err != nil {
            break
        }
        dev.ProcessWSMsg(reply)
    }
    dev.online = false
    dev.ws = nil
    log.Println("设备", ws.Request().RemoteAddr, "[",ws.Request().Form.Get("id"),"] websocket 连接断开")

}


发送心跳消息的代码:

func (d *Device) WSCheck() {
    //go func() { }() 以并发的方式调用匿名函数funcx
    go func() {
        for d.online {
            d.WebsocketSendString(fmt.Sprintf(`{"eventType":"sundyn_ws_check","time":"%s"}`,
                  time.Now().Format("2006-01-02 15:04:05")))
            time.Sleep(time.Second * 20)
        }
    }()
}

// 通过 WebSocket 发送字符串
func (d *Device) WebsocketSendString(str string) bool {
    if !d.online {
        return false
    }
    log.Println(d.ws.Request().RemoteAddr)
    if err := websocket.Message.Send(d.ws, str); err != nil {
        log.Println("设备", d.ws.Request().RemoteAddr,
            "[",d.ws.Request().Form.Get("id"),"] websocket 发送消息失败:%s", err)
        _ = d.ws.Close()
        return false
    }
    return true
}
阅读 269
评论
    0 个回答
    撰写回答

    登录后参与交流、获取后续更新提醒

    相似问题
    推荐文章