1.主要采用了Netty的什么功能
webSocket的wss 复制代码
//wss配置 @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(1024 * 1024)); pipeline.addLast(new ChunkedWriteHandler()); // pipeline.addLast(new HttpRequestHandler("/ws")); pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true, 1024 * 512)); // pipeline.addLast(new HeartbeatServerHandler()); pipeline.addLast(new TextWebSocketFrameHandler()); // 配置ssl访问的 logger.info(WebsocketChatServerInitializer.class.getResource("/").toString()); URL xmlpath = this.getClass().getClassLoader().getResource(""); logger.info(xmlpath.toString()); // File f = new File(this.getClass().getResource("/").getPath()); File f = new File(WebsocketChatServerInitializer.class.getResource("").toString()); logger.info(f.getAbsolutePath()); SSLContext sslContext = SslUtil.createSSLContext("PKCS12", this.getClass().getClassLoader().getResourceAsStream("keystore.p12"), "changeit"); SSLEngine engine =sslContext.createSSLEngine(); SSLEngine sslEngine = sslContext.createSSLEngine(); sslEngine.setNeedClientAuth(false); sslEngine.setUseClientMode(false); pipeline.addFirst(new SslHandler(sslEngine)); } 复制代码
2.WEB聊天的基本流程和一些限制
2.1消息采用wss发送 2.2首先前端用户先在服务端登录,获取token,然后连接websocket绑定服务端. 为了防止恶意连接保存token的时候时候key为:前缀_用户名 2.3服务端校验token后会保存一个键值对,用户名:Channel 为了防止恶意信息的发送,在发送消息的时候会根据用户名获取Channel,然后当前的Channel和获取到的Channel可以做个比对,这样用户就是正常用户了 2.4web端绑定了服务端后可以进行消息的收发,消息格式为JSON Netty服务端主要通过保存的Channel获取连接,然后做信息转发推送 2.5配置个后台管理的模块,对用户进行强制管理,后消息广播 复制代码
3.消息格式
整体格式 { "cmd":null, "mdChild":ull, "from":null, "accept":null, "group":null, "msg":null, "status":null, "id":null, "createDate":"2021-01-09 22:26:14", "chatSet":null, "groupSet":null, "oldMsg":null } 单聊 { "cmd":"3", "from":{ "userCode":"dnmt" }, "accept":{ "userCode":"fhx" }, "msg":"单聊测试" } 群聊 { "cmd":"4", "from":{ "userCode":"dnmt" }, "group":{ "groupCode":"g003" }, "msg":"群聊测试" } 复制代码
4服务端的扩展
3.1因为当用户量变大,服务端可能处理有些跟不上。 这里可以采用的是服务端集群部署。 3.2集群部署问题 消息的转发可能会跨服务器进行推送? 用户的跨服务器绑定? 3.3netty集群解决跨服务器消息推送思路 采用redis的发布和订阅进行消息的转发,当前获取订阅消息判断用户是否存在,如果存在就进行消息处理。 3.4用户的跨服务器绑定。 这里用到了zookeeper 当服务器启动的时候,会把服务器的连接信息发送到zookeeper上 当用户登录的时候,可以根据一个简单的负载均衡算法(随机、或者最小)获取netty服务器的绑定信息,然后绑定到后端服务器。 3.5进一步性能提升 服务端在处理转发消息的时候,采用线程池处理。 复制代码
5.以玩转的地方
1.支持了WEB的语音、和视频聊天 刚开始的时候是采用了peerjs的WEBRTC方式,进行的视频聊天,但是对node不了解和感觉这样不可控,采用了下面的方式。 2.通过WEBRTC的浏览器音频,视频录制功能,定时获取到数据,然后进行base64编码进行数据传输,转发到web端解码进行音视频聊天。 3.在视频聊天的时候,可以借助opencv进行一些对视频的操作(这里是我开始学习opencv的地方) 简单的例子:视频中人脸识别的思路,首先提取视频文件的音频(ffmpeg),然后对视频跳帧(主要想提高点速度)的处理获取每帧的图片,处理完毕后提取的音频和新的视频文件合并,然后编码进行视频流转发 复制代码