Gaea源码阅读(四):服务端通讯

在(三)中加载server时,将根据配置建立tcp/http/telnet服务。如demo中这三个服务中enable了tcp和telnet。

 

以tcp服务为例,实现类在gaea.server.tcp.implement中配置

<!-- socket server implement class -->
<property>
<name>gaea.server.tcp.implement</name>
<value>com.bj58.spat.gaea.server.core.communication.tcp.SocketServer</value>
</property>

//实现类SocketServer

	/**
	 * start netty server
	 */
	@Override
	public void start() throws Exception {
		logger.info("loading invoker...");
		String invoker = Global.getSingleton().getServiceConfig().getString("gaea.proxy.invoker.implement");
		invokerHandle = (IInvokerHandle) Class.forName(invoker).newInstance();
		logger.info("initing server...");
		initSocketServer();
	}

InvokerHandle提供了同步和异步两种选择,这里配置使用的是异步Handler

<!-- proxy invoker-->
<property>
<name>gaea.proxy.invoker.implement</name>
<value>com.bj58.spat.gaea.server.core.proxy.AsyncInvokerHandle</value>
</property>

initSocketServer建立SocketChannel,Handler使用SocketHandler

        bootstrap.setFactory(new NioServerSocketChannelFactory(
			                        	Executors.newCachedThreadPool(),
			                        	Executors.newCachedThreadPool(),
			                        	Global.getSingleton().getServiceConfig().getInt("gaea.server.tcp.workerCount")
			                        )
        					);
        //使用SocketHandler
        SocketHandler handler = new SocketHandler();
        bootstrap.setPipelineFactory(new SocketPipelineFactory(handler, Global.getSingleton().getServiceConfig().getInt("gaea.server.tcp.frameMaxLength")));

        try {
        	InetSocketAddress socketAddress = null;
        	socketAddress = new InetSocketAddress(Global.getSingleton().getServiceConfig().getString("gaea.server.tcp.listenIP"),
        			Global.getSingleton().getServiceConfig().getInt("gaea.server.tcp.listenPort"));
            Channel channel = bootstrap.bind(socketAddress);
            allChannels.add(channel);
		} catch (Exception e) {}

//SocketHandler处理请求

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
		try {
			logger.debug("message receive");
			ByteBuffer buffer = ((ChannelBuffer)e.getMessage()).toByteBuffer();
			byte[] reciveByte = buffer.array();
			logger.debug("reciveByte.length:" + reciveByte.length);
			
			byte[] headDelimiter = new byte[0];
			System.arraycopy(reciveByte, 0, headDelimiter, 0, 0);
			
			byte[] requestBuffer = new byte[reciveByte.length];
			System.arraycopy(reciveByte, 0, requestBuffer, 0, (reciveByte.length));
			
			GaeaContext gaeaContext = new GaeaContext(requestBuffer,
					new GaeaChannel(e.getChannel()), 
					ServerType.TCP,
					this);
			
			SocketServer.invokerHandle.invoke(gaeaContext);
		} catch(Throwable ex) {
			byte[] response = ExceptionHelper.createErrorProtocol();
			e.getChannel().write(response);
			logger.error("SocketHandler invoke error", ex);
		}
	}

服务器端收到消息后,调用该messageReceived(Netty机制)。在该方法中将转交给invokerHandle.invoke

//AsyncInvokerHandler
	public void invoke(final GaeaContext context) throws Exception {
		logger.debug("-------------------begin async invoke-------------------");
		asyncInvoker.run(taskTimeOut, new IAsyncHandler(){
			@Override
			public Object run() throws Throwable {
				// request filter
				for(IFilter f : Global.getSingleton().getGlobalRequestFilterList()) {
					if(context.getExecFilter() == ExecFilterType.All || context.getExecFilter() == ExecFilterType.RequestOnly) {
						f.filter(context);
					}
				}
				
				//调用
				if(context.isDoInvoke()) {
					if(context.getServerType() == ServerType.HTTP){
						httpThreadLocal.set(context.getHttpContext());
					}
					doInvoke(context);
				}
				
				// response filter
				for(IFilter f : Global.getSingleton().getGlobalResponseFilterList()) {
					if(context.getExecFilter() == ExecFilterType.All || context.getExecFilter() == ExecFilterType.ResponseOnly) {
						f.filter(context);
					}
				}
				return context;
			}

fliter在这里被使用了


doInvoke将使用到(三)中的Proxy工厂类、ProxyStub

			//根据lookup找到ProxyStub
			IProxyStub localProxy = Global.getSingleton().getProxyFactory().getProxy(request.getLookup());

			//invoker real service
			GaeaResponse gaeaResponse = localProxy.invoke(context);
			
                        //返回应答
			response = createResponse(gaeaResponse);


至此,Gaea基本流程基本走了一遍。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值