In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces how websocket and the lower computer communicate and transmit behavior information through netty, the content is very detailed, interested friends can refer to, hope to be helpful to you.
Introduction to the preface
In the development of the Internet of things, it is often necessary to control devices through the web, including obtaining information, performing operations, starting and stopping, etc., just as we control some devices such as millet boxes, routers, rice cookers or online dogs at home on our mobile phones. Here, all the lower-layer devices can be linked to the server through socket communication, while the user side is linked to the server through http link or websocket link, and makes corresponding actions by sending and receiving data. The figure below is as follows
Official account of Wechat: bugstack wormhole stack & execution process
Case goal
This chapter integrates Springboot+Netty and receives forwarding behavior messages by deploying two servers, nettySocket and webSocket.
The client uses js link websocket to receive server feedback and send instructions to obtain the information of the lower computer.
Start an analog lower computer in test for feedback of information and data. In real development, the communication between the lower computer and the server is usually a well-defined bytecode, so we need to write our own decoder.
Environmental preparation
Jdk 1.8.0
IntelliJ IDEA Community Edition 2018.3.1 x64
Netty 4.1.36.Final
Code sample 1itstack-demo-netty-3-01
2 └── src
3 ├── main
4 │ ├── java
5 │ │ └── org.itstack.demo.ark
6 │ │ ├── domain
7 │ ├── msgobj
8 │ ├── Feedback.java
9 │ ├── QueryInfoReq.java
10 │ └── Text.java
11 │ ├── Device.java
12 │ ├── EasyResult.java
13 │ ├── InfoProtocol.java
14 │ └── ServerInfo.java
15 │ │ ├── server
16 │ ├── socket
17 │ ├── MyChannelInitializer.java
18 │ ├── MyServerHandler.java
19 │ └── NettyServer.java
20 │ └── websocket
21 │ ├── MyWsChannelInitializer.java
22 │ ├── MyWsServerHandler.java
23 │ └── WsNettyServer.java
24 │ │ ├── util
25 │ ├── CacheUtil.java
26 │ ├── MsgUtil.java
27 │ └── MsgUtil.java
28 │ │ ├── web
29 │ └── NettyController.java
30 │ │ └── Application.java
31 │ └── resources
32 │ │ └── application.yml
33 │ └── webapp
34 │ ├── arkWs
35 │ │ ├── js
36 │ └── ws.js
37 │ │ └── arkWsControlCenter.html
38 │ ├── res
39 │ └── WEB-INF
40 │ └── index.jsp
41 │
42 └── test
43 └── java
44 └── org.itstack.demo.test
45 └── ApiTest.java
Demo part of the key code block, complete code download follow official account; bugstack wormhole stack, reply to Netty case
Server/socket/MyServerHandler.java & socket data processing
When there is a lower computer link server, the lower computer information is built, and the actual use can be verified by registration.
When the information of the lower computer is received, it is forwarded to the websocket side, so that the web page side receives the feedback of the lower computer information.
1public class MyServerHandler extends ChannelInboundHandlerAdapter {
two
3 private Logger logger = LoggerFactory.getLogger (MyServerHandler.class)
four
5 / *
6 * this channel becomes active when the client actively links the link on the server. That is, the client and the server establish a communication channel and can transmit data.
7 * /
8 @ Override
9 public void channelActive (ChannelHandlerContext ctx) throws Exception {
10 SocketChannel channel = (SocketChannel) ctx.channel ()
11 String channelId = channel.id () .toString ()
12 System.out.println ("Link report start")
13 System.out.println ("Link report information: a client is linked to this server. ChannelId:" + channelId)
14 System.out.println ("linked report IP:" + channel.localAddress () .getHostString ())
15 System.out.println ("linked report Port:" + channel.localAddress () .getPort ())
16 System.out.println ("link report completed")
seventeen
18 / / build equipment information {lower machine, repeater, IO board}
19 Device device = new Device ()
20 device.setChannelId (channelId)
21 device.setNumber (UUID.randomUUID () .toString ())
22 device.setIp (channel.remoteAddress (). GetHostString ())
23 device.setPort (channel.remoteAddress () .getPort ())
24 device.setConnectTime (new Date ())
25 / / add device information
26 deviceGroup.put (channelId, device)
27 CacheUtil.cacheClientChannel.put (channelId, channel)
28}
twenty-nine
thirty
31 @ Override
32 public void channelRead (ChannelHandlerContext ctx, Object objMsgJsonStr) throws Exception {
33 / / A message from the receiving device
34 System.out.println (new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss") .format (new Date ()) + "received message content:" + objMsgJsonStr)
thirty-five
36 / / forward messages to Ws
37 CacheUtil.wsChannelGroup.writeAndFlush (new TextWebSocketFrame (objMsgJsonStr.toString ()
38}
thirty-nine
40}
Server/websocket/MyWsServerHandler.java & websocket data processing
Websocket data needs to be used after conversion and can support text messages. In this case, json strings are used to facilitate object transmission.
ChannelRead forwards the data, when it receives the data, it sends it to the lower computer, which is mainly controlled by channel in the content.
1public class MyWsServerHandler extends ChannelInboundHandlerAdapter {
two
three
4 @ Override
5 public void channelRead (ChannelHandlerContext ctx, Object msg) throws Exception {
six
7...
eight
9 / / ws
10 if (msg instanceof WebSocketFrame) {
11 WebSocketFrame webSocketFrame = (WebSocketFrame) msg
12 / / close the request
13 if (webSocketFrame instanceof CloseWebSocketFrame) {
14 handshaker.close (ctx.channel (), (CloseWebSocketFrame) webSocketFrame.retain ())
15 return
16}
17 / / ping request
18 if (webSocketFrame instanceof PingWebSocketFrame) {
19 ctx.channel () .write (new PongWebSocketFrame (webSocketFrame.content () .retain ()
20 return
21}
22 / / only text format is supported, not binary messages
23 if (! (webSocketFrame instanceof TextWebSocketFrame)) {
24 throw new Exception ("text formatting only")
25}
twenty-six
27 String request = (TextWebSocketFrame) webSocketFrame) .text ()
28 System.out.println ("Server receives:" + request)
29 InfoProtocol infoProtocol = JSON.parseObject (request, InfoProtocol.class)
30 / / socket forward messages
31 String channelId = infoProtocol.getChannelId ()
32 Channel channel = CacheUtil.cacheClientChannel.get (channelId)
33 if (null = = channel) return
34 channel.writeAndFlush (MsgUtil.buildMsg (infoProtocol))
thirty-five
36 / / websocket message feedback was sent successfully
37 ctx.writeAndFlush (MsgUtil.buildWsMsgText (ctx.channel (). Id (). ToString (), "convey a message to the lower computer success!"))
38}
thirty-nine
40}
forty-one
42}
Web/NettyController.java & the control layer facilitates access to server-side information
The control layer provides query service list, linked device information, and active trigger message sending.
In addition, if you need to manually control the startup and shutdown of the server, you can provide a method to call here.
1@Controller
2public class NettyController {
three
4 private Logger logger = LoggerFactory.getLogger (NettyController.class)
five
6 @ RequestMapping ("/ index")
7 public String index () {
8 return "index"
9}
ten
11 @ RequestMapping ("/ queryNettyServerList")
12 @ ResponseBody
13 public Collection queryNettyServerList () {
14 try {
15 Collection serverInfos = CacheUtil.serverInfoMap.values ()
16 logger.info ("query server list. {}", JSON.toJSONString (serverInfos))
17 return serverInfos
18} catch (Exception e) {
19 logger.info ("failed to query server list." , e)
20 return null
21}
22}
twenty-three
24 @ RequestMapping ("/ queryDeviceList")
25 @ ResponseBody
26 public Collection queryDeviceList () {
27 try {
28 Collection deviceInfos = CacheUtil.deviceGroup.values ()
29 logger.info ("query list of device links. {}", JSON.toJSONString (deviceInfos))
30 return deviceInfos
31} catch (Exception e) {
32 logger.info ("failed to query the list of device links." , e)
33 return null
34}
35}
thirty-six
37 @ RequestMapping ("/ doSendMsg")
38 @ ResponseBody
39 public EasyResult doSendMsg (String reqStr) {
40 try {
41 logger.info ("send information to the device [you can call this API through another Web service]: {}", reqStr)
42 InfoProtocol infoProtocol = MsgUtil.getMsg (reqStr)
43 String channelId = infoProtocol.getChannelId ()
44 Channel channel = CacheUtil.cacheClientChannel.get (channelId)
45 channel.writeAndFlush (MsgUtil.buildMsg (infoProtocol))
46 return EasyResult.buildSuccessResult ()
47} catch (Exception e) {
48 logger.error ("failed to send message to device: {}", reqStr, e)
49 return EasyResult.buildErrResult (e)
50}
51}
fifty-two
53}
Application.java & initiator layer
Start the socket service when the service is ready by inheriting the CommandLineRunner method
After startup, you need to cycle through to verify whether the startup is complete.
1@SpringBootApplication
2@ComponentScan ("org.itstack.demo.ark")
3public class Application implements CommandLineRunner {
four
5 private Logger logger = LoggerFactory.getLogger (Application.class)
six
7 @ Value ("${netty.socket.port}")
8 private int nettyServerPort
9 @ Value ("${netty.websocket.port}")
10 private int nettyWsServerPort
11 / / default thread pool
12 private static ExecutorService executorService = Executors.newFixedThreadPool (2)
thirteen
14 public static void main (String [] args) {
15 SpringApplication.run (Application.class, args)
16}
seventeen
18 @ Override
19 public void run (String... Args) throws Exception {
20 / / start NettyServer-socket
21 logger.info ("start NettyServer service, startup port: {}", nettyServerPort)
22 NettyServer nettyServer = new NettyServer (new InetSocketAddress (nettyServerPort))
23 Future future = executorService.submit (nettyServer)
24 Channel channel = future.get ()
25 if (null = = channel) {
26 throw new RuntimeException ("netty server-s open error channel is null")
27}
28 while (! channel.isActive ()) {
29 logger.info ("start the NettyServer service, loop waiting to start...")
30 Thread.sleep
31}
32 logger.info ("start NettyServer service, complete: {}", channel.localAddress ())
33 CacheUtil.serverInfoMap.put (nettyServerPort, new ServerInfo ("NettySocket", NetUtil.getHost (), nettyServerPort, new Date ()
thirty-four
35 / / start NettyServer-websocket
36 logger.info ("start NettyWsServer service, startup port: {}", nettyWsServerPort)
37 WsNettyServer wsNettyServer = new WsNettyServer (new InetSocketAddress (nettyWsServerPort))
38 Future wsFuture = executorService.submit (wsNettyServer)
39 Channel wsChannel = wsFuture.get ()
40 if (null = = wsChannel) {
41 throw new RuntimeException ("netty server-ws open error channel is null")
42}
43 while (! wsChannel.isActive ()) {
44 logger.info ("start the NettyWsServer service, loop waiting to start...")
45 Thread.sleep
46}
47 logger.info ("start NettyWsServer service, complete: {}", wsChannel.localAddress ())
48 CacheUtil.serverInfoMap.put (nettyServerPort, new ServerInfo ("NettyWsSocket", NetUtil.getHost (), nettyServerPort, new Date ()
49}
fifty
51}
Webapp/arkWs/js/ws.js & Link websocket server
1socket = new WebSocket ("ws://localhost:7398/websocket")
two
3 socket.onmessage = function (event) {
four
5 var msg = JSON.parse (event.data)
6 console.info (msg)
seven
8 $("# msgBox") .val ($("# msgBox") .val () + event.data + "\ r\ n")
nine
10}
Case testing
Start the following respectively
Application.java,Plugins/spring-boot/spring-boot:run
ApiTest.java, right start the analog lower computer
Open the server link; http://localhost:8080/ http://localhost:8080/arkWs/arkWsControlCenter.html
Official account of Wechat: bugstack wormhole stack & server and monitoring
Send simulation information and observe the execution result
12019-12-01 15 Initializing Spring FrameworkServlet 11V 49.965 INFO 7620-[nio-8080-exec-1] o.a.c.c..[ tomcat] .[ localhost]. [/]: tomcat 'dispatcherServlet'
22019-12-01 15 o.s.web.servlet.DispatcherServlet 1114 49.965 INFO 7620-[nio-8080-exec-1] o.s.web.servlet.DispatcherServlet: FrameworkServlet 'dispatcherServlet': initialization started
32019-12-01 15 o.s.web.servlet.DispatcherServlet 11 FrameworkServlet 49.980 INFO 7620-[nio-8080-exec-1] o.s.web.servlet.DispatcherServlet: FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms
42019-12-01 15 o.itstack.demo.ark.web.NettyController 11V 51.157 INFO 7620-[nio-8080-exec-3] o.itstack.demo.ark.web.NettyController: query the list of device links. [{"channelId": "281d1279", "connectTime": 1575184302964, "ip": "127.0.0.1", "number": "74de0967-c0b4-4426-a9d1-183feaff2acf", "port": 3972}]
52019-12-01 15 INFO 111.162 INFO 7620-[io-8080-exec-10] o.itstack.demo.ark.web.NettyController: query server list. [{"ip": "10.13.70.50", "openDate": 1575184290501, "port": 7397, "typeInfo": "NettyWsSocket"}]
62019-12-01 15 o.i.d.a.s.websocket.MyWsServerHandler 11V 58.476 INFO 7620-[ntLoopGroup-7-1] o.i.d.a.s.websocket.MyWsServerHandler: link report begins
72019-12-01 15 o.i.d.a.s.websocket.MyWsServerHandler 11V 58.476 INFO 7620-[ntLoopGroup-7-1] o.i.d.a.s.websocket.MyWsServerHandler: link report message: there is a client linked to this server
82019-12-01 15 o.i.d.a.s.websocket.MyWsServerHandler 11V 58.476 INFO 7620-[ntLoopGroup-7-1] o.i.d.a.s.websocket.MyWsServerHandler: link report IP:0:0:0:0:0:0:0:1
92019-12-01 15 o.i.d.a.s.websocket.MyWsServerHandler 11V 58.476 INFO 7620-[ntLoopGroup-7-1] o.i.d.a.s.websocket.MyWsServerHandler: link report Port:7398
102019-12-01 15 o.i.d.a.s.websocket.MyWsServerHandler 11V 58.476 INFO 7620-[ntLoopGroup-7-1] o.i.d.a.s.websocket.MyWsServerHandler: link report completed
11 the server receives: {"channelId": "281d1279", "msgType": 2, "msgObj": {"stateType": "1"}}
122019-12-01 15:12:05 received message content: {"msgObj": {"stateMsg": "temperature information: 91.313348941763 °C", "stateType": 1, "channelId": "93c1120a"}, "msgType": 3, "channelId": "93c1120a"}
13 the server receives: {"channelId": "281d1279", "msgType": 2, "msgObj": {"stateType": "1"}}
142019-12-01 15:12:05 received message content: {"msgObj": {"stateMsg": "temperature information: 44.83794772946285 °C", "stateType": 1, "channelId": "93c1120a"}, "msgType": 3, "channelId": "93c1120a"}
To sum up
In the use of springboot and netty combination, the development of a simple server is very convenient, and in the collection of some springcloud services, can make the project more perfect.
You can try to do some device control services, and you can also control the equipment at home through an H6 link when we are not at home, such as turning on the water heater when we get home soon.
This case is also biased towards simulation, in the actual development process, there will still be a lot of business problems to be solved, especially the communication between the server and the lower computer, the need to write encoders and decoders.
On the websocket and the lower computer how to communicate and transmit behavior information through netty way to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.