UNPKG

agora-react-native-rtm

Version:

React Native around the Agora RTM SDKs for Android and iOS agora

259 lines (243 loc) 7.78 kB
import { LoginOptions, LoginResponse, LogoutResponse, PublishResponse, RTMClient, RenewTokenOptions, RenewTokenResponse, SubscribeResponse, UnsubscribeResponse, } from '../api/RTMClient'; import { RTMClientEventMap } from '../api/RTMEvents'; import { RTMHistory } from '../api/RTMHistory'; import { RTMLock } from '../api/RTMLock'; import { RTMPresence } from '../api/RTMPresence'; import { RTMStorage } from '../api/RTMStorage'; import { RTMStreamChannel } from '../api/RTMStreamChannel'; import { PublishOptions, SubscribeOptions } from '../legacy/AgoraRtmBase'; import { RtmConfig } from '../legacy/IAgoraRtmClient'; import { IRtmClientImpl } from '../legacy/impl/IAgoraRtmClientImpl'; import { DeviceEventEmitter, EVENT_TYPE, EventProcessor, callIrisApi, handleError, wrapRtmResult, } from './IrisRtmEngine'; import { RtmHistoryInternal } from './RtmHistoryInternal'; import { RtmLockInternal } from './RtmLockInternal'; import { RtmPresenceInternal } from './RtmPresenceInternal'; import { RtmStorageInternal } from './RtmStorageInternal'; import { StreamChannelInternal } from './StreamChannelInternal'; export class RtmClientInternal extends RTMClient { private _rtmClientImpl: IRtmClientImpl = new IRtmClientImpl(); static _event_handlers: RTMClientEventMap[] = []; public presence: RTMPresence = new RtmPresenceInternal(); public storage: RTMStorage = new RtmStorageInternal(); public lock: RTMLock = new RtmLockInternal(); public history: RTMHistory = new RtmHistoryInternal(); static _streamChannels: Map<string, StreamChannelInternal> = new Map(); private event_name_map = { linkState: 'onLinkStateEvent', presence: 'onPresenceEvent', message: 'onMessageEvent', storage: 'onStorageEvent', lock: 'onLockEvent', topic: 'onTopicEvent', tokenPrivilegeWillExpire: 'onTokenPrivilegeWillExpire', token: 'onTokenEvent', }; constructor(config: RtmConfig) { super(); if (config?.eventHandler) { Object.entries(config.eventHandler).forEach(([key, value]) => { this.addEventListener(key as keyof RTMClientEventMap, value); }); } const jsonParams = { config: config, toJSON: () => { return { config: config, }; }, }; let result = callIrisApi.call(this, 'RtmClient_create', jsonParams); if (result.result < 0) { throw handleError(result, 'RtmClient_create'); } this._rtmClientImpl.setParameters( JSON.stringify({ 'rtm.app_type': 8, }) ); } async createStreamChannel(channelName: string): Promise<RTMStreamChannel> { let operation = 'createStreamChannel'; try { const status = this._rtmClientImpl.createStreamChannel(channelName); if (status.result < 0) { throw handleError(status, 'createStreamChannel'); } else { const streamChannel = new StreamChannelInternal(channelName); RtmClientInternal._streamChannels.set(channelName, streamChannel); return streamChannel; } } catch (error) { throw handleError(error, operation); } } release(): number { RtmClientInternal._event_handlers = []; this.removeAllListeners(); const ret = this._rtmClientImpl.release(); return ret; } addEventListener<EventType extends keyof RTMClientEventMap>( eventType: EventType, listener: RTMClientEventMap[EventType] ): void { const callback = (eventProcessor: EventProcessor<any>, data: any) => { if (eventProcessor.type(data) !== EVENT_TYPE.RTMEvent) { return; } eventProcessor.func.map((it) => { it({ [eventType]: listener }, eventType, data); }); }; // @ts-ignore listener!.agoraCallback = callback; const eventName = this.event_name_map[eventType] || eventType; DeviceEventEmitter.addListener(eventName, callback); } removeEventListener<EventType extends keyof RTMClientEventMap>( eventType: EventType, listener?: RTMClientEventMap[EventType] ) { DeviceEventEmitter.removeListener( eventType, // @ts-ignore listener?.agoraCallback ?? listener ); } removeAllListeners<EventType extends keyof RTMClientEventMap>( eventType?: EventType ) { RtmClientInternal._event_handlers = []; DeviceEventEmitter.removeAllListeners(eventType); } async login(options?: LoginOptions): Promise<LoginResponse> { const token = options?.token || ''; let operation = 'login'; let callBack = 'onLoginResult'; try { const status = this._rtmClientImpl.login(token); let result = await wrapRtmResult(status, operation, callBack); return result; } catch (error) { throw handleError(error, operation); } } async logout(): Promise<LogoutResponse> { let operation = 'logout'; let callBack = 'onLogoutResult'; try { const status = this._rtmClientImpl.logout(); let result = await wrapRtmResult(status, operation, callBack); return result; } catch (error) { throw handleError(error, operation); } } async publish( channelName: string, message: string | Uint8Array, options?: PublishOptions ): Promise<PublishResponse> { let operation = 'publish'; let callBack = 'onPublishResult'; try { const status = this._rtmClientImpl.publish( channelName, message, message.length, options ? options : new PublishOptions() ); let result = await wrapRtmResult(status, operation, callBack); return { ...result, channelName, }; } catch (error) { throw handleError(error, operation); } } async subscribe( channelName: string, options?: SubscribeOptions ): Promise<SubscribeResponse> { let operation = 'subscribe'; let callBack = 'onSubscribeResult'; try { const status = this._rtmClientImpl.subscribe( channelName, options ? options : new SubscribeOptions() ); let result = await wrapRtmResult(status, operation, callBack); return { ...result, channelName, }; } catch (error) { throw handleError(error, operation); } } async unsubscribe(channelName: string): Promise<UnsubscribeResponse> { let operation = 'unsubscribe'; let callBack = 'onUnsubscribeResult'; try { const status = this._rtmClientImpl.unsubscribe(channelName); let result = await wrapRtmResult(status, operation, callBack); return { ...result, channelName, }; } catch (error) { throw handleError(error, operation); } } async renewToken( token: string, options?: RenewTokenOptions ): Promise<RenewTokenResponse> { let operation = 'renewToken'; let callBack = 'onRenewTokenResult'; try { if (!options) { const status = this._rtmClientImpl.renewToken(token); let result = await wrapRtmResult(status, operation, callBack); return result; } else { const channelName = options.channelName; if (!channelName) { throw handleError(new Error('Channel name is required'), operation); } if (!RtmClientInternal._streamChannels.has(channelName)) { throw handleError(new Error('Stream channel not found'), operation); } const status = RtmClientInternal._streamChannels .get(channelName)! .renewToken(token); let result = await wrapRtmResult(status, operation, callBack); return result; } } catch (error) { throw handleError(error, operation); } } setParameters(parameters: string): number { return this._rtmClientImpl.setParameters(parameters); } }