/** * Copyright (c) 2018-2019, Jie Li 李杰 ([email protected]). * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.momo.netty.service; import com.google.common.collect.Maps; import com.momo.netty.utils.*; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Map; /** * @Description: 处理消息的handler * TextWebSocketFrame: 在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体 */ @Slf4j @Component(value = "chatHandler") public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { private NettyHandlerService nettyHandlerService; public ChatHandler(NettyHandlerService nettyHandlerService) { this.nettyHandlerService = nettyHandlerService; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //首次连接是FullHttpRequest,处理参数 if (msg instanceof FullHttpRequest) { FullHttpRequest request = (FullHttpRequest) msg; String uri = request.uri(); Map paramMap = getUrlParams(uri); //如果url包含参数,需要处理 if (uri.contains("?")) { String newUri = uri.substring(0, uri.indexOf("?")); request.setUri(newUri); } Object obj = paramMap.get("token"); if (null == obj || "undefined".equals(obj)) { ctx.channel().close(); return; } ChannelManager.putChannel(ChannelManager.channelLongText(ctx), ctx.channel()); } else if (msg instanceof TextWebSocketFrame) { //正常的TEXT消息类型 // TextWebSocketFrame frame = (TextWebSocketFrame) msg; } super.channelRead(ctx, msg); } @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { nettyHandlerService.refreshToken(ctx, msg.text()); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { ctx.channel().close(); nettyHandlerService.onlineCount("-"); ChannelManager.removeChannel(ChannelManager.channelLongText(ctx)); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { nettyHandlerService.onlineCount("-"); ChannelManager.putChannel(ChannelManager.channelLongText(ctx), ctx.channel()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { String channelId = ChannelManager.channelLongText(ctx); Long UserId = ChannelManager.getUserId(channelId); log.error("netty channel error baseId {} channelId{} {} {}", UserId, channelId, cause.getMessage(), cause); nettyHandlerService.onlineCount("-"); ChannelManager.channelClose(channelId, UserId); ctx.channel().close(); } private static Map<String, String> getUrlParams(String url) { Map<String, String> map = Maps.newHashMap(); url = url.replace("?", ";"); if (!url.contains(";")) { return map; } if (url.split(";").length > 0) { String[] arr = url.split(";")[1].split("&"); for (String s : arr) { String key = s.split("=")[0]; String value = s.split("=")[1]; map.put(key, value); } return map; } else { return map; } } }