1、maven项目,第一步需要配置jar包

org.springframework.boot

spring-boot-starter-websocket

2、前台使用

var websocket = null;

//判断当前浏览器是否支持WebSocket

if('WebSocket' in window){

//连接WebSocket节点

websocket = new WebSocket("ws://localhost:81/api/imserver/"+用户id;);

}else{

console.log("您的浏览器不支持WebSocket");

}

//连接发生错误的回调方法

websocket.onerror = function(){

};

//连接成功建立的回调方法

websocket.onopen = function(event){

}

//接收到消息的回调方法

websocket.onmessage = function(event){

setMessageInnerHTML(event.data);

}

//连接关闭的回调方法

websocket.onclose = function(){

}

//发送消息

function send(){

var message = document.getElementById('text').value;

websocket.send(message);

}

窗口关闭或者退出登录时调用,如果挂掉需要重新请求

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。

window.onbeforeunload = function(){

websocket.close();

}

前台检测后台是否挂掉

//针对断网的情况的心跳重连

var heartCheck = {

timeout: 20000,//20ms

timeoutObj: null,

reset: function( ){

clearTimeout(this.timeoutObj);

  this.start();

},

start: function( ){

this.timeoutObj = setTimeout(function(){

websocket.send("HeartBeat"); //自定义需要执行的命令

}, this.timeout)

}

};

heartCheck.start();

heartCheck.reset();

//将消息显示在网页上

function setMessageInnerHTML(innerHTML){

document.getElementById('message').innerHTML += innerHTML + '
';

}

3、后台使用

新建WebSocketConfig 类

@Configuration

public class WebSocketConfig {

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

}

新建WebSocketServer类

@ServerEndpoint(value="/imserver/{userId}")

@Component

public class WebSocketServer {

private final static Logger log = LoggerFactory.getLogger(WebSocketServer.class);

/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/

private static int onlineCount = 0;

/**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/

private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();

/**与某个客户端的连接会话,需要通过它来给客户端发送数据*/

private Session session;

/**接收userId*/

private String userId="";

/**

* 连接建立成功调用的方法

**/

@OnOpen

public void onOpen(Session session,@PathParam("userId") String userId) {

this.session = session;

this.userId=userId;

if(webSocketMap.containsKey(userId)){

webSocketMap.remove(userId);

webSocketMap.put(userId,this);

//加入set中

}else{

webSocketMap.put(userId,this);

//加入set中

addOnlineCount();

//在线数加1

}

log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());

try {

sendMessage("");

} catch (IOException e) {

log.error("用户:"+userId+",网络异常!!!!!!");

}

}

/**

* 连接关闭调用的方法

*/

@OnClose

public void onClose() {

if(webSocketMap.containsKey(userId)){

webSocketMap.remove(userId);

//从set中删除

subOnlineCount();

}

log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());

}

/**

* 收到客户端消息后调用的方法

*

* @param message 客户端发送过来的消息*/

@OnMessage

public void onMessage(String message, Session session) {

//log.info("用户消息:"+userId+",报文:"+message);

//可以群发消息

//消息保存到数据库、redis

if(StringUtils.isNotBlank(message)){

try {

if("ping".equals(message)) {

webSocketMap.get(userId).sendMessage("pong");

}else {

//解析发送的报文

JSONObject jsonObject = JSON.parseObject(message);

//追加发送人(防止串改)

jsonObject.put("fromUserId",this.userId);

String toUserId=jsonObject.getString("toUserId");

//传送给对应toUserId用户的websocket

if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){

webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());

}else{

log.error("请求的userId:"+toUserId+"不在该服务器上");

//否则不在这个服务器上,发送到mysql或者redis

}

}

}catch (Exception e){

e.printStackTrace();

}

}

}

/**

* 用户错误

* @param session

* @param error

*/

@OnError

public void onError(Session session, Throwable error) {

log.error("用户错误:"+this.userId+",原因:"+error.getMessage());

}

/**

* 实现服务器主动推送

*/

public void sendMessage(String message) throws IOException {

this.session.getBasicRemote().sendText(message);

}

/**

* 发送自定义消息

* */

public static void sendInfo(String message,@PathParam("userId") String userId) {

try {

log.info("发送消息到:"+userId+",报文:"+message);

if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){

webSocketMap.get(userId).sendMessage(message);

}else{

log.error("用户"+userId+",不在线!");

}

} catch (Exception e) {

log.error("异常"+userId+",报文:"+message);

}

}

public static synchronized int getOnlineCount() {

return onlineCount;

}

public static synchronized void addOnlineCount() {

WebSocketServer.onlineCount++;

}

