netty启用websocket的压缩机制
netty启用websocket的压缩机制
package com.aerotop.connector.websocket.base;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.compression.JZlibDecoder;
import io.netty.handler.codec.compression.JZlibEncoder;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
/**
* @author xhh
*/
public class WebSocketServerInitialzer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//websocket 基于http协议,所以要有http编解码器
pipeline.addLast(new HttpServerCodec());
//对写大数据流的支持
pipeline.addLast(new ChunkedWriteHandler());
//对httpMessage进行聚合,聚合成fullHttpRequest或fullHttpRespones
pipeline.addLast(new HttpObjectAggregator(1024 * 64));
//支持websocket,并启用压缩,设置压缩子协议
pipeline.addLast(new WebSocketServerProtocolHandler("/websocket", "permessage-deflate", true));
// 添加压缩处理器
pipeline.addLast(new WebSocketServerCompressionHandler());
//自定义的handler
pipeline.addLast(new NettyWebSocketHandler());
}
}
前端vue,websocket启用压缩
<template>
<div id="app-1">
<!-- 输入框绑定message数据 -->
<input
type="text"
v-model="message"
placeholder="输入消息"
@keyup.enter="sendMessage"
>
<!-- 发送按钮 -->
<button @click="sendMessage">发送</button>
<!-- 消息展示区域 -->
<div id="output">
<!-- 遍历messages数组 -->
<p v-for="(msg, index) in messages" :key="index">
{{ msg }}
</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
message: '', // 绑定输入框内容
messages: [], // 存储所有消息记录
socket: null // WebSocket实例
};
},
mounted() {
// 组件挂载后初始化WebSocket
this.initWebSocket()
},
methods: {
// 初始化WebSocket连接
initWebSocket() {
// 创建带压缩协商的WebSocket连接
this.socket = new WebSocket('ws://127.0.0.1:8002/websocket', ['permessage-deflate'])
// 连接成功回调
this.socket.onopen = (event) => {
this.log(`连接已建立,压缩支持:${this.socket.extensions}`)
}
// 接收消息回调
this.socket.onmessage = (event) => {
this.log(`收到消息: ${event.data}`)
}
// 错误处理
this.socket.onerror = (error) => {
debugger
this.log('连接错误: ' + error)
}
// 连接关闭处理
this.socket.onclose = (event) => {
this.log('连接已关闭')
}
},
// 发送消息方法
sendMessage() {
if (!this.message.trim()) return // 空消息过滤
if (this.socket.readyState === WebSocket.OPEN) {
this.socket.send(this.message)
this.log(`已发送: ${this.message}`)
this.message = '' // 清空输入框
} else {
this.log('连接未就绪')
}
},
// 记录日志方法
log(text) {
this.messages.push(text) // 自动触发视图更新
// 自动滚动到底部(可选)
const outputDiv = document.getElementById('output')
if (outputDiv) {
outputDiv.scrollTop = outputDiv.scrollHeight
}
}
},
beforeDestroy() {
// 组件销毁前关闭连接
if (this.socket) {
this.socket.close()
}
}
};
</script>
<style scoped>
/* 修改后的样式 */
#app {
max-width: 600px;
margin: 20px auto;
padding: 20px;
background: #2d3439; /* 新增背景色 */
}
#output {
margin-top: 20px;
height: 900px;
overflow-y: auto;
border: 1px solid #3d4a52; /* 调整边框颜色 */
padding: 10px;
background: #1e2327; /* 深色背景 */
border-radius: 8px; /* 添加圆角 */
}
p {
margin: 5px 0;
padding: 8px 12px;
color: #ffffff; /* 白色文字 */
background: #2d3439; /* 消息背景 */
border-radius: 4px; /* 圆角效果 */
border-bottom: 1px solid #3d4a52; /* 调整分割线 */
}
/* 滚动条样式 */
#output::-webkit-scrollbar {
width: 8px;
}
#output::-webkit-scrollbar-track {
background: #1e2327;
}
#output::-webkit-scrollbar-thumb {
background: #3d4a52;
border-radius: 4px;
}
</style>