通过Netty实现与硬件设备(设备的上下道信息、经纬度)通讯的功能

1.Netty的业务场景

​ 平台主要需求是和硬件(铁路小车安装的硬件)对接,并定时对设备进行监控检查,需要使用Netty作为通信中间件来监听端口,小车上的硬件通过TCP连接向服务端发送指令,后台主要是通过netty的ChannelHandler来实现对硬件数据的接收和处理。我的项目是把接收到的数据存入数据库,当然也可以放到缓存中。由于我也是刚开始接触netty,所以直接上代码,至于原理请自行百度。

2. Netty的主要组件

2.1 Channel

​ Channel作为Netty网络通信的主体,可以看作是通讯的载体,主要有三个状态:打开、关闭、连接。

​ Channel主要的IO操作:读(read)、写(write)、连接(connect)、绑定(bind),均为异步,也就是说在调用如上方法后,并不保证IO操作完成,但会在IO操作成功、失败或取消后,生成相应的记录保存在一个凭证中并返回。

3.下面把项目代码贴出来:

spring boot项目netty依赖

 <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.0.Final</version>
        </dependency>

3.1  Netty服务   服务启动监听器

 

package com.htkj.netty.server;

import com.htkj.netty.handler.DecoderHandler;
import com.htkj.netty.handler.ServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;


/**
 * Netty服务   服务启动监听器
 * @author zl
 * @date 2019-12-11
 *
 */
@Component
public class NettyServer {

    private static Logger logger = LoggerFactory.getLogger(ServerHandler.class);

    @Value("${netty.port}")
    private int port;

    public static ServerSocketChannel serverSocketChannel;
    @Autowired
    private ServerHandler serverHandler;
    

    public void start() throws Exception {
        // 连接处理group
        EventLoopGroup boss = new NioEventLoopGroup();
        // 事件处理group
        EventLoopGroup worker = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();//1.创建ServerBootStrap实例
        // 绑定处理group
        bootstrap.group(boss, worker)//2.设置并绑定Reactor线程池:EventLoopGroup,EventLoop就是处理所有注册到本线程的Selector上面的Channel
        		.channel(NioServerSocketChannel.class)//3.设置并绑定服务端的channel
                // 保持连接数
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 有数据立即发送
                .option(ChannelOption.TCP_NODELAY, true)
                // 保持连接
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                // 处理新连接
                .childHandler(new ChannelInitializer<SocketChannel>() {//设置了客户端连接socket属性。
                    @Override
                    protected void initChannel(SocketChannel sc) throws Exception {
                        // 增加任务处理
                        ChannelPipeline p = sc.pipeline();
                        p.addLast(new DecoderHandler(), // 自定义解码器
            
  • 8
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
Netty是一款基于NIO的网络通讯框架,它提供了高性能、高可靠性的网络编程能力,因此可以用来实现即时通讯。以下是一个简单的使用Netty实现即时通讯的示例: 1. 创建一个Netty的Server端和Client端 ```java // Server端 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 ServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); // 绑定端口,开始接收进来的连接 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 。 // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } // Client端 EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }); // 连接服务端 ChannelFuture f = b.connect(host, port).sync(); // 等待连接关闭 f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } ``` 2. 编写ServerHandler和ClientHandler ```java // ServerHandler public class ServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 处理客户端发送过来的消息 ByteBuf in = (ByteBuf) msg; try { System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)); // 将消息返回给客户端 ctx.write(in); ctx.flush(); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 当出现异常时关闭连接 cause.printStackTrace(); ctx.close(); } } // ClientHandler public class ClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) { // 发送消息给服务端 ctx.writeAndFlush(Unpooled.copiedBuffer("Hello Server", CharsetUtil.UTF_8)); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 处理服务端返回的消息 ByteBuf in = (ByteBuf) msg; try { System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8)); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 当出现异常时关闭连接 cause.printStackTrace(); ctx.close(); } } ``` 这样,我们就可以用Netty实现简单的即时通讯了。当然,实际应用中还需要考虑更多的因素,例如协议的定义和解析、消息的组装和拆解等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stone.小小的太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值