private static String mapStreamType(Method method) {
        Class<?>[] paramClasses = method.getParameterTypes();
        Class<?> returnClass = method.getReturnType();

        int paramLen = paramClasses.length;

        //BidirectionalStream & ClientStream
        if (paramLen > 0 && SofaStreamObserver.class.isAssignableFrom(paramClasses[0]) && SofaStreamObserver.class.isAssignableFrom(returnClass)) {
            if (paramLen > 1) {
                throw new SofaRpcException(RpcErrorType.CLIENT_CALL_TYPE, "Bidirectional/Client stream method parameters can be only one StreamHandler.");
            }
            return RpcConstants.INVOKER_TYPE_BI_STREAMING;
        }
        //ServerStream
        else if (paramLen > 1 && SofaStreamObserver.class.isAssignableFrom(paramClasses[paramLen -1]) && void.class == returnClass) {
            return RpcConstants.INVOKER_TYPE_SERVER_STREAMING;
        } else if (SofaStreamObserver.class.isAssignableFrom(returnClass) || Arrays.stream(paramClasses).anyMatch(SofaStreamObserver.class::isAssignableFrom)) {
            throw new SofaRpcException(RpcErrorType.CLIENT_CALL_TYPE, "SofaStreamObserver can only at the specified location of parameter.Please check related docs.");
        }
        return null;
    }
Gets the stream call type of certain method

@param method the method
@return call type,server/client/bidirectional stream or default value. If not mapped to any stream call type, use the default value
remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/utils/SofaProtoUtils.java