public static synchronized void subOnlineCount() {

WebSocketServer.onlineCount--;

}

}

后台使用时调用其发送方法,前台就可以收到,然后修改页面显示

WebSocketServer.sendInfo("",userid);

谢谢观看!!!

c# websocket 心跳重连_websocket的简单使用相关推荐

  1. java 心跳 断网重连_工作笔记5 - websocket心跳重连机制

    心跳重连缘由 在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开, 而浏览器不会执行websocket 的?onclos ...

  2. 【websocket前后端交互】vue-springboot实现websocket前后端交互链接,websocket心跳重连,包含前后端代码,复制即可用【详细解释版本】

    前言: 还是老规矩,一步步的教大家如何建立前后端的 websocket 链接,并能完成互相传送数据的简单功能.由于网上找了半天发现很多帖子都是东一句西一句的,要不就是写的没什么注释和解释,导致我这个前 ...

  3. c# websocket 心跳重连_初探和实现websocket心跳重连(npm: websocket-heartbeat-js) - 子慕大诗人 - 博客园...

    (event) { heartCheck.reset(); 如上代码,heartCheck 的 reset和start方法主要用来控制心跳的定时. 什么条件下执行心跳: 当onopen也就是连接成功后 ...

  4. websocket心跳链接代码_websocket心跳的实现(包括全部代码)

    本文主要讲的是如果设计websocket心跳已经需要考虑哪些问题. 前言 在使用websocket的过程中,有时候会遇到客户端网络关闭的情况,而这时候在服务端并没有触发onclose事件.这样会: 多 ...

  5. WebSocket心跳重连机制

    阅读本文章前请先了解WebSocket 场景 WebSocket在连接关闭的情况下会触发onclose事件,在链接异常的情况下会触发onerror事件.而在弱网条件下,onclose事件触发的灵敏度却 ...

  6. websocket心跳链接代码_WebSocket原理与实践(五)--心跳及重连机制

    在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失.所以就需要 ...

  7. socket心跳机制图片_WebSocket心跳检测和重连机制

    1. 心跳重连原由 心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生. websocket连接断开有以下两种情况: 前端断开 在使用websocket过程中,可能会出现网络断 ...

  8. Websocket心跳检测、重连机制

    前言 为了获取实时数据,前端需要和后端保持通信,HTTP 协议只能是客户端向服务器发出请求,服务器返回查询结果.这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦.我们只能使 ...

  9. C语言socket重连和心跳,c# socket 心跳 重连

    /// /// 检查一个Socket是否可连接 /// /// /// private bool IsConnected(Socket socket) { if (socket == null || ...

最新文章

  1. 有关GetPrivateProfileString的使用方法
  2. Openstack组件部署 — Keystone功能介绍与认证实现流程
  3. 013_html水平线
  4. html3d样式,CSS+HTML3D文字效果
  5. 数据科学竞赛-自然语言处理赛流程
  6. 查询在具有最小内存容量的所有PC中具有最快处理器的PC制造商 (20 分)(两种思路+详解)
  7. java 异步处理数据格式_spring mvc对异步请求的处理
  8. WebRequest msdn整理
  9. python是如何进行内存管理的_Python是如何进行内存管理的?
  10. js数组再倒数第二个添加元素_js 循环对象数组将元素逐个添加至新数组问题
  11. 《计算机组成原理》----第1章 计算机系统体系结构 1.1 什么是计算机系统体系结构...
  12. WPS加载项部署运行问题排查方法
  13. 信息系统安全等级保护 备案表
  14. 面向对象:结构化开发方法和面向对象开发方法
  15. 十进制 二进制 十六进制 八进制
  16. 计算机科班生学计算机组成原理的意义何在呢?
  17. 凌晨3点不回家:因为想不到的心酸!
  18. 古剑奇谭2打砺罂10分钟过的方法!
  19. High Dynamic Range(HDR)图像介绍(一)
  20. 竞品分析:小宇宙APP——如何在播客领域站住脚?

热门文章

  1. MyBatis设计模式总结
  2. IDEA 集成Lombok 插件-安装插件
  3. 消费者广播模式和负载均衡模式
  4. Base64编码 - Java加密与安全
  5. oracle字段重复新增错误,Oracle 判断表或字段是否存在新增/修改表结构可重复执行sql...
  6. mysql 字符大对象_第02期:MySQL 数据类型的艺术 - 大对象字段
  7. MySQL之性能优化解说
  8. Servlet的第一个程序HelloWorld
  9. java中定时器的使用
  10. ng-options track by 思考