我的前一篇文章“webSocket如何在自己的工程中使用?”

地址:https://blog.csdn.net/jintingbo/article/details/80755636

讲述了webSocket的初级使用,初学者可以先看看那篇文章。

本文主要是解决webSocket自动关闭。

websocket它有一个“心跳”机制,但这个心跳机制是要程序自己去写代码实现的,websocket本身没有给你做这个东西。

它是如何自动关闭的呢?当电脑浏览器发送pong帧的时候,由于内容为空,于是服务器将空内容转发回去,导致客户端浏览器以为是错误的帧类型,发送关闭信息进行error关闭。(服务器返回时,必须要把它原来发来的东西发回去的,这是TCP/IP协议的要求)。

即然服务器接收到浏览器发送的"pong"后如果回复一个“pong”时,它会结束连接,那么为了避免这种事发生,可以在服务器接收到一个“pong”空信息时,不回复它的"pong",也就不关闭连接了。这是一种解决方案。

另一种解决方案是:当发生关闭时,可以主动发送心跳给对方,让连接复活,这样就相当于不断线了。本文就是用这个方案实现的。

第一步:在html文件中加入:
-----------------------------

<script type="text/javascript">
var ws;
//避免重复连接
var lockReconnect = false;
var wsUrl = "ws://localhost:8080/cl-market-camera-web/websocket";
createWebSocket(wsUrl);
function createWebSocket(url) {
try {
ws = new WebSocket(url);
initEventHandle();
} catch (e) {
                        //重新连接
reconnect(url);
}
}
        //封装websocket的那几个接口函数
