springboot+Netty搭建web服务器实现物联网温湿度采集
前言:这段时间做了一个课程设计,内容是将温湿度传感器采集到的温湿度数据上传到web服务器并以表格或者折线图的方式可视化展示出来。话不多说:上代码①Netty服务器搭建NettyServer.java/*** @author cx* @Time 2020/6/29 22:00* @Description netty 服务器配置*/public class NettyServer {public vo
前言:这段时间做了一个课程设计,内容是将温湿度传感器采集到的温湿度数据上传到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());
}
}
springbootApplication
package com.hunau.springboot;
import com.hunau.springboot.nettyserver.NettyServer;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.net.InetSocketAddress;
@SpringBootApplication
@MapperScan("com.hunau.springboot.mapper")
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
/**启动服务端*/
NettyServer nettyServer = new NettyServer();
nettyServer.start(new InetSocketAddress("127.0.0.1",8087));
}
}
②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";
}
}
③实体层
Humiture.java
/**
* @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
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>test</title>
<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> <!--5.jpg-->
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="main" style="width: 600px;height:400px;position: absolute; top:50%; left: 50%; margin-top: -200px;margin-left: -300px"></div>
<!--<div style="left:945px;top:819px ">-->
<!-- <a href="/" rel="external nofollow" >-->
<!-- <button type="button" class="btn btn-primary ">返回首页</button>-->
<!-- </a>-->
<!--</div>-->
<!--<script th:inline="javascript">-->
<!-- var data = [[${value}]];-->
<!-- console.log(data);-->
<!--</script>-->
<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
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymleaf</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" th:href="@{/layui.css}">
<script th:src="@{/layui.js}"></script>
<script></script>
</head>
<body background="2.jpg"> <!--2.jpg-->
<!--<div style="text-align: center;margin-top: 20px">-->
<!-- <button type="button" class="btn btn-success ">温湿度采集表格数据展示</button>-->
<!--</div>-->
<h1 style="text-align: center;margin-top: 20px">温湿度超声波采集表格数据展示</h1>
<h2 style="text-align: center;margin-top: 20px;color: mediumvioletred">author : cx</h2>
<!--<div style="text-align: center;margin-top: 20px">-->
<!-- <button type="button" class="btn btn-danger ">author:陈霞</button>-->
<!--</div>-->
<table class="table table-hover table-dark" th:align="center" th:valign="middle" style="margin-top: 40px">
<thead>
<tr>
<th scope="col">组号</th>
<th scope="col">温度</th>
<th scope="col">湿度</th>
<th scope="col">ip地址</th>
<th scope="col">距离</th>
<th scope="col">采集时间</th>
</tr>
</thead>
<tbody>
<tr th:each="c,State:${message}">
<th scope="row" th:text="${c.id}"></th>
<td th:text="${c.temp}"></td>
<td th:text="${c.humidity}"></td>
<td th:text="${c.ip}"></td>
<td th:text="${c.distance}"></td>
<td th:text="${c.time}"></td>
</tr>
</tbody>
</table>
<div style="text-align: center">
<a href="/humiture" rel="external nofollow" >
<button type="button" class="btn btn-primary ">点击查看动态折现图</button>
</a>
</div>
</body>
</html>
application.yml文件配置如下:
server:
port: 8081
spring:
resources:
static-locations: classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources
datasource:
username: 填写数据库用户名
password: 填写密码
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: mapper/HumitureMapper.xml
type-aliases-package: com.hunau.springboot.domain
#showSql
logging:
level:
com:
example:
mapper : debug
pom.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hunau</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--thymleaf模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--网页相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.15</version>
</dependency>
<!-- mybatis相关依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<!--netty依赖-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.36.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
代码到此结束
下面上效果图
客户端发送温湿度格式为 字符串,中间以逗号隔开例如“29,88”
(温度,湿度)服务器就会接收到对应的温湿度信息并且存入数据库!
都看到这里了,不妨点个赞再走呗,创作不易,不想被白嫖,求点赞,奥利给!!!
更多推荐
所有评论(0)