SpringBoot建立websocket连接

介绍

WebSocket 协议是一种基于TCP的协议,用于在客户端和服务器之间建立持久连接,并且可以在这个连接上实时地交换数据。WebSocket协议有自己的握手协议,用于建立连接,也有自己的数据传输格式。

当客户端发送一个 WebSocket 请求时,服务器将发送一个协议响应以确认请求。在握手期间,客户端和服务器将协商使用的协议版本、支持的子协议、支持的扩展选项等。一旦握手完成,连接将保持打开状态,客户端和服务器就可以在连接上实时地传递数据。

WebSocket 协议使用的是双向数据传输,即客户端和服务器都可以在任意时间向对方发送数据,而不需要等待对方的请求。它支持二进制数据和文本数据,可以自由地在它们之间进行转换。

总之,WebSocket协议是一种可靠的、高效的、双向的、持久的通信协议,它适用于需要实时通信的Web应用程序,如在线游戏、实时聊天等。

使用

导入依赖

        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.5.2</version>
        </dependency>

工具一

package com.seekgenjs.position.util;


import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;


@SuppressWarnings("all")
@Component
public class WebSocketClient {

    Logger logger = LoggerFactory.getLogger(WebSocketClient.class);


    private final String URI = "wss://xxxx/wss";
    private final String User_Name = "xxx";
    private final String Act_Login = "xxx";
    private final String Act_Device = "xxxx";

    @Resource
    MyWebSocketClient myWebSocketClient;


    //项目启动建立连接
    @PostConstruct
    public void init() {

        try {
            URI uri = new URI(URI);
            org.java_websocket.client.WebSocketClient client = new org.java_websocket.client.WebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake hand) {

                    logger.debug("{}_Connected to WebSocket server", URI);

                    send(login());

                    timer();

                }

                private void timer() {
                    // Send heartbeat packet every 30 seconds
                    logger.debug("{}_开始执行定时任务,Send heartbeat packet every 30 seconds", System.currentTimeMillis());

                    Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            try {
                                //发送心跳的业务代码
                                send(sendHeartbeat());
                            } catch (Exception e) {
                                //print the error log
                                e.printStackTrace();
                            }

                        }
                    }, 1000L * 3, 1000L * 25);
                }

                @Override
                public void onMessage(String message) {
                    System.out.println(message);
                    handleMessage(message);
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    System.out.println("Connection closed");
                    logger.debug("{}_Connection closed", System.currentTimeMillis());
                }

                @Override
                public void onError(Exception ex) {
                    ex.printStackTrace();
                }

            };
            client.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }


    //登录
    private String login() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("act", Act_Login);
        map.put("user_name", User_Name);
        map.put("access_token", myWebSocketClient.getToken());
        return JSON.toJSONString(map);

    }

    //心跳包
    private String sendHeartbeat() {
        logger.debug("{}_Send heartbeat packet", System.currentTimeMillis());
        HashMap<String, Object> map = new HashMap<>();
        map.put("act", Act_Device);
        return JSON.toJSONString(map);
    }


    /**
     * 处理接收数据
     *
     * @param message
     */
    public void handleMessage(String message) {
        System.out.println("{}_Received message: " + message);
       
    }


}

工具二

package com.seekgenjs.position.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seekgenjs.common.core.domain.R;
import com.seekgenjs.common.utils.DateUtils;
import com.seekgenjs.common.utils.JsonUtils;
import com.seekgenjs.common.utils.StringUtils;
import com.seekgenjs.common.utils.Threads;
import com.seekgenjs.common.utils.redis.RedisUtils;
import com.seekgenjs.mine.clinentVo.EquipmentInfo;
import com.seekgenjs.mqtt.MqttClientService;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

@SuppressWarnings("all")
@Component
public class HeartbeatWebSocketClient {
    Logger logger = LoggerFactory.getLogger(HeartbeatWebSocketClient.class);
    private boolean isClosed;
    private Timer heartbeatTimer;
    private WebSocketClient client;
    @Resource
    private WssCacheToken cacheToken;
   



    public WebSocketClient init() throws Exception {
        WebSocketClient client = new org.java_websocket.client.WebSocketClient(
            new URI(WssConstant.WSS_URI)) {
            @Override
            public void onOpen(ServerHandshake serverHandshake) {
                // 连接成功后 --执行登录操作 --发送心跳消息
                send(login());
            }
            @Override
            public void onMessage(String s) {
               handleMessage(s);
            }
            @Override
            public void onClose(int i, String s, boolean b) {
                logger.error("{}:Connection closed", DateUtils.getTime());
                // 连接关闭,停止心跳定时器
                stopHeartbeat();
                isClosed = true;
                //重连
                reconnection();
            }

            @Override
            public void onError(Exception e) {
                logger.error("{}:Connection error,reason:{}", DateUtils.getTime(),e.getMessage());
               stopHeartbeat();
            }
        };
        client.connect();
        Threads.sleep(1000);
        // 启动心跳定时器
        startHeartbeat(client);
        return client;
    }


    /**
     * 断开重连
     * 重试5次为未连接上,等待半小时
     * @throws Exception
     * @return
     */
    public synchronized WebSocketClient reconnection(){
        int i = 5;
        WebSocketClient wsc = null;
        while (i<5 && wsc!=null && !wsc.isOpen()){
            i++;
            try {
                WebSocketClient oldClient = this.client;
                if (null != oldClient) {
                    oldClient.close();
                    logger.info("关闭旧的websocket连接");
                }
                logger.info("打开新的websocket连接,并进行认证");
                WebSocketClient newClient = init();
                this.client = newClient;
                this.isClosed = false;
                wsc = newClient;
                // 启动心跳定时器
                startHeartbeat(newClient);
                //return newClient;
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
        Threads.sleep(1000*60*30);
        if (wsc==null){
            reconnection();
        }
        logger.info("重连成功");
        return wsc;
    }



    /**
     *  发送心跳包
     */
    @Async
    private void startHeartbeat(WebSocketClient socketClient) {
        // 启动心跳定时器,每隔30秒发送一条心跳消息
        this.heartbeatTimer = new Timer();
        this.heartbeatTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (!isClosed) {
                    logger.info("websocket向服务端发送消息,消息内容:{}", "heartbeat");
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("act", WssConstant.ACT_DEVICE);
                    socketClient.send(JSON.toJSONString(map));
                }
            }
        }, 3000, 3000);
    }

    /**
     * 停止心跳
     */
    private void stopHeartbeat() {
        // 停止心跳定时器
        if (this.heartbeatTimer != null) {
            this.heartbeatTimer.cancel();
            this.heartbeatTimer = null;
        }
    }

    /**
     * 登录
     * @return
     */
    private String login() {
        logger.info("{}:wss 登录", DateUtils.getTime());
        HashMap<String, Object> map = new HashMap<>();
        map.put("act", WssConstant.ACT_LOGIN);
        map.put("user_name", WssConstant.USER_NAME);
        map.put("access_token", "token");
        return JSON.toJSONString(map);
    }
    /**
     * 处理接收数据
     *
     * @param message
     */
    public void handleMessage(String message) {
        
    }
   

}

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值