function initEventHandle() {
ws.onclose = function () {
console.info("连接关闭");
reconnect(wsUrl);
};
ws.onerror = function () {
console.info("传输异常");
reconnect(wsUrl);
};
ws.onopen = function () {
//心跳检测重置
heartCheck.reset().start();
};

websocket.onmessage = function(event) {
                    //console.info(event.data);

setMessageInnerHTML(event.data);
//如果获取到消息,心跳检测重置
heartCheck.reset().start();

}
}
function reconnect(url) {
if(lockReconnect) return;
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () {
    console.info("尝试重连..." + new Date().format("yyyy-MM-dd hh:mm:ss"));
    createWebSocket(url);
    lockReconnect = false;
}, 5000);
}
//心跳检测,每5s心跳一次
var heartCheck = {
timeout: 5000,
timeoutObj: null,
serverTimeoutObj: null,
reset: function(){
    clearTimeout(this.timeoutObj);
    clearTimeout(this.serverTimeoutObj);
    return this;
        },
start: function(){
    var self = this;
    this.timeoutObj = setTimeout(function(){
        //这里发送一个心跳,后端收到后,返回一个心跳消息,
        //onmessage拿到返回的心跳就说明连接正常
        ws.send("HeartBeat" + new Date().format("yyyy-MM-dd hh:mm:ss"));
                console.info("客户端发送心跳:" + new Date().format("yyyy-MM-dd hh:mm:ss"));

self.serverTimeoutObj = setTimeout(function(){
                            //如果超过一定时间还没重置,说明后端主动断开了

ws.close();
                            //如果onclose会执行reconnect,我们执行ws.close()就行了.
//如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
}
}

//js中格式化日期,调用的时候直接:new Date().format("yyyy-MM-dd hh:mm:ss")
Date.prototype.format = function(fmt) {
var o = {
    "M+" : this.getMonth()+1,                 //月份 
    "d+" : this.getDate(),                    //日 
    "h+" : this.getHours(),                   //小时 
    "m+" : this.getMinutes(),                 //分 
    "s+" : this.getSeconds(),                 //秒 
    "q+" : Math.floor((this.getMonth()+3)/3), //季度
    "S"  : this.getMilliseconds()             //毫秒 
        }; 
        if(/(y+)/.test(fmt)) {

fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));

}

for(var k in o) {
    if(new RegExp("("+ k +")").test(fmt)){
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
            }
                }
        return fmt; 
        }
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
</script>

第二步:在java的controller包中写一个WebSocketTest类
------------------------------
package com.clmarket.controller;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/websocket")
public class WebSocketTest {
        //设置连接数
private static int onlineCount = 0;
private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = 
new CopyOnWriteArraySet<WebSocketTest>();
private Session session;
public Session getSession(){
return this.session;
}
@OnOpen
public void onOpen(Session session){
this.session = session;
webSocketSet.add(this);     //加入set中
addOnlineCount();           //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
@OnClose
public void onClose(){
webSocketSet.remove(this);  //从set中删除
subOnlineCount();           //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 服务器向浏览器发送消息
* @param message 需要推送到浏览器的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
for(WebSocketTest item: webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}

/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}

public static synchronized void addOnlineCount() {
WebSocketTest.onlineCount++;
}

public static synchronized void subOnlineCount() {
WebSocketTest.onlineCount--;
}

}

第三步:如何把自己的信息借助上面的WebSocketTest类推送出去
-----------------------------

比如服务器有一个字符串“鄂H AAAAA8”这样的字符串,要把它推到浏览器里显示出来,

其实只要三句话搞定:

String license=“鄂H AAAAA8”;

//new一个WebSocketTest对象,表示我要用它来发送
WebSocketTest wst=new WebSocketTest();
//这个session实际上是import javax.websocket.Session;
Session session=wst.getSession();
//调用这个webSocketTest对象的onMessage就可以把license发送出去了。
wst.onMessage(license, session);

全文完:湖北荆门金庭波 QQ:14280784

webSocket如何解决自动关闭的意思相关推荐

  1. python3 实现 websocket server 解决中文乱码

    pip install websocket-client 原文:https://www.cnblogs.com/wangqj1996/p/9244601.html 一.什么是websocket Web ...

  2. python websocket server 解决中文乱码

    参考:https://www.cnblogs.com/wangqj1996/p/9244601.html 一.什么是websocket WebSocket是HTML5开始提供的一种在单个 TCP 连接 ...

  3. websocket没准备好如何解决_那些很重要,但是不常用的技术,websocket

    目录 1. 为什么会有websocket 2. websocket协议格式 3. 协议具体实现 一.为什么需要 WebSocket? 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 ...

  4. websocket没准备好如何解决_看完让你彻底搞懂Websocket原理

    偶然在知乎上看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇回帖让我对 websocket 的认识深刻有木有.所以转到我博客里,分享一下.比较喜欢看这种博客,读起来很轻松,不枯燥,没有布道师的阵仗 ...

  5. WebSocket 集群解决方案

    欢迎关注方志朋的博客,回复"666"获面试宝典 问题起因 最近做项目时遇到了需要多用户之间通信的问题,涉及到了WebSocket握手请求,以及集群中WebSocket Sessio ...

  6. 分布式 WebSocket 集群解决方案

    作者 | weixin_34194702 来源 | blog.csdn.net/weixin_34194702/article/details/88701309 问题起因 最近做项目时遇到了需要多用户 ...

  7. 【微信小程序开发•系列文章七】websocket

    2019独角兽企业重金招聘Python工程师标准>>> 为什么需要websocket? 传统的实时交互的游戏,或服务器主动发送消息的行为(如推送服务),如果想做在微信上,可能你会使用 ...

  8. 微信小程序之WebSocket

     (扫码带走看 ^ ^) 本文版权归 OSChina jsongo0 所有,此处为技术收藏,如有再转请自觉标明原文出处,这是大家对原创作者劳动成果的自觉尊重! 原文地址:https://my.osch ...

  9. WebSocket集群解决方案

    一.问题起因 最近做项目时遇到了需要多用户之间通信的问题,涉及到了WebSocket握手请求,以及集群中WebSocket Session共享的问题. 期间我经过了几天的研究,总结出了几个实现分布式W ...

最新文章

  1. python模块化设计耦合度_什么是程序设计中的高内聚、低耦合?
  2. IDEA打包成可执行的JAR包
  3. java取主机的网卡物理地址
  4. Mysql的存储过程修改表的数据:项目上一个小练习
  5. 做个高颜值的优秀按钮,用 CSS3 实现社交按钮动画
  6. Qt文档阅读笔记-void QObject::deleteLater()解析
  7. 清除zend studio10.5中的内置浏览器中的历史记录
  8. 35. 第一个只出现一次的字符(C++版本)
  9. 【算法原理+洛谷P6114+HDU6761】Lyndon分解
  10. MATLAB-多目标线性规划问题
  11. 数据库update多条数据
  12. SpringBoot集成EasyUI
  13. PyG自定义数据集学习笔记(持续更新
  14. 服务器过载保护(上篇)——过载介绍
  15. Linux打开21端口
  16. Python中“xx+=xx”与“xx=xx+xx”的区别
  17. 杠杆炒股中洗盘是什么?
  18. 培训班出来的人后来都怎么样了?(六)
  19. mac系统常用操作指南
  20. 职场写作(二)常见职场写作场景——周报

热门文章

  1. 用电脑回收站的数据保护机制:理解python类成员保护和访问限制,及编程思想
  2. 广东省英语听说计算机考试时间,广东2018英语听说考试3月17-19日进行
  3. 三大互联网巨头抢购高德软件 阿里巴巴胜算最大
  4. 天冷保暖妙招,怎么样穿的少也暖和
  5. 人类历史上首次,完全无人的谷歌无人车上路了!
  6. 淘宝拍立淘图片搜索API
  7. 【Cocos2d-x】Cocos2d-x精灵的性能优化
  8. 神秘SHEIN,一个千亿美元公司复合式创新的故事
  9. 思博伦Spirent Testcenter交换机性能测试主要技术指标_丢帧率/吞吐量/转发速率之间的关系_双极未来
  10. box2d 服务器性能,Box2d预览