Java网络Socket编程-websocket

实现一个用于监测 WebSocket 连接状态的线程类,其作用是通过创建一个 WebSocket 客户端,连接到指定的 WebSocket 地址,并监测连接的状态。

代码中的 WebSocketThread 类继承自 Thread,意味着它可以在单独的线程中执行。该线程类使用 Tyrus 提供的 @ClientEndpoint 注解来标识这是一个 WebSocket 客户端端点。

在代码中,通过定义 @OnOpen@OnMessage@OnClose@OnError 注解的方法,来处理与 WebSocket 连接相关的事件。例如,在 onOpen 方法中,当连接成功建立时,会将 session 对象赋值,并重置重连次数。

通过调用 connect 方法,可以创建一个 WebSocket 客户端,并连接到指定的 WebSocket 地址。在连接过程中,会触发 @OnOpen 注解的方法。

run 方法中,循环执行连接和断开连接的操作。在每次连接成功后,使用一个内部循环来定时检查连接状态。如果超过设定的连接超时时间 connectTimeout,仍未收到消息或心跳,则认为连接已关闭,更新监控 WebSocket 的状态为 "CLOSE"。如果在超时时间内收到了消息或心跳,更新监控 WebSocket 的状态为 "OPEN"。

通过调用 close 方法,可以关闭 WebSocket 连接,并更新监控 WebSocket 的状态为 "CLOSE"。

代码中的 running 变量用于控制线程的运行状态,当调用 stopThread 方法时,将设置 runningfalse,从而终止线程的执行。

此线程在连接断开后会尝试重新连接,并通过计数器 reconnectTimes 控制重连次数和心跳间隔。在每次重连时,会等待一段时间后再次尝试连接。每次重连后都会检查连接状态并更新监控 WebSocket 的状态。

请注意,该代码片段中使用了一些自定义的类和接口,例如 IMonWebsocketService,这些类和接口在代码中没有给出具体实现。因此,要使代码正常运行,需要确保相关的类和接口已经正确实现,并且适配于你的应用程序环境

import org.glassfish.tyrus.client.ClientManager;

import javax.websocket.*;
import java.net.URI;
@ClientEndpoint
public class WebSocketThread extends Thread{


    private Session session;


    private volatile boolean running = true;



    private Long websocketId;
    private String websocketUrl;
    private Integer connectTimeout; // 重连延迟,单位:毫秒
    private String msg;

    private IMonWebsocketService monWebsocketService;

    private String status = "";

    private volatile Integer reconnectTimes = 0;


    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        //System.out.println("WebSocket 连接已打开");
        reconnectTimes = 0;
    }

    @OnMessage
    public void onMessage(String message) {
        //System.out.println("接收到消息: " + message);
        if(StringUtils.isBlank(msg)||"#".equals(msg)){
            reconnectTimes = 0;
        }else{
            if(StringUtils.isNotBlank(message)&&message.equals(msg)){
                reconnectTimes = 0;
            }
        }
    }

    @OnClose
    public void onClose() {
        //System.out.println("WebSocket 连接已关闭");
//        latch.countDown();
        closeStatus();
    }

    @OnError
    public void onError(Throwable error) {
        //System.out.println("WebSocket 错误: " + error.getMessage());
//        latch.countDown();
        closeStatus();
    }

    public void connect(String websocketUrl) {
        ClientManager client = ClientManager.createClient();
//        latch = new CountDownLatch(1);
        try {
            client.connectToServer(this, new URI(websocketUrl));
//            latch.await(); // 等待 WebSocket 连接建立完成
        } catch (Exception e) {
            //System.out.println("无法连接到 WebSocket 服务器: " + e.getMessage());
            closeStatus();
        }
    }

    public void close() {
        closeStatus();
        try {
            session.close();
        } catch (Exception e) {
            //System.out.println("无法关闭 WebSocket 连接: " + e.getMessage());
        }finally {
//            latch.countDown();
        }
    }


//    private CountDownLatch latch = new CountDownLatch(1);


    private void closeStatus(){
        if(!"close".equals(status)) {
            //System.out.println("close-update base");
            monWebsocketService.updateMonWebsocketStatus(websocketId, Status.CLOSE);
            status = "close";
            reconnectTimes = connectTimeout/1000 + 1;
        }
    }



    public WebSocketThread(Long websocketId, String websocketUrl, Integer connectTimeout, String msg, IMonWebsocketService monWebsocketService){
        this.websocketId = websocketId;
        this.websocketUrl = websocketUrl;
        this.connectTimeout = connectTimeout;
        this.msg = msg;
        this.monWebsocketService = monWebsocketService;
    }

    public void stopThread() {
        running = false;
//        latch.countDown();
    }


    public void run() {
//        String websocketUrl = "ws://127.0.0.1:8000/websocket/message"; // 替换为你要测试的 WebSocket 地址

//        WebSocketClient client = new WebSocketClient();
        while (running) {

            connect(websocketUrl);

            out:while (running){
                try {
                    Thread.sleep(1000);
                    reconnectTimes++;
                        //System.out.println("reconnectTimes*1000:"+reconnectTimes*1000);
                    if(reconnectTimes*1000>connectTimeout){//收到消息的心跳间隔大于设置的时间
                        //System.out.println("close");
                        closeStatus();
                        reconnectTimes --;
                        if (session == null||!session.isOpen()) break out;
                    }else{
                        //System.out.println("open");
                        if(!"open".equals(status)) {
                                //System.out.println("open-update base");
                            monWebsocketService.updateMonWebsocketStatus(websocketId, Status.OPEN);
                            status = "open";
                        }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }


            close();

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }


    }

}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty是一个高性能的网络编程框架,而websocket是一种在Web应用中实现双向通信的协议。Netty可以用来实现WebSocket服务器,从而让Web应用能够与客户端建立持久化的连接,并进行双向通信。 要在Netty中实现WebSocket服务器,你可以使用Netty提供的WebSocket协议的支持。下面是一个简单的示例代码: ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; public class WebSocketServer { private final int port; public WebSocketServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new HttpServerCodec(), new HttpObjectAggregator(65536), new WebSocketServerProtocolHandler("/websocket"), new WebSocketServerHandler()); } }); Channel ch = b.bind(port).sync().channel(); System.out.println("WebSocket Server started at port " + port + "."); System.out.println("Open your browser and navigate to http://localhost:" + port + "/"); ChannelFuture future = ch.closeFuture(); future.sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if (args.length > 0) { port = Integer.parseInt(args[0]); } new WebSocketServer(port).run(); } } ``` 在上面的示例代码中,我们创建了一个WebSocket服务器,并将其绑定到指定的端口上。通过`WebSocketServerHandler`类来处理客户端和服务器之间的WebSocket通信。 你可以根据自己的需求,定制`WebSocketServerHandler`来处理不同的业务逻辑。例如,你可以在`channelRead()`方法中处理接收到的WebSocket消息,然后通过`channel().writeAndFlush()`方法发送响应消息给客户端。 希望以上信息能对你有所帮助!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值