All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.houbb.config.socket.client.handler.ConfigClientHandler Maven / Gradle / Ivy

/*
 * Copyright (c)  2019. houbinbin Inc.
 * rpc All rights reserved.
 */

package com.github.houbb.config.socket.client.handler;

import com.alibaba.fastjson.JSON;
import com.github.houbb.config.socket.client.support.channel.ClientChannelManager;
import com.github.houbb.config.socket.client.support.invoke.InvokeService;
import com.github.houbb.config.socket.client.support.listener.ConfigNotifyListener;
import com.github.houbb.config.socket.common.constant.ServiceNameConst;
import com.github.houbb.config.socket.common.req.ConfigNotifyBatchReq;
import com.github.houbb.config.socket.common.req.ConfigNotifyReq;
import com.github.houbb.config.socket.common.rpc.RpcMessageDto;
import com.github.houbb.config.socket.common.util.ChannelUtil;
import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.houbb.log.integration.core.Log;
import com.github.houbb.log.integration.core.LogFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * 

客户端处理类

* * TODO: ChannelInboundHandlerAdapter 学习一下对应的方法,然后处理各种场景。 * *
 Created: 2019/10/16 11:30 下午  
*
 Project: rpc  
* * @author houbinbin * @since 0.0.2 */ public class ConfigClientHandler extends SimpleChannelInboundHandler { private static final Log log = LogFactory.getLog(ConfigClientHandler.class); /** * 调用管理类 */ private InvokeService invokeService; /** * 通知监听类 */ private ConfigNotifyListener listener; /** * 客户端 channel 管理类 * @since 1.5.0 */ private ClientChannelManager clientChannelManager; public ConfigClientHandler invokeService(InvokeService invokeService) { this.invokeService = invokeService; return this; } public ConfigClientHandler listener(ConfigNotifyListener listener) { this.listener = listener; return this; } public ConfigClientHandler clientChannelManager(ClientChannelManager clientChannelManager) { this.clientChannelManager = clientChannelManager; return this; } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { log.info("客户端注册-----------------------"); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { log.info("客户端注销-----------------------"); clientChannelManager.unRegister(ctx.channel()); super.channelInactive(ctx); } @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf)msg; byte[] bytes = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(bytes); String text = new String(bytes); log.info("[Client] channelId {} 接收到消息 {}", ChannelUtil.getChannelId(ctx), text); RpcMessageDto rpcMessageDto = null; try { rpcMessageDto = JSON.parseObject(bytes, RpcMessageDto.class); } catch (Exception exception) { log.error("RpcMessageDto json 格式转换异常 {}", JSON.parse(bytes)); return; } final String methodType = rpcMessageDto.getMethodType(); final String json = rpcMessageDto.getJson(); if(rpcMessageDto.isRequest()) { // 请求类接口,根据 serviceName 做路由 if(ServiceNameConst.SERVER_CONFIG_NOTIFY.equals(methodType)) { ConfigNotifyReq notifyReq = JSON.parseObject(json, ConfigNotifyReq.class); listener.configNotify(notifyReq); } else if(ServiceNameConst.SERVER_CONFIG_NOTIFY_BATCH.equals(methodType)) { ConfigNotifyBatchReq notifyReq = JSON.parseObject(json, ConfigNotifyBatchReq.class); listener.configNotifyBatch(notifyReq); } else { log.warn("不支持的方法类型 {}", methodType); } } else { // 丢弃掉 traceId 为空的信息 if(StringUtil.isBlank(rpcMessageDto.getTraceId())) { log.info("[Server] response traceId 为空,直接丢弃", JSON.toJSON(rpcMessageDto)); return; } invokeService.addResponse(rpcMessageDto.getTraceId(), rpcMessageDto); log.info("[Client] response is :{}", JSON.toJSON(rpcMessageDto)); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 每一次如果都关闭,会导致长链接丢失。 // 最简单的方法是保持不关闭。 // 同时把服务端,当做注册中心。当然,也可以单独写一个注册中心。 String id = ChannelUtil.getChannelId(ctx.channel()); log.error("[Rpc client] {} meet ex", id, cause); ctx.flush(); // ctx.close(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { // 每次用完要关闭,不然拿不到response,我也不知道为啥(目测得了解netty才行) // 个人理解:如果不关闭,则永远会被阻塞。 ctx.flush(); // ctx.close(); final String id = ChannelUtil.getChannelId(ctx.channel()); log.info("{} channelReadComplete", id); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy