IqOahz 2020-08-17 11:12 采纳率: 66.7%
浏览 102
已采纳

Go语言 websocket 一个端口建立多个连接会频繁断开

建立websocket连接的URL: <code>var url = "ws://" + window.location.host + "/dev_ws?id=" + mac();</code>


下面是Go语言的发送心跳消息的代码


```

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

}

```


<br>


本机(192.168.1.182)通过如下URL建立websocket连接的时候, 前端接收心跳正常(20秒一次),连接正常

<code>URL: ws://192.168.1.182:27017/dev_ws?id=F460E249E981</code>

![image.png](/img/bVbLkAP)


<br>


本机(192.168.1.182)/本机和其他设备(192.168.1.108) &nbsp;同一时段通过如下两个URL建立websocket连接的时候, 前端接收心跳正常(20秒一次),连接都正常

<code>URL: ws://192.168.1.182:27017/dev_ws?id=F460E249E981</code>

<code>URL: ws://192.168.1.182:27017/dev_ws?id=ECA86B96E961</code>


<br>


本机(192.168.1.182)和其他设备(192.168.1.108) &nbsp;同一时段通过同一个URL建立websocket连接的时候

<code>URL: ws://192.168.1.182:27017/dev_ws?id=F460E249E981</code>

前端接收心跳频率变快

![image](/img/bVbLoTx)

频繁重连(ip是108和182)

![image.png](/img/bVbLkOQ)




前端js重连机制

```

var timeoutId = "";

function sundyn_ws_check() {

  if(timeoutId != ""){

    clearTimeout(timeoutId);

  }

  timeoutId = setTimeout(function (){ 

    app.RetryConn();

  }, 30000);

}

```


我刚开始做这块, 我还不太懂, 我感觉可能是<Code>websocket.Message.Send(d.ws, str)</Code>的问题, 不同设备连接同一个URL会影响消息的发送,只会给后连接的发送心跳消息, 导致前一个接收不到心跳重连


<br>


帮忙解答一下, 是哪出的问题及怎么解决

万分感谢!



<br><br><br><br>

需要更多代码往下看


js:

```

function main() {

  if (!window["WebSocket"]) {

    alert("您的浏览器不支持 WebSocket, 程序无法正常运行!!!");

    return

  }

  setmousedown();

  var url = "ws://" + window.location.host + "/dev_ws?id=" + mac();

  createWS(url);

}


//心跳重连

var timeoutId = "";

function sundyn_ws_check() {

  if(timeoutId != ""){

    clearTimeout(timeoutId);

  }

  timeoutId = setTimeout(function (){ 

    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;

}


function createWS(url) {

  console.log("准备连接" + url);

  var 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();

```


<br>

处理websocket连接的代码:

```

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

```

<br>


```

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 连接断开")


}

```


  • 写回答

2条回答 默认 最新

  • 浴火_凤凰 2020-08-17 11:55
    关注

    理论上不会,我记得websocket不是通过URL区分的

    他们俩虽然使用了同一个URL 但是来源的ip和端口 都不一样。

    服务器应该能区分开,你检查一下代码吧 看看收到消息之后 应该会有保存链接的代码

    这部分代码 是不是导致后来的链接把先到的链接覆盖了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 vhdl+MODELSIM
  • ¥20 simulink中怎么使用solve函数?
  • ¥30 dspbuilder中使用signalcompiler时报错Error during compilation: Fitter failed,求解决办法
  • ¥15 gwas 分析-数据质控之过滤稀有突变中出现的问题
  • ¥15 没有注册类 (异常来自 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
  • ¥15 知识蒸馏实战博客问题
  • ¥15 用PLC设计纸袋糊底机送料系统
  • ¥15 simulink仿真中dtc控制永磁同步电机如何控制开关频率
  • ¥15 用C语言输入方程怎么
  • ¥15 网站显示不安全连接问题