자주 묻는 질문
대기실 관리
Q. 대기실에 적용 가능한 이미지의 사이즈가 궁금해요.
A. 이미지의 해상도나 가로·세로 비율에 대한 제한은 없으나 업로드 가능한 최대 용량은 2MB입니다. 이미지 영역의 비율이나 모양은 변경할 수 없으므로 편집 시 크롭 박스 형태가 고정됩니다.
대기 시스템
Q. 진입 허용 수가 제한하는 것은 동시 접속자와 총 접속자 중 무엇인가요?
A. 동시 접속자 수입니다. 자세한 내용은 기본 제어 세그먼트의 진입 허용 수 설정을 참조하세요.
Q. 한 대기자가 여러 브라우저나 탭으로 접속한 경우 다른 대기 번호를 배정 받나요?
A. 같은 순번으로 배정됩니다.
Q. 대기열이 움직이는 기준은 무엇인가요?
A. 앞선 대기자의 작업 완료 또는 대기열 이탈입니다.
세그먼트 설정
Q. 대기 순번 유지 설정을 실시간으로 변경할 수 있나요?
A. 네! 대기 순번 유지 설정은 실시간으로 적용됩니다. 변경 사항은 세그먼트 재시작이나 서비스 중단 없이 즉시 적용됩니다.
실시간 업데이트 예시:
- 일시적으로 보존 비활성화: 트래픽이 많은 중에 대기 순번 유지를 끄고 모든 사용자가 대기열을 다시 거치도록 강제
- 보존 기간 조정: 현재 대기 중인 방문자에 영향을 주지 않고 보존 시간을 60초에서 10분으로 변경
- 비상 대기열 재설정: 보존을 비활성화하여 모든 대기 순번을 재설정하여 새로 시작
- 조건부 활성화: 필요에 따라 켜고 끄면서 특정 시간 동안만 보존 활성화
이 유연성을 통해 가동 중단 없이 실시간 조건을 기반으로 대기열 관리 전략을 조정할 수 있습니다.
Q. 진입 패스 설정을 실시간으로 변경할 수 있나요?
A. 네! 진입 패스 설정은 실시간으로 적용됩니다. 변경 사항은 세그먼트 재시작이나 서비스 중단 없이 즉시 적용됩니다.
실시간 업데이트 예시:
- 패스 기간 조정: 더 긴 세션을 수용하기 위해 진입 패스 유효성을 30분에서 2시간으로 변경
- 진입 패스 비활성화: 모든 액세스에서 모든 사용자가 대기실을 거치도록 강제하기 위해 진입 패스를 끔
- 이벤트 중간에 진입 패스 활성화: 진행 중인 이벤트 중에 진입 패스를 활성화하여 돌아오는 방문자의 사용자 경험 향상
- 조건부 패스 제어: 트래픽 패턴 또는 이벤트 단계를 기반으로 진입 패스 활성화/비활성화
이 유연성을 통해 가동 중단 없이 실시간으로 변경되는 조건에 대응하여 액세스 제어 전략을 동적으로 조정할 수 있습니다.
Q. 대기 순번 유지 또는 진입 패스 없이 진입 키 무효화를 사용할 수 있나요?
A. 네, 무효화는 독립적입니다. 그러나 무효화는 대기 순번 유지 및 진입 패스와 함께 사용할 때 최적의 효과를 발휘합니다. 사용자 보호를 언제 우회할지에 대한 세밀한 제어를 제공하기 때문입니다.
Q. 진입 키 무효화를 여러 번 트리거하면 어떻게 되나요?
A. 무효화는 이벤트 기반입니다: 키가 확인되고 무효화 조건을 충족할 때마다 무효화됩니다. 복잡한 시나리오를 위해 여러 무효화 조건(URL + 타이머)을 결합할 수 있습니다.
Q. 이미 활성화한 진입 키 무효화를 비활성화할 수 있나요?
A. 네! 진입 키 무효화 비활성화는 즉시 적용되는 실시간 변경입니다. 무효화된 키는 무효 상태로 유지되지만, 무효화를 비활성화한 후 발급된 새 키는 정상 동작합니다.
Q. 진입 키 무효화는 모든 통합 유형에서 작동하나요?
A. URL 기반 무효화는 UTI(URL 트리거 통합)에서 작동합니다. 타이머 기반 무효화는 모든 통합 유형(UTI 및 CBI)에서 작동합니다.
Q. 대기 키와 진입 키를 별도로 무효화할 수 있나요?
A. 타이머 기반 무효화에서는 사용자 범위 지정 설정을 통해 선택할 수 있습니다:
- 진입한 사용자만: 서비스에 진입한 사용자의 진입 키를 무효화(재발급)합니다. 대기 중인 사용자의 대기 키는 영향받지 않습니다.
- 대기중 사용자부터: 서비스에 진입하거나 진입을 위해 대기 중인 사용자의 대기 키와 진입 키를 모두 무효화(재발급)합니다.
URL 기반 무효화의 경우, 진입 키만 무효화됩니다 (URL에 액세스한 사용자의 진입 키만 무효화).
Q. 담당자 지정을 생성 후 변경할 수 있나요?
A. 네. 세그먼트 설정을 편집하여 언제든지 담당자 지정을 변경할 수 있습니다.
Q. 여러 실무자를 지정할 수 있나요?
A. 네. 하나의 세그먼트에 여러 실무자를 지정할 수 있습니다. 지정된 모든 실무자는 세그먼트를 수정할 수 있습니다.
통합 공통 질문
Q. NetworkError는 어떻게 처리해야 하나요?
A. 사용자에게 알리고 재시도하거나 원래 로직을 진행하세요:
Web Javascript 통합의 경우
function handleNetworkError(response) {
if (confirm('네트워크 오류가 발생했습니다. 다시 시도하시겠습니까?')) {
nfStart(keys, callback); // 재시도
} else {
performOriginalLogic(); // 계속 진행
}
}
Android 통합의 경우
- Kotlin
- Java
private val callback = object : NetfunnelCallback() {
override fun onNetworkError(statusCode: Int, message: String) {
when (statusCode) {
1001 -> {
// 네트워크 연결되지 않음
showNetworkErrorDialog()
}
1002 -> {
// 네트워크 타임아웃 - 재시도
retryWithDelay()
}
}
}
}
private fun retryWithDelay() {
Handler(Looper.getMainLooper()).postDelayed({
Netfunnel.nfStart(projectKey, segmentKey, callback, this)
}, 2000)
}
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
switch (statusCode) {
case 1001:
// 네트워크 연결되지 않음
showNetworkErrorDialog();
break;
case 1002:
// 네트워크 타임아웃 - 재시도
retryWithDelay();
break;
}
}
};
private void retryWithDelay() {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, this);
}, 2000);
}
Q. 키를 반환하는 것을 잊어버리면 어떻게 되나요?
A. 키는 서버 타임아웃에 의해 자동으로 반환될 수 있지만, 이로 인해 병목 현상이 발생할 수 있습니다. 항상 명시적으로 반환하세요:
Web Javascript 통합의 경우
// 추천: 항상 키 반환
nfStart(keys, function(response) {
if (response.status === 'Success') {
performAction()
.then(() => nfStop(keys))
.catch(() => nfStop(keys)); // 오류 발생 시에도 반환
}
});
Android 통합의 경우
- Kotlin
- Java
// 추천: 항상 키 반환
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
performAction()
.onSuccess {
Netfunnel.nfStop(projectKey, segmentKey, completeCallback)
}
.onFailure {
Netfunnel.nfStop(projectKey, segmentKey, completeCallback) // 에러가 발생해도 반환
}
}
}
// 추천: 항상 키 반환
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
performAction()
.onSuccess(() -> {
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback);
})
.onFailure(() -> {
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback); // 에러가 발생해도 반환
});
}
};
Q. NetFUNNEL 통합을 어떻게 디버깅하나요?
A. 로깅을 활성화하고 콘솔을 확인하세요:
Web Javascript 통합의 경우
<script
src="https://agent-lib.stclab.com/agents/client/javascript/netfunnel-javascript-agent.js"
data-nf-client-id="your-client-id"
data-nf-print-log="true"
></script>
이후 DevTools 콘솔에서 NetFUNNEL 로그 메시지를 확인하세요.
Android 통합의 경우
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
printLog = true // 로깅 활성화
)
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
이후 Logcat에서 NetFUNNEL 로그 메시지를 확인하세요.
Q. URL 트리거와 코드 기반 방법을 모두 사용할 수 있나요?
A. 네, 단일 서비스 내에서 두 방법을 함께 사용할 수 있습니다:
- URL 트리거를 페이지 진입 속도 제어에 사용
- 코드 기반을 비즈니스 동시 사용자 수 제어에 사용
// 랜딩 페이지 보호를 위한 URL 트리거
// (콘솔에서 구성)
// 로그인을 위한 기본 제어
function handleLogin() {
Netfunnel.nfStart("login_project", "login_segment", loginCallback);
}
// 결제를 위한 구간 제어
function startCheckout() {
Netfunnel.nfStartSection("checkout_project", "checkout_segment", checkoutCallback);
}
일반적인 패턴:
- 페이지 진입 보호를 위해 URL 트리거 통합 사용
- 진입점(로그인, 주요 기능)에 기본 제어 (코드 기반 통합) 사용 - 화면 로드 후 빠른 키 반환
- 중요한 프로세스(결제, 결제 처리)에 구간 제어 (코드 기반 통합) 사용 - 전체 프로세스 완료까지 키 보유
그러나 운영 복잡성을 줄이기 위해 하나의 방법을 우선적으로 사용하는 것이 권장됩니다.
Q. 기본 제어와 구간 제어의 차이점은 무엇인가요?
A.
- 기본 제어: 진입 속도를 제한합니다 (사용자가 얼마나 빨리 진입할 수 있는지)
- 구간 제어: 고정된 동시 사용자 수를 유지합니다 (동시에 활성화될 수 있는 사용자 수)
간단한 진입 제한에는 기본 제어를 사용하고, 특정 동시성 수준을 유지하려면 구간 제어를 사용하세요.
자세한 내용은 제어 유형 비교를 참고하세요.
Q. 같은 앱에서 기본 제어와 구간 제어를 모두 사용할 수 있나요?
A. 예, 같은 애플리케이션에서 두 방법을 모두 사용할 수 있습니다:
iOS
- Swift
- Objective-C
// 로그인을 위한 기본 제어
func handleLogin() {
Netfunnel.shared.nfStart(projectKey: "login_project", segmentKey: "login_segment")
}
// 체크아웃을 위한 구간 제어
func startCheckout() {
Netfunnel.shared.nfStartSection(projectKey: "checkout_project", segmentKey: "checkout_segment")
}
// 로그인을 위한 기본 제어
- (void)handleLogin {
[[Netfunnel shared] nfStartWithProjectKey:@"login_project" segmentKey:@"login_segment"];
}
// 체크아웃을 위한 구간 제어
- (void)startCheckout {
[[Netfunnel shared] nfStartSectionWithProjectKey:@"checkout_project" segmentKey:@"checkout_segment"];
}
일반적인 패턴:
- 진입점(로그인, 주요 기능)에는 기본 제어 (코드 기반 통합) 사용 - 뷰 컨트롤러 로드 후 빠른 키 반환
- 중요한 프로세스(체크아웃, 결제)에는 구간 제어 (코드 기반 통합) 사용 - 전체 프로세스 완료까지 키 보유
Android
- Kotlin
- Java
// 로그인용 기본 제어
fun handleLogin() {
Netfunnel.nfStart("login_project", "login_segment", loginCallback, this)
}
// 체크아웃용 구간 제어
fun startCheckout() {
Netfunnel.nfStartSection("checkout_project", "checkout_segment", checkoutCallback, this)
}
// 로그인용 기본 제어
public void handleLogin() {
Netfunnel.INSTANCE.nfStart("login_project", "login_segment", loginCallback, this);
}
// 체크아웃용 구간 제어
public void startCheckout() {
Netfunnel.INSTANCE.nfStartSection("checkout_project", "checkout_segment", checkoutCallback, this);
}
일반적인 패턴:
- 진입 지점(로그인, 주요 기능)에는 기본 제어 (코드 기반 통합) 사용 - Activity 로드 후 빠른 키 반환
- 중요한 프로세스(체크아웃, 결제)에는 구간 제어 (코드 기반 통합) 사용 - 전체 프로세스 완료까지 키 보유
Q. NetFUNNEL을 여러 번 초기화할 수 있나요?
A. 아니요, NetFUNNEL은 Application 클래스에서 한 번만 초기화해야 합니다. 여러 번 초기화하면 예기치 않은 동작이 발생할 수 있습니다.
JavaScript 통합
Q. 스크립트를 공통 JS 파일에 넣을 수 있나요?
A. 네, 스크립트를 동적으로 삽입할 수 있습니다:
<script src="./netfunnel.js" defer></script>
// netfunnel.js
var scriptNF = document.createElement("script");
scriptNF.setAttribute("data-nf-client-id", "your-client-id");
scriptNF.src = "https://agent-lib.stclab.com/agents/client/javascript/netfunnel-javascript-agent.js";
document.head.appendChild(scriptNF);
궁금한 질문을 찾을 수 없다면 Javascript 문제 해결을 참고하거나 STCLab 기술지원 팀에 문의하세요.
Android 통합
Q. Fragment에서 NetFUNNEL을 사용할 수 있나요?
A. 예, 하지만 Activity 컨텍스트를 전달해야 합니다:
- Kotlin
- Java
class MyFragment : Fragment() {
fun startNetFUNNEL() {
activity?.let { activity ->
Netfunnel.nfStart(projectKey, segmentKey, callback, activity)
}
}
}
public class MyFragment extends Fragment {
public void startNetFUNNEL() {
Activity activity = getActivity();
if (activity != null) {
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, activity);
}
}
}
궁금한 질문을 찾을 수 없다면 Android 문제 해결을 참고하거나 STCLab 기술지원 팀에 문의하세요.
iOS 통합
Q. 에이전트가 빌드되지 않는 문제가 발생했어요 (잘못된 개인정보 보호 매니페스트)
A. 버전 4.3.2-onprem부터 Apple 정책 변경으로 인해 에이전트의 privacyinfo가 업데이트되었습니다. 최신 에이전트 버전을 사용하고 있는지 확인하세요.
Q. 델리게이트 콜백에서 앱이 충돌하는 문제가 발생했어요
A. 델리게이트 콜백 내부에서 UI를 조작하는 경우, DispatchQueue.main.async를 사용하여 코드가 메인 스레드에서 실행되도록 하세요.
Q. 디버그 로그를 보고 싶어요
A. initialize 함수에서 printLog: true를 설정하여 로그를 활성화하세요. 디버깅 중에만 사용하고 프로덕션 빌드에서는 false로 설정하세요.
Q. 대기실이 나타나지 않는 문제가 발생했어요
A. 진입 허용 수가 0이면 대기실이 나타나야 하며 사용자가 진입할 수 없습니다. 콘솔 → 세그먼트 설정 → 기본 설정 → 진입 허용 수를 0으로 설정하여 대기실이 표시되도록 강제하세요.
Q. 델리게이트 콜백에서 UI를 업데이트하고 싶어요
A. NetFUNNEL 콜백은 비동기입니다. 이러한 콜백 내부에서 UI 요소를 직접 호출하면 앱이 예상치 못하게 동작하거나 충돌할 수 있습니다. UI 업데이트를 위해 항상 메인 큐로 디스패치하세요.
Q. 에이전트 버전을 확인하는 방법이 궁금해요
A. getVersion()을 사용하여 NetFUNNEL iOS 에이전트 버전을 가져옵니다.
궁금한 질문을 찾을 수 없다면 iOS 문제 해결을 참고하거나 STCLab 기술지원 팀에 문의하세요.
Flutter 통합
Q. 디버깅용 로그 메시지를 확인하고 싶어요
A. 디버깅을 위해 NetFUNNEL Flutter 에이전트에서 발생하는 로그 메시지를 확인하는 방법은 다음과 같습니다:
- 초기화 함수의
printLog: true설정 - Flutter 콘솔에서
[NF4]prefix를 가진 로그 확인
await Netfunnel.instance.initialize(
clientId: 'your-client-id',
printLog: true, // 로깅 활성화
);
디버깅 시에는 printLog 값을 true로 사용하길 권장하나, 앱 배포 시 false 사용을 권장합니다.
Q. 환경별 설정을 다르게 하고 싶어요
A. Netfunnel.instance.initialize()의 profile 파라미터를 사용하여 환경별 설정을 적용할 수 있습니다:
// 프로덕션 환경 (도쿄)
await Netfunnel.instance.initialize(
profile: 'prod_tokyo',
clientId: 'your-client-id',
// ...
);
// 프로덕션 환경 (미동부)
await Netfunnel.instance.initialize(
profile: 'prod_us_east',
clientId: 'your-client-id',
// ...
);
Q. HTTP 통신 시 오류가 발생해요
A. NetFUNNEL Flutter 에이전트는 기본적으로 HTTPS 통신을 권장합니다. HTTP 통신을 사용할 경우, 플랫폼에 따른 설정을 통해 HTTP 통신을 허용할 수 있습니다.
Android
android/app/src/main/res/xml/network_security_config.xml 파일 생성:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">{{DOMAIN_URL}}</domain>
</domain-config>
</network-security-config>
android/app/src/main/AndroidManifest.xml 설정 추가:
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
</application>
iOS
ios/Runner/Info.plist 설정 추가:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Q. 에이전트 버전을 확인하고 싶어요
A. 에이전트의 버전을 확인하기 위해 getVersion() 함수를 사용할 수 있습니다:
String version = Netfunnel.instance.getVersion();
print('NetFUNNEL Agent 버전: $version');
| 함수명 | 파라미터 | 반환 값 | 설명 |
|---|---|---|---|
getVersion | N/A | String | NetFUNNEL 에이전트의 버전을 반환(확인)하는 함수 |
궁금한 질문을 찾을 수 없다면 Flutter 문제 해결을 참고하거나 STCLab 기술지원 팀에 문의하세요.