Java implementa monitoramento de pulsação

Antes de tudo, deixe-me dizer que deve haver mais de uma maneira de realizar o monitoramento de batimentos cardíacos. Antes de fazer isso, o requisito dado pelo líder era usar o netty para implementá-lo. Depois de assistir por mais de um dia, um pequeno a demonstração foi concluída com netty, mas foi descoberta quando o servidor foi conectado.socket io. Então mudei para a implementação do socket io.
Deve haver outras implementações, mas como não abordei, não vou falar sobre isso por enquanto, vamos começar com o netty.

netty

O primeiro passo: pacote de guia

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>5.0.0.Alpha2</version
        </dependency>

Em relação a este pacote netty, muitas pessoas na Internet disseram que o netty é compatível com versões anteriores. Mas, como ainda não o encontrei, não posso dar um conselho muito bom. Só posso dizer que, se você encontrar problemas, pode pensar nisso nessa direção.
Código. Na verdade, isso envolve coisas muito esotéricas, como codificar e decodificar! Mas como o que tenho a fazer é relativamente simples, não examinei esse aspecto com muito cuidado. Contanto que eu implemente um monitoramento simples de pulsação aqui, tudo bem!
Implemente principalmente a classe SimpleChannelInboundHandler<String>. Deve-se observar que versões diferentes de netty têm nomes de método ligeiramente diferentes, como messageReceive, e algumas versões são chamadas de clientRead0. Isso é apenas aleatório.

package com.dsyl.done.netty;
 
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;
 
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
 
public class HeartBeatClientHandler extends SimpleChannelInboundHandler<String> {
 
      private ClientStarter clientStarter;
 
      public HeartBeatClientHandler(ClientStarter clientStarter) {
        this.clientStarter = clientStarter;
      }
 
      /**
       * 客户端监听写事件。也就是设置时间内没有与服务端交互则发送ping 给服务端
       */
      @Override
      public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent) {
          IdleState state = ((IdleStateEvent)evt).state();
          if(state == IdleState.ALL_IDLE) {
            ctx.writeAndFlush("PING");
            System.out.println("send PING");
          }
        }
        super.userEventTriggered(ctx, evt);
      }
      /**
       * channelInactive 被触发一定是和服务器断开了。分两种情况。一种是服务端close,一种是客户端close。
       */
      @Override
      public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        System.err.println("客户端与服务端断开连接,断开的时间为:"+(new Date()).toString());
        // 定时线程 断线重连
        final EventLoop eventLoop = ctx.channel().eventLoop();
        //设置断开连接后重连时间,此设置是断开连接一分钟(60秒)后重连
        eventLoop.schedule(() -> clientStarter.connect(), 60, TimeUnit.SECONDS);
      }
 
      /**
       * 在服务器端不使用心跳检测的情况下,如果客户端突然拔掉网线断网(注意这里不是客户度程序关闭,而仅是异常断网)
       */
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if(cause instanceof IOException) {
          System.out.println("server "+ctx.channel().remoteAddress()+"关闭连接");
        }
      }
 
    /**
     * 消息监控,监听服务端传来的消息(和netty版本有关,有的版本这个方法叫做clientRead0)
     */
      @Override
    protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
        if (msg.equals("PONG")) {
              System.out.println("receive form server PONG");
            }
            ReferenceCountUtil.release(msg);
         
    }
    }

package com.dsyl.done.netty;
 
import java.net.InetSocketAddress;
 
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
 
public class ClientStarter {
 
    private Bootstrap bootstrap;
    private int times = 0;
 
    public ClientStarter(Bootstrap bootstrap) {
        this.bootstrap = bootstrap;
        ClientStarter clientStarter = this;
        bootstrap.group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                        ch.pipeline().addLast(new StringDecoder());
                        //发送消息频率。单位秒。此设置是60秒发送一次消息
                        ch.pipeline().addLast(new IdleStateHandler(60, 60, 60));
                        ch.pipeline().addLast(new HeartBeatClientHandler(clientStarter));
                    }
                });
    }
 
    public void connect() {
        ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress("ip", 端口));
        channelFuture.addListener(future ->{
                if (future.isSuccess()) {
                    System.out.println("connect to server success");
                } else {
                    System.out.println("connect to server failed,try times:" + ++times);
                    connect();
                }
        });
    }
}

Isso conclui a configuração. Ao testar, basta criar um novo objeto ClientStarter e chamar o método start.

ClientStarter starter = new ClientStarter(new Bootstrap());
starter.connect();

Então, ao testar, crie um servidor localmente e teste ok, mas há um problema na depuração conjunta com o servidor:

Isso ocorre porque o servidor coloca o cliente offline depois que a conexão é bem-sucedida. Em seguida, repita o processo. Este é um problema de configuração do lado do servidor.

soquete io

Isso pode ser considerado como um tipo de encapsulamento no netty. De qualquer forma, é mais simples e conveniente de usar do que o netty. Ele é usado principalmente pelo nosso servidor, então mudei para este formulário.
O primeiro passo é orientar o pacote

<!-- netty socketio -->
        <dependency>
            <groupId>com.corundumstudio.socketio</groupId>
            <artifactId>netty-socketio</artifactId>
            <version>1.7.13</version>
        </dependency>

        <dependency>
            <groupId>io.socket</groupId>
            <artifactId>socket.io-client</artifactId>
            <version>1.0.0</version>
        </dependency>

Deixe-me falar sobre isso aqui, o seguinte é a dependência que o cliente precisa importar e o anterior. . . O servidor deve ser importado? De qualquer forma, olhei o código do projeto do nosso servidor e as duas dependências foram importadas.
Deixe-me ir diretamente para o meu código local, é bem simples:

    public void connectServer() {
        String url = "http://" + serverListenIp;
        try {
            IO.Options options = new IO.Options();
            options.transports = new String[] { "websocket" };
            options.reconnectionAttempts = 1000000000;
            options.reconnectionDelay = 60000;// 失败重连的时间间隔
            options.timeout = 10000;// 连接超时时间(ms)
            // par1 是任意参数
            final Socket socket = IO.socket(url + "?userType=0", options);
            socket.on(Socket.EVENT_CONNECT, objects -> {
                System.out.println("client: 连接成功");
                System.out.println("拉取缓存的数据信息!");
                //做你想做的操作
            });
            socket.on(Socket.EVENT_CONNECTING, objects -> System.out.println("client: " + "连接中"));
            socket.on(Socket.EVENT_CONNECT_TIMEOUT, objects -> System.out.println("client: " + "连接超时"));
            socket.on(Socket.EVENT_CONNECT_ERROR, objects -> System.out.println("client: " + "连接失败"));
            socket.connect();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

Aqui Socket.EVENT_CONNECT, Socket.EVENT_CONNECTING, etc. recebem constantes. Se você não entender, você pode olhar para a definição


 

Acho que você gosta

Origin blog.csdn.net/m0_69824302/article/details/130544738
Recomendado
Clasificación