springboot+Netty搭建web服务器实现物联网温湿度采集

前言:这段时间做了一个课程设计,内容是将温湿度传感器采集到的温湿度数据上传到web服务器并以表格或者折线图的方式可视化展示出来。话不多说:上代码!!!

①Netty服务器搭建

NettyServer.java

/**
 * @author cx
 * @Time 2020/6/29 22:00
 * @Description netty 服务器配置
 */
public class NettyServer {
    public void start(InetSocketAddress socketAddress){
        /**new 一个主线程组*/
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        /**new 一个工作线程组*/
        EventLoopGroup workGroup = new NioEventLoopGroup(200);
        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(bossGroup,workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ServerChannelInitializer())
                .localAddress(socketAddress)
                /**设置队列的大小*/
                .option(ChannelOption.SO_BACKLOG,1024)
                /**两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文*/
                .childOption(ChannelOption.SO_KEEPALIVE,true);
                /**绑定端口,开始接收进来的连接*/
                try{
                    ChannelFuture future = bootstrap.bind(socketAddress).sync();
                    System.out.println("服务器ip为:"+socketAddress.getHostName());
                    System.out.println("服务器端口号为:"+socketAddress.getPort());
                    future.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    /**关闭主线程组*/
                    bossGroup.shutdownGracefully();
                    /**关闭工作线程组*/
                    workGroup.shutdownGracefully();
                }
    }
}

NettyServerHandler.java

/**
 * @author cx
 * @Time 2020/6/29 22:23
 * @Description 服务端业务处理
 */
@Component
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    /**获取实例化对象*/
    @Autowired
    protected IHumitureService humitureService;

    private static NettyServerHandler serverHandler;

    /**配合@Component注解获取service层的bean*/
    @PostConstruct
    public void init(){
        serverHandler = this;
        serverHandler.humitureService = this.humitureService;
    }

    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端发起连接!!!!");
    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        /**获取客户端的IP*/
        InetSocketAddress insocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String ip = insocket.getAddress().getHostAddress();
        /**将温湿度数据处理*/
        String tem = msg.toString();
        String[] arr = tem.split(",");
        Humiture  humiture = new Humiture();
        humiture.setTemp(arr[0]);
        humiture.setHumidity(arr[1]);
        humiture.setIp(ip);
        /**调用业务层方法将数据写入数据库*/
        serverHandler.humitureService.insertData(humiture);
        System.out.println("服务器接收到客户端的温度,湿度---"+msg.toString());
        System.out.println("温湿度写入数据库成功!!!!");
        ctx.write("receive OK!");
        ctx.flush();
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

注意:上面代码解决了一个问题,就是如何在controller层外获得bean,然后调用业务层方法将获得的数据写入数据库。方法是在handler类上加一个@Component注解,然后写一个init()方法,init()方法上面加一个@PostConstruct注解将bean实例化

ServerChannelInitializer .java

/**
 * @author cx
 * @Time 2020/6/29 22:06
 * @Description 初始化编码器
 */
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        /**添加编解码*/
        socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast(new NettyServerHandler());
    }
}

②controller层代码

HumitureController .java

/**
 * @author cx
 * @Time 2020/6/28 15:32
 * @Description 温湿度采集 控制层
 */
@Controller
public class HumitureController {
    @Autowired
    private IHumitureService iHumitureService;

    @GetMapping("/test")
    @ResponseBody
    public List<Humiture> list()
    {
        return iHumitureService.listHumiture();
    }

    @GetMapping("/list")
    @ResponseBody
    public Map<String,Object> selectAll()
    {
        Map<String,Object> map = new HashMap<>();
        List<Humiture> data = iHumitureService.listHumiture();
        map.put("code",0);
        map.put("msg","随便写点东西");
        map.put("count",10);
        map.put("data",data);
        return map;
    }
}

IndexController .java

/**
 * @author cx
 * @Time 2020/6/28 10:22
 * @Description 页面信息展示 控制层
 */
@Controller
public class IndexController {

    @Autowired
    private IHumitureService iHumitureService;

    @GetMapping("/")
    public String hello(ModelMap modelMap)
    {
        List<Humiture> list = iHumitureService.listHumiture();
        modelMap.addAttribute("message",list);
        return "index";
    }

    @GetMapping("/humiture")
    public String humiture(ModelMap modelMap)
    {
        List<Humiture> list = iHumitureService.listHumiture();
        modelMap.addAttribute("value",list);
        return "humiture";
    }
}

③实体层

/**
 * @author cx
 * @Time 2020/6/28 15:11
 * @Description 温湿度检测 实体
 */
public class Humiture {

    /**数据编号*/
    private int id;
    /**温度*/
    private String temp;
    /**湿度*/
    private String humidity;
    /**ip地址*/
    private String ip;
    /**采集时间*/
    private String time;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getHumidity() {
        return humidity;
    }

