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> {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();//websocket 基于http协议,所以要有http编解码器pipeline.addLast(new HttpServerCodec());//对写大数据流的支持pipeline.addLast(new ChunkedWriteHandler());//对httpMessage进行聚合,聚合成fullHttpRequest或fullHttpResponespipeline.addLast(new HttpObjectAggregator(1024 * 64));//支持websocket,并启用压缩,设置压缩子协议pipeline.addLast(new WebSocketServerProtocolHandler("/websocket", "permessage-deflate", true));// 添加压缩处理器pipeline.addLast(new WebSocketServerCompressionHandler());//自定义的handlerpipeline.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() {// 组件挂载后初始化WebSocketthis.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) => {debuggerthis.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>