AI 대화 Chat 시그널링 솔루션
IM SDK의 통합
IM SDK의 통합
CocoaPods 자동 로드 방식을 사용하여 IM SDK를 통합하는 것을 권장합니다.
1. CocoaPods를 설치합니다. 터미널 창구에 다음 명령을 입력하세요(Mac에 Ruby 환경이 미리 설치되어 있어야 함):
sudo gem install cocoapods
2. Podfile 파일을 생성합니다. 프로젝트 경로로 이동한 후 다음 명령줄을 입력하면 프로젝트 경로에 한 Podfile 파일이 생성됩니다.
pod init
3. Podfile 파일을 편집합니다. 다음과 같이 Podfile 파일을 설정하세요.
platform :ios, '8.0'source 'https://github.com/CocoaPods/Specs.git'target 'App' do# 완전 버전의 IM SDK를 통합합니다.버전 번호는 '8.1.6129'보다 높아야 합니다.pod 'TXIMSDK_Plus_iOS','8.1.6129'# 또는 볼륨이 축소된 IM SDK( AI 신호 관련 기능만 포함)를 통합합니다.버전 번호는 '8.2.6361'보다 높아야 합니다.pod 'TXIMSDK_Plus_SignalingSDK','8.2.6361'end
4. SDK를 업데이트하고 설치합니다.
터미널 창구에 다음 명령을 입력하여 로컬 라이브러리 파일을 업데이트하고 IM SDK를 설치합니다.
pod install
또는 다음 명령을 사용하여 로컬 라이브러리 버전을 업데이트합니다.
pod update
주의:
IM SDK의 인용
프로젝트 코드에서 SDK를 사용하는 방법에는 두 가지가 있습니다.
Xcode > Build Setting > Header Search Paths에서 SDK 헤더 파일 경로를 설정한 후, 프로젝트가 SDK API를 사용해야 하는 파일에 구체적인 헤더 파일을 도입합니다.#import "ImSDK_Plus.h"
프로젝트가 SDK API를 사용해야 하는 파일에 구체적인 헤더 파일을 도입합니다.
#import <ImSDK_Plus/ImSDK_Plus.h>
SDK(aar) 통합
Gradle 자동 로드 방식을 사용하여 IM SDK를 통합하는 것을 권장합니다.
1. SDK 종속성의 추가.
1.1 app의 build.gradle을 찾아서 repositories에 mavenCentral() 종속성을 추가합니다.
repositories {google()// mavenCentral 저장소의 추가.mavenCentral()}
1.2 다음에 dependencies에 IM SDK 종속성을 추가합니다.
dependencies {// 완전 버전의 IM SDK를 통합합니다.버전 번호는 '8.1.6129'보다 높아야 합니다.api 'com.tencent.imsdk:imsdk-plus:8.1.6129'// 또는 볼륨이 축소된 IM SDK( AI 신호 관련 기능만 포함)를 통합합니다.버전 번호는 '8.2.6361'보다 높아야 합니다.api 'com.tencent.imsdk:signalingsdk:8.2.6361'}
2. App 사용 아키텍처를 지정합니다. defaultConfig에서 App이 사용하는 CPU 아키텍처를 지정합니다(IM SDK 4.3.118 버전부터 armeabi-v7a, arm64-v8a, x86, x86_64 지원).
defaultConfig {ndk {abiFilters "arm64-v8a"}}
3. SDK 동기화합니다. 네트워크가 maven에 연결되는 것 확실시키고 Sync 버튼을 클릭하면 SDK가 자동으로 다운로드되어 프로젝트에 통합됩니다.


App 권한의 설정
AndroidManifest.xml에서 앱 권한을 구성합니다. IM SDK에는 다음 권한이 필요합니다.
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
혼합 규칙의 설정
proguard-rules.pro 파일에서 IM SDK 관련 클래스를 혼합 제외 목록에 추가합니다.
-keep class com.tencent.imsdk.** { *; }
SDK 통합
npm 방식을 통해 IM SDK를 손님의 web 및 미니프로그램에 통합하는 것을 권장합니다.
// 버전 번호는 v3.4.5및 그의 이상npm install @tencentcloud/chat
설명:
동기화 종속 과정에서 문제가 발생하면 npm 소스를 전환한 후 다시 시도하세요.
npm config set registry http://r.cnpmjs.org/
모듈 도입
import TencentCloudChat from '@tencentcloud/chat';
SDK의 초기화
1. 초기화 인터페이스의 호출
// 1. Chat 콘솔에서 애플리케이션 SDKAppID를 가져옵니다.// 2. config 객체의 초기화.V2TIMSDKConfig *config = [[V2TIMSDKConfig alloc] init];// 3. log 출력 레벨의 지정.config.logLevel = V2TIM_LOG_INFO;// 4. V2TIMSDKListener의 이벤트 리스너를 추가합니다. self는 id<V2TIMSDKListener>의 구현 클래스이고 IM SDK의 이벤트를 모니터링할 필요가 없는 경우 이 단계는 생략할 수 있습니다.[[V2TIMManager sharedInstance] addIMSDKListener:self];// 5. IM SDK를 초기화합니다. 이 인터페이스를 호출한 후 즉시 로그인 인터페이스를 호출할 수 있습니다.[[V2TIMManager sharedInstance] initSDK:sdkAppID config:config];
2. 로그인.
NSString *userID = @"your user id";NSString *userSig = @"userSig from your server";[[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{NSLog(@"success");} fail:^(int code, NSString *desc) {// 다음 오류 코드가 반환되면 사용하는 UserSig가 만료되었음을 의미하므로 새로 발급된 UserSig를 사용하여 다시 로그인하십시오.// 1. ERR_USER_SIG_EXPIRED(6206)// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)// 주의: 기타 오류 코드의 경우 여기에서 로그인 인터페이스를 호출하지 마십시오. IM SDK 로그인이 무한 루프에 빠지는 것을 방지하기 위한 것입니다.NSLog(@"failure, code:%d, desc:%@", code, desc);}];
1. 초기화 인터페이스를 호출합니다.
// 1. Chat 콘솔에서 애플리케이션 SDKAppID를 가져옵니다.// 2. config 객체를 초기화합니다.V2TIMSDKConfig config = new V2TIMSDKConfig();// 3. log 출력 레벨을 지정합니다.config.setLogLevel(V2TIMSDKConfig.V2TIM_LOG_INFO);// 4. V2TIMSDKListener의 이벤트 리스너를 추가합니다. sdkListener는 V2TIMSDKListener의 구현 클래스이고 IM SDK의 이벤트를 모니터링할 필요가 없는 경우 이 단계는 생략할 수 있습니다.V2TIMManager.getInstance().addIMSDKListener(sdkListener);// 5. IM SDK를 초기화합니다. 이 인터페이스를 호출한 후 즉시 로그인 인터페이스를 호출할 수 있습니다.V2TIMManager.getInstance().initSDK(context, sdkAppID, config);
2. 로그인.
String userID = "your user id";String userSig = "userSig from your server";V2TIMManager.getInstance().login(userID, userSig, new V2TIMCallback() {@Overridepublic void onSuccess() {Log.i("imsdk", "success");}@Overridepublic void onError(int code, String desc) {// 다음 오류 코드가 반환되면 사용하는 UserSig가 만료되었음을 의미하므로 새로 발급된 UserSig를 사용하여 다시 로그인하십시오.// 1. ERR_USER_SIG_EXPIRED(6206)// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)// 주의: 기타 오류 코드의 경우 여기에서 로그인 인터페이스를 호출하지 마십시오. IM SDK 로그인이 무한 루프에 빠지는 것을 방지하기 위한 것입니다.Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);}});
1. 초기화 인터페이스를 호출합니다.
import TencentCloudChat from '@tencentcloud/chat';let options = {SDKAppID: 0 // 접속 시 0을 Chat 애플리케이션의 SDKAppID로 교체해야 합니다.};// SDK 인스턴스 생성합니다.`TencentCloudChat.create()` 메서드는 동일한 `SDKAppID`에 대해 동일한 인스턴스만 반환합니다.let chat = TencentCloudChat.create(options); // SDK 인스턴스는 일반적으로 chat으로 표시됩니다.chat.setLogLevel(0); // 일반 레벨및 로그 수량이 많은 경우 접속 시 사용을 권장합니다.// chat.setLogLevel(1); // 릴리스 레벨, SDK가 핵심 정보를 출력하며 프로덕션 환경에서 사용을 권장합니다.
2. 로그인.
let promise = chat.login({userID: 'your userID', userSig: 'your userSig'});promise.then(function(imResponse) {console.log(imResponse.data); // 로그인 성공.if (imResponse.data.repeatLogin === true) {// 계정이 이미 로그인되어 있으며, 이번 로그인 작업은 중복 로그인입니다.console.log(imResponse.data.errorInfo);}}).catch(function(imError) {console.warn('login error:', imError); // 로그인 실패에 관련 정보.});
주의:
Real-Time Communication Engine (RTC Engine)와 Chat의
sdkAppId와 secretKey는 동일해야 합니다.메시지를 수신하는 수신자의 Chat은 로그인에 성공해야 하며, 즉 온라인 상태여야 합니다.
수신자의 RTC Engine 계정과 Chat 계정은 동일한
userId여야 합니다(즉, 동일한 userId로 RTC Engine 방에 입장하고 IM에 로그인해야 함).서버 다운스트림 메시지의 수신
IM SDK의 1:1 채팅 사용자 정의 메시지의 수신 기능(iOS & Android / Web & 미니프로그램)을 통해, 클라이언트에서 콜백을 모니터링하여 실시간 자막과 AI 상태 데이터를 받습니다.
type | 설명 |
10000 | 실시간 자막, 번역의 전송 |
10001 | AI 대화 실시간 상태의 전송 |
10010 | 대형 모델 메시지의 투과 |
실시간 자막의 수신
{"type": 10000, // 10000은 실시간 자막 전송을 나타냅니다."sender": "user_a", // 발화자의 userid."receiver": [], // 수신자 userid 목록입니다.해당 메시지는 실제로 방 내에서 브로드캐스트됩니다."payload": {"text":"", // 음성 인식된 텍스트."translation_text":"", // 번역된 텍스트."start_time":"00:00:01", // 이 문장의 시작 시간."end_time":"00:00:02", // 이 문장의 종료 시간."roundid": "xxxxx" // 한 라운드 대화의 고유 식별자."end": true // true인 경우, 이 문장이 완전한 문장임을 나타냅니다.}}
로봇 상태의 수신
{"type": 10001, // 로봇의 상태."sender": "user_a", // 발신자 userid입니다, 여기는 로봇의 id입니다."receiver": [], // 수신자 userid 목록입니다.해당 메시지는 실제로 방 내에서 브로드캐스트됩니다."payload": {"roundid": "xxx", // 한 라운드 대화의 고유 식별자."timestamp": 123"state": 1, // 1 듣는 중 2 생각 중 3 말하는 중 4 중단됨.}}
대형 모델 메시지 투과의 수신
{"type": 10010, // 하행 대형 모델 메시지의 전송."sender": "user_a", // 발신자 userid입니다. 여기는 로봇의 id입니다."receiver": [], // 수신자 userid 목록입니다. 해당 메시지는 실제로 방 내에서 브로드캐스트됩니다."payload": {"id": "uuid", // 메시지 id입니다. uuid 사용 가능하며 문제 해결 시 사용할 수 있습니다."taskid":"xxxxxx", // 해당 ai 대화의 taskid입니다., 선택가 필수한 항목입니다."timestamp": 123 // 타임스탬프입니다.문제 해결 시 사용할 수 있습니다."data": {"key": "value" //업무에서 자체 정의한 json 형식입니다.}}}
코드 예시
// addSimpleMsgListener를 호출하여 이벤트 리스너를 설정합니다.V2TIMManager.sharedInstance().addSimpleMsgListener(listener: self)/// 1:1 채팅 자체 지정 메시지의 수신./// @param msgID 메시지 ID./// @param info 발신자 정보./// @param data 자체 정의 메시지의 바이너리 콘텐츠.func onRecvC2CCustomMessage(_ msgID: String!, sender info: V2TIMUserInfo!, customData data: Data!) {do {if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {print("onRecvGroupCustomMessage: \(jsonObject)")handleMessage(jsonObject)} else {print("The data is not a dictionary.")}} catch {print("Error parsing JSON: \(error)")}}
// addSimpleMsgListener를 호출하여 이벤트 리스너를 설정합니다.V2TIMManager.getInstance().addSimpleMsgListener(sdkListener);/*** 1:1 채팅 자체 정의 메시지의 수신* @param msgID 메시지 ID* @param sender 발신자 정보* @param customData 전송 내용*/public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {Log.i("onRecvC2CCustomMessage", "msgID:" + msgID + ", from:" + sender.getNickName() + ", content:" + new String(customData));try {String jsonString = new String(customData, "UTF-8");JSONObject jsonObject = new JSONObject(jsonString);System.out.println("onRecvGroupCustomMessage: " + jsonObject);handleMessage(jsonObject);} catch (UnsupportedEncodingException e) {System.out.println("The data is not a dictionary.");} catch (JSONException e) {System.out.println("Error parsing JSON: " + e);}}
const onMessageReceived = (event) => {const messageList = event.data;messageList?.forEach((msg) => {if (msg.type === TencentCloudChat.TYPES.MSG_CUSTOM) {console.log('자체 정의 메시지 수신', event);const { data } = msg.payload;try {const jsonData = JSON.parse(data);console.log(`receive custom msg from ${msg.from} data: ${data}`);if (jsonData.type === 10000) {console.log('자막 메시지', jsonData);return;}if (jsonData.type === 10001) {console.log('로봇 상태', jsonData);return;}if (jsonData.type === 10010) {console.log('대형 모델 메시지의 전송', jsonData);return;}} catch (error) {console.error('receive custom msg', data, error);}}});}// 메시지의 리스너chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
설명:
기본적으로 1:1 채팅 자체 정의 메시지를 통해 실시간 자막과 AI 상태 데이터를 수신합니다. 1:1 채팅이 요구 사항을 충족하지 못하는 경우 그룹 채팅 사용자 정의 메시지 채널을 개설해야 합니다. 문의하기을 참조하십시오.
단말에서 업스트림 신호를 전송합니다
자체 정의 신호를 전송하여 ASR 과정을 건너뛰고 AI와 직접 텍스트로 소통하거나, 중단 신호를 보내고 중단시키거나, 또는 대형 모델에 직접 투과 정보를 전송할 수 있습니다.
type | 설명 |
20000 | ai_conversation_chat:AI 대화 텍스트의 전송 |
20001 | ai_conversation_interrupt:수동으로 중단시킵니다 |
20010 | 대형 모델에 투과 정보를 전송합니다 |
업링크 신호를 전송하여 ASR 과정을 건너뛰고 AI와 직접 텍스트로 소통합니다
{"type": 20000,"sender": "user_a", // 발신자 userid입니다. 서버는 해당 userid가 유효한지 확인합니다."receiver": ["user_bot"], // 수신자 userid 목록입니다.로봇 userid만 입력하면 되며, 서버에서 해당 userid의 유효성을 확인합니다."payload": {"id": "uuid", // 메시지 ID입니다.문제 해결 시 uuid를 사용할 수 있습니다."message": "xxx", // 메시지 내용."timestamp": 123, // 타임스탬프입니다.문제 해결에 사용할 수 있습니다."taskid": "v2_20240920_xxxxx",}}
중단 신호를 보내서 중단시킵니다
{"type": 20001,"sender": "userid", // 발신자 userid입니다.서버는 해당 userid가 유효한지 확인합니다."receiver": ["user_bot"], // 수신자 userid 목록입니다.로봇 userid만 입력하면 됩니다."payload": {"id": "uuid", // 메시지 ID입니다.문제 해결 시 uuid를 사용할 수 있습니다."timestamp": 123 // 타임스탬프입니다.문제 해결에 사용할 수 있습니다."taskid": "v2_20240920_xxxxx",}}
대형 모델에 투과 정보를 전송합니다
{"type": 20010,"sender": "userid","receiver": ["robotid"],"payload": {"id": "uuid","taskid": "v2_20240920_xxxxx","timestamp": 1234,"data": {"key": "value" //업무에서 자체 정의한 json 형식입니다}}}
코드 예시
@IBAction func interruptAi(_ sender: UIButton) {let timestamp = Int(Date().timeIntervalSince1970 * 1000)let payload = ["id": userId + "_\(roomId)" + "_\(timestamp)", // 메시지 ID입니다.문제 해결 시 uuid를 사용할 수 있습니다."timestamp”: timestamp, // 타임스탬프입니다. 문제 해결에 사용할 수 있습니다."taskid": aiTaskId,] as [String : Any]let content = ["type": 20001,"sender": userId,"receiver": [botId],"payload": payload] as [String : Any]let contentData = try! JSONSerialization.data(withJSONObject: content, options: [])let contentString = String(data: contentData, encoding: .utf8)!let dataDict = ["service_command": "trtc_ai_service.SendCustomCmdMsg","request_content": contentString] as [String : Any]do {let jsonData = try JSONSerialization.data(withJSONObject: dataDict, options: [])V2TIMManager.sharedInstance().callExperimentalAPI("sendTRTCCustomData", param: jsonData as NSObject) { _ inprint("sendTRTCCustomData success")} fail: { code, desc inprint("sendTRTCCustomData error, \(code), \(desc ?? "null")")}} catch {print("Error serializing dictionary to JSON: \(error)")}}
public void interruptAi() {long timestamp = System.currentTimeMillis();Map<String, Object> payload = new HashMap<>();payload.put("id", userId + "_" + roomId + "_" + timestamp); // 메시지 ID입니다. 문제 해결 시 uuid를 사용할 수 있습니다.payload.put("timestamp", timestamp); // 타임스탬프입니다.문제 해결에 사용할 수 있습니다.payload.put("taskid", aiTaskId);Map<String, Object> content = new HashMap<>();content.put("type", 20001);content.put("sender", userId);content.put("receiver", Collections.singletonList(botId));content.put("payload", payload);String contentString = new JSONObject(content).toString();Map<String, Object> dataDict = new HashMap<>();dataDict.put("service_command", "trtc_ai_service.SendCustomCmdMsg");dataDict.put("request_content", contentString);try {byte[] jsonData = new JSONObject(dataDict).toString().getBytes("UTF-8");V2TIMManager.getInstance().callExperimentalAPI("sendTRTCCustomData", jsonData, new V2TIMValueCallback() {@Overridepublic void onSuccess(Object o) {System.out.println("sendTRTCCustomData success");}@Overridepublic void onError(int code, String desc) {System.out.println("sendTRTCCustomData error, " + code + ", " + (desc != null ? desc : "null"));}});} catch (UnsupportedEncodingException e) {System.out.println("Error serializing dictionary to JSON: " + e);}}
// 중단 신호를 전송합니다.chat.callExperimentalAPI('sendTRTCCustomData', {serviceCommand: 'trtc_ai_service.SendCustomCmdMsg',data: {type: 20001,sender: "user_a", // 발신자 userid입니다.서버는 해당 userid가 유효한지 확인합니다.receiver: ["user_bot"], // 수신자 userid 목록입니다.로봇 userid만 입력하면 됩니다.payload: {id: "uuid", // 메시지 ID입니다.문제 해결 시 uuid를 사용할 수 있습니다.timestamp: 123, // 타임스탬프입니다.문제 해결에 사용할 수 있습니다.taskid: "작업의 taskid"}}});
주의:
type, sender, receiver 및 payload의 taskid, id, timestamp는 꼭 입력해야 하는 항목입니다.