    public void setHumidity(String humidity) {
        this.humidity = humidity;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

④mapper层

HumitureMapper .java

/**
 * @author cx
 * @Time 2020/6/28 15:18
 * @Description 温湿度采集 数据层
 */
@Repository
public interface HumitureMapper {
    /**
     * @description 温湿度采集 查询
     *
     * @param
     * @return 温湿度采集 列表
     */
    public List<Humiture> listHumiture();
    /**
     * @description 温湿度采集 存库
     *
     * @param
     * @return 温湿度采集 存库
     */
    public int insertData(Humiture humiture);
}

⑤service层代码

IHumitureService .java

/**
 * @author cx
 * @Time 2020/6/28 15:22
 * @Description 温湿度采集 业务层接口
 */
public interface IHumitureService {
    /**
     * @description 温湿度采集 查询
     *
     * @param
     * @return 温湿度采集 列表
     */
    public List<Humiture> listHumiture();
    /**
     * @description 温湿度采集 存库
     *
     * @param
     * @return 温湿度采集 存库
     */
    public int insertData(Humiture humiture);
}

HumitureServiceImpl .java

/**
 * @author cx
 * @Time 2020/6/28 15:23
 * @Description 温湿度采集 业务层实现
 */
@Service
public class HumitureServiceImpl implements IHumitureService {

    @Autowired
    private HumitureMapper humitureMapper;

    /**
     * @description 温湿度采集 查询
     *
     * @param
     * @return 温湿度采集 列表
     */
    @Override
    public List<Humiture> listHumiture()
    {
        return humitureMapper.listHumiture();
    }
    /**
     * @description 温湿度采集 存库
     *
     * @param
     * @return 温湿度采集 存库
     */
    @Override
    public int insertData(Humiture humiture){
        return humitureMapper.insertData(humiture);
    }
}

⑥resource下的mapper

HumitureMapper .xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hunau.springboot.mapper.HumitureMapper">
    <resultMap id="HumitureResult" type="Humiture">
        <result property="id" column="id"/>
        <result property="temp" column="temp"/>
        <result property="humidity" column="humidity"/>
        <result property="ip" column="ip"/>
        <result property="time" column="time"/>
    </resultMap>

    <select id="listHumiture" resultMap="HumitureResult">
        select * from tb_humiture
    </select>

    <insert id="insertData" parameterType="Humiture">
        insert into tb_humiture
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="temp != null  and temp != ''  ">temp,</if>
            <if test="humidity != null  and humidity != ''  ">humidity,</if>
            <if test="ip != null  and ip != ''  ">ip,</if>
            <if test="time != null  and time != ''  ">time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="temp != null  and temp != ''  ">#{temp},</if>
            <if test="humidity != null  and humidity != ''  ">#{humidity},</if>
            <if test="ip != null  and ip != ''  ">#{ip},</if>
            <if test="time != null  and time != ''  ">#{time},</if>
        </trim>
    </insert>
</mapper>

⑦前端代码

humiture.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>testtitle>
    <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js">script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
head>
<body> 


<div id="main" style="width: 600px;height:400px;position: absolute; top:50%; left: 50%; margin-top: -200px;margin-left: -300px">div>









<script th:inline="javascript">
    /**基于准备好的dom,初始化echarts实例*/
    var myChart = echarts.init(document.getElementById('main'));
    var data = [[${value}]];
    console.log(data);
    /**温度*/
    var temperature = [];
    /**湿度*/
    var humidity = [];
    /**采集时间*/
    var coltime = [];
    /**获取温度打包为数组*/
    for (i in data)
        temperature.push(data[i].temp);
    console.log(temperature);
    /**获取湿度打包为数组*/
    for (i in data)
        humidity.push(data[i].humidity);
    console.log(humidity);
    for (i in data)
        coltime.push(data[i].time);
    console.log(coltime);
    /**指定图表的配置项和数据*/
    option = {
        title: {
            text: '温湿度动态图'
        },
        tooltip: {
            trigger: 'axis'
        },
        legend: {
            data: ['温度', '湿度']
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        toolbox: {
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: coltime
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                name: '温度',
                type: 'line',
                stack: '总量',
                data: temperature
            },
            {
                name: '湿度',
                type: 'line',
                stack: '总量',
                data: humidity
            }
        ]
    };

    /**使用刚指定的配置项和数据显示图表*/
    myChart.setOption(option);
script>
body>
html>

index.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>testtitle>
    <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js">script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
head>
<body> 


<div id="main" style="width: 600px;height:400px;position: absolute; top:50%; left: 50%; margin-top: -200px;margin-left: -300px">div>









<script th:inline="javascript">
    /**基于准备好的dom,初始化echarts实例*/
    var myChart = echarts.init(document.getElementById('main'));
    var data = [[${value}]];
    console.log(data);
    /**温度*/
    var temperature = [];
    /**湿度*/
    var humidity = [];
    /**采集时间*/
    var coltime = [];
    /**获取温度打包为数组*/
    for (i in data)
        temperature.push(data[i].temp);
    console.log(temperature);
    /**获取湿度打包为数组*/
    for (i in data)
        humidity.push(data[i].humidity);
    console.log(humidity);
    for (i in data)
        coltime.push(data[i].time);
    console.log(coltime);
    /**指定图表的配置项和数据*/
    option = {
        title: {
            text: '温湿度动态图'
        },
        tooltip: {
            trigger: 'axis'
        },
        legend: {
            data: ['温度', '湿度']
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        toolbox: {
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: coltime
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                name: '温度',
                type: 'line',
                stack: '总量',
                data: temperature
            },
            {
                name: '湿度',
                type: 'line',
                stack: '总量',
                data: humidity
            }
        ]
    };

    /**使用刚指定的配置项和数据显示图表*/
    myChart.setOption(option);
script>
body>
html>

代码到此结束
下面上效果图
springboot+Netty搭建web服务器实现物联网温湿度采集_第1张图片
springboot+Netty搭建web服务器实现物联网温湿度采集_第2张图片
客户端发送温湿度格式为 字符串,中间以逗号隔开例如“29,88”(温度,湿度)服务器就会接收到对应的温湿度信息并且存入数据库!

如果觉得总结得还OK的话,不妨点个赞,创作不易,不想被白嫖,求点赞,奥利给!!!

你可能感兴趣的:(springboot)