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

com.qq.tars.server.core.ServantAdapter Maven / Gradle / Ivy

There is a newer version: 1.7.2
Show newest version
/**
 * Tencent is pleased to support the open source community by making Tars available.
 *
 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * 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.qq.tars.server.core;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.util.concurrent.Executor;

import com.qq.tars.common.support.Endpoint;
import com.qq.tars.net.core.Processor;
import com.qq.tars.net.core.nio.SelectorManager;
import com.qq.tars.net.util.Utils;
import com.qq.tars.protocol.annotation.ServantCodec;
import com.qq.tars.rpc.exc.TarsException;
import com.qq.tars.rpc.protocol.Codec;
import com.qq.tars.rpc.protocol.ServantProtocolFactory;
import com.qq.tars.rpc.protocol.tars.TarsCodec;
import com.qq.tars.server.config.ConfigurationManager;
import com.qq.tars.server.config.ServantAdapterConfig;
import com.qq.tars.server.config.ServerConfig;

public class ServantAdapter implements Adapter {

    private SelectorManager selectorManager = null;

    private final ServantAdapterConfig servantAdapterConfig;

    private ServantHomeSkeleton skeleton;

    public ServantAdapter(ServantAdapterConfig servantAdapterConfig) {
        this.servantAdapterConfig = servantAdapterConfig;
    }

    public void bind(AppService appService) throws IOException {
        this.skeleton = (ServantHomeSkeleton) appService;
        ServerConfig serverCfg = ConfigurationManager.getInstance().getServerConfig();

        boolean keepAlive = true;
        Codec codec = createCodec(serverCfg);
        Processor processor = createProcessor(serverCfg);
        Executor threadPool = ServantThreadPoolManager.get(servantAdapterConfig);

        Endpoint endpoint = this.servantAdapterConfig.getEndpoint();
        if (endpoint.type().equals("tcp")) {
            this.selectorManager = new SelectorManager(Utils.getSelectorPoolSize(), new ServantProtocolFactory(codec), threadPool, processor, keepAlive, "server-tcp-reactor", false);
            this.selectorManager.setTcpNoDelay(serverCfg.isTcpNoDelay());
            this.selectorManager.start();

            System.out.println("[SERVER] server starting at " + endpoint + "...");
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.socket().bind(new InetSocketAddress(endpoint.host(), endpoint.port()), 1024);
            serverChannel.configureBlocking(false);

            selectorManager.getReactor(0).registerChannel(serverChannel, SelectionKey.OP_ACCEPT);

            System.out.println("[SERVER] server started at " + endpoint + "...");

        } else if (endpoint.type().equals("udp")) {

            this.selectorManager = new SelectorManager(1, new ServantProtocolFactory(codec), threadPool, processor, false, "server-udp-reactor", true);
            this.selectorManager.start();

            System.out.println("[SERVER] server starting at " + endpoint + "...");
            DatagramChannel serverChannel = DatagramChannel.open();
            DatagramSocket socket = serverChannel.socket();
            socket.bind(new InetSocketAddress(endpoint.host(), endpoint.port()));
            serverChannel.configureBlocking(false);

            this.selectorManager.getReactor(0).registerChannel(serverChannel, SelectionKey.OP_READ);
            System.out.println("[SERVER] servant started at " + endpoint + "...");
        }
    }

    public ServantAdapterConfig getServantAdapterConfig() {
        return servantAdapterConfig;
    }

    public ServantHomeSkeleton getSkeleton() {
        return skeleton;
    }

    private Processor createProcessor(ServerConfig serverCfg) throws TarsException {
        Processor processor = null;
        Class processorClass = skeleton.getProcessorClass();
        if (processorClass == null) {
            return new TarsServantProcessor();
        }

        if (processorClass != null) {
            Constructor constructor;
            try {
                constructor = processorClass.getConstructor(new Class[] { ServantAdapter.class });
                processor = constructor.newInstance(this);
            } catch (Exception e) {
                throw new TarsException("error occurred on create codec, codec=" + processorClass.getName());
            }
        }
        return processor;
    }

    private Codec createCodec(ServerConfig serverCfg) throws TarsException {
        Codec codec = null;
        Class codecClass = skeleton.getCodecClass();
        if (codecClass == null) {
            ServantCodec servantCodec = skeleton.getApiClass().getAnnotation(ServantCodec.class);
            if (servantCodec != null) {
                codecClass = servantCodec.codec();
            }
        }

        if (codecClass == null) {
            codecClass = TarsCodec.class;
        }

        if (codecClass != null) {
            Constructor constructor;
            try {
                constructor = codecClass.getConstructor(new Class[] { String.class });
                codec = constructor.newInstance(serverCfg.getCharsetName());
            } catch (Exception e) {
                throw new TarsException("error occurred on create codec, codec=" + codecClass.getName());
            }
        }
        return codec;
    }

    public void stop() {
        if (selectorManager != null) {
            selectorManager.stop();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy