Netty解决监控传输、指令操作

解决项目中出现的问题

在目前还没有进行过发送操作指令,只有传输图像

传输图像是通过一个阻塞队列数组,把图像数据存放进去,前端再调用接口获取数据

弊端就是实现过程复杂,同时无法进行1对多和实时传输,同时,指令发送也有问题,只是在演示的时候使用一下

目前就是想用Netty改进一下,把图像处理后传到前端。

第一步:实现前端和netty的连接

前后端连接已经解决

前端代码如下

1
2
3
4
5
6
7
8
9
<form action="" onsubmit="return false">
<h1>多人聊天</h1>
<textarea id="msgTxt" cols="50" rows="20">

</textarea><br>
<input type="text" name="msg" style="width: 300px">
<input type="button" value="发送" onclick="send(this.form.msg.value)">
<input type="button" value="清空" onclick="clean()">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

var socket //定义对象
if (!window.WebSocket) {

//有的浏览器里可能没有Websocket对象,window就代表浏览器,就做一下兼容性处理
window.WebSocket = window.MozWebSocket;
}
if (window.WebSocket) {

socket = new WebSocket("ws://127.0.0.1:9000/chat"); //websocket用的是ws协议

socket.onmessage = function (event) { //收到客户端消息
var ta = document.getElementById("msgTxt");
ta.value = ta.value + "\n" + event.data;
}
socket.onopen = function (event) {
var ta = document.getElementById("msgTxt");
ta.value = ta.value + "\n" + "连上服务器";
}

socket.onclose = function (event) {
var ta = document.getElementById("msgTxt");
ta.value = ta.value + "\n" + "退出聊天室";
}
//socket不断接受服务端传来的数据,然后通过三个事件进行处理
}

//客户端想发送数据
function send(msg) {
if (!window.WebSocket) {
return false;
}
if (socket.readyState == WebSocket.OPEN) {
let data = {
"icon": "111",
"content": msg,
"chatType": "G"
}
socket.send(JSON.stringify(data));
} else {
alert("连接没有建立");
}
}

function clean() {
var ta = document.getElementById("msgTxt");
ta.value = "";
}

后端核心代码

  • 引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.28</version>
</dependency>

<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.17.Final</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
</dependencies>
  • 服务端
1
2
3
4
5
6
7
8
9
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new WebChatServerInitialize());
ChannelFuture f = bootstrap.bind(port).sync();

处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
ctx.close();
return;
}
if (!(frame instanceof TextWebSocketFrame)) {
throw new UnsupportedOperationException(
String.format("%s frame types not supported", frame.getClass().getName()));
}

String request = ((TextWebSocketFrame) frame).text();
logger.debug("收到客户端发送的数据:" + request);
// 回复心跳
if (request.length() == 0) {
ctx.writeAndFlush(new TextWebSocketFrame(""));
return;
}
JSONObject requestJson = (JSONObject) JSONObject.parse(request);
JSONObject respJson = new JSONObject();
respJson.put("icon", requestJson.get("icon"));
respJson.put("content", requestJson.get("content"));
// 读取信息,并转发
Channel incoming = ctx.channel();
ChannelGroup channels = ChannelsHolder.getChannelGroups().get("all");

String currentChatType = (String) requestJson.get("chatType");
if (currentChatType.equals("G")) {
//对聊天室的人都遍历一下
for (Channel ch : channels) {
// System.out.println(ch.id() + " :all chaannel id");
if (ch != incoming) {
//被动接收消息的人
respJson.put("type", 1);
ch.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
//ch.writeAndFlush(new TextWebSocketFrame("用户"+incoming.remoteAddress()+"说:"+msg.text()+"\n"));
} else {
//发消息的人
respJson.put("type", 2);
ch.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
//ch.writeAndFlush(new TextWebSocketFrame("我说:"+msg.text()+"\n"));
}
}
} else {
String userId = (String) requestJson.get("msgToUserId");

Channel cl = ChannelsHolder.K_userId_V_Channel.get(userId);
respJson.put("type", 1);
cl.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
respJson.put("type", 2);
incoming.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
}


}

第二步:实现netty实时传输发送图片给前端并显示

第三步:实现摄像头发送图像给netty,netty转发给前端

第四步:实现授权验证,前端只能显示可以显示的数据


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!