'use strict'; import {EventEmitter2} from "eventemitter2"; import logger from './utils/logger'; import Utils from './utils/utils'; import ChannelH5 from "./channelh5"; import Globallets from "./utils/globalvars"; import Udb from "./utils/udb"; import MetricsUtil from "./utils/metricsUtil"; class NewH5 { private observer: EventEmitter2; version: number = 1811221520; svn: number = 2322262; h5_g_globals: Globallets; h5_g_chlH5: ChannelH5; /** * sdk入口 * @param appid 业务id * @param domain 业务主站一级域名 * @param thirdUdbAppId udb分配的第三方appid(小程序项目使用) * @param wxAppid 小程序项目id(小程序项目使用) * @param apDomain 业务侧设置的自定义ap域名,如果不设置则用默认的 */ constructor(appid: number, domain: string, thirdUdbAppId: string="", wxAppid: string="", apDomain: string="") { this.observer = new EventEmitter2(); this.h5_g_globals = new Globallets(); // console.log('constructor', MetricsUtil) // MetricsUtil.report(111, "svc_login", "", "", 222, 333); if (!appid || !domain) { logger.error("new NewH5 parameters error! \"appid\" and \"domain\" are all required!" + JSON.stringify(arguments)); return; } //小程序环境。页面的脚本逻辑是在 JsCore 中运行, JsCore 是一个没有窗口对象的环境,所以不能在脚本中使用 window ,也无法在脚本中操作组件 if (typeof(window) == 'undefined') { if (!thirdUdbAppId || !wxAppid) { logger.error("new NewH5 parameters error! \"thirdUdbAppId\" and \"wxAppid\" are all required!" + JSON.stringify(arguments)); return; } this.h5_g_globals.isMiniProgram = true; this.h5_g_globals.bShareAnonymousUid = false; //小程序环境不允许共享匿名uid } //从cookie中获取uid和udb_c let uid = parseInt(Utils.getCookie("osudb_uid", this.h5_g_globals.isMiniProgram)); let udb_c = Utils.getCookie("osudb_c", this.h5_g_globals.isMiniProgram); /** * 1、非小程序环境,如果能从本地cookie里读到osudb_uid和osudb_c,就认为是实名用户;否则是匿名用户,先进行匿名会话流程。用户登录后(业务侧处理),业务侧会在本地cookie写入osudb_uid和osudb_c * 然后业务侧调用login接口,sdk从本地cookie中读出osudb_uid和osudb_c,开始实名会话流程 * 2、小程序环境,如果能从微信cookie里读到osudb_uid和osudb_c,就认为是实名用户;否则是匿名用户,先进行匿名会话流程,并且尝试小程序登录,成功后开始实名会话流程,失败则继续进行匿名会话流程 */ if (!udb_c || !uid) { uid = 0; this.h5_g_globals.userType = 0; if (this.h5_g_globals.isMiniProgram) { this.loginUdb(domain, thirdUdbAppId, wxAppid); } } else { this.h5_g_globals.userType = 1; } this.h5_g_globals.uid = uid; this.h5_g_globals.credit = udb_c; this.h5_g_globals.appid = appid; this.h5_g_globals.domain = domain; //一个页面调用一次NewH5接口即可,不要多次调用 logger.warn("new NewH5 version=" + this.version + ' svn=' + this.svn + ' userType=' + this.h5_g_globals.userType + ' isMiniProgram=' + this.h5_g_globals.isMiniProgram + ' arguments=' + JSON.stringify(arguments) + ' uid=' + uid + ' credit=' + udb_c); if (!this.h5_g_chlH5) { this.h5_g_chlH5 = new ChannelH5(this, apDomain); } this.h5_g_chlH5.start(); //listen browser beforeunload event if (!this.h5_g_globals.isMiniProgram) { window.addEventListener('beforeunload', this.onWindowBeforeUnload.bind(this)); } else { //TODO 小程序的onUnload由业务侧处理? } } on(event, listener) { this.observer.on(event, listener); } off(event, listener) { this.observer.removeListener(event, listener); } trigger(event, ...data) { setTimeout(() => this.emit(event, ...data), 0); } emit(event, ...data) { this.observer.emit(event, event, ...data); } onWindowError(errorMsg, url, lineNumber) { logger.warn('onWindowError errorMsg=' + errorMsg + ' url=' + url); } onWindowBeforeUnload(event) { this.stop(); } /** * 小程序环境使用,驱动sdk登录udb获取credit等内容 * @param domain 业务一级域名 * @param thirdUdbAppId * @param wxAppid */ loginUdb(domain: string, thirdUdbAppId: string, wxAppid: string) { if (!this.h5_g_globals.isMiniProgram) { logger.warn('NewH5.loginUdb is available in MiniProgram only!!!'); return; } Udb.udbLogin(domain, thirdUdbAppId, wxAppid).then(res => { logger.warn('NewH5.loginUdb thirdparty loginudb success') this.h5_g_globals.uid = res.osudb_uid; this.h5_g_globals.credit = res.osudb_c; this.h5_g_globals.userType = 1; this.login(); //转入实名会话流程 }); // .catch(err => { // logger.error('NewH5.loginUdb thirdparty loginudb failed:' + JSON.stringify(err)); // this.h5_g_globals.userType = 0; // }); } //发送业务数据,obj.data是Uint8Array sendAppData(obj):Promise { if (this.h5_g_chlH5) { return this.h5_g_chlH5.sendAppData(obj); } } //这命名很蛋疼,作用其实是把obj.struct序列化,填充到obj.data,然后通过ap route sendAppSender(obj) { if (this.h5_g_chlH5) { return this.h5_g_chlH5.sendAppSender(obj); } } /** * 进频道,返回Promise,支持链式调用 * @param obj */ joinChannel(obj):Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.joinChannel(obj); } } /** * 退频道,返回Promise,支持链式调用 */ leaveChannel():Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.leaveChannel(); } } /** * 发送公屏消息,返回Promise,支持链式调用 * @param obj */ sendChatMsg(obj):Promise { if (this.h5_g_chlH5) { if (!!obj.extProps && !Utils.isMap(obj.extProps)) { logger.error("NewH5.sendChatMsg extProps must be a Map"); return Promise.reject({errMsg: "extProps must be a Map"}); } return this.h5_g_chlH5.sendChatMsg(obj); } } /** * 订阅或退订广播组,返回Promise,支持链式调用 * @param obj */ subscribeBcGroup(obj):Promise { if (this.h5_g_chlH5) { return this.h5_g_chlH5.subscribeBc(obj); } } /** * 查询用户信息,返回Promise,支持链式调用 * @param uids */ getUserInfo(uids: Array):Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.getUserInfo(uids); } } /** * 查询频道信息,返回Promise,支持链式调用 */ getChannelInfo():Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.getChannelInfo(); } } /** * 是否匿名用户 */ isGuestLogin():boolean { if (this.h5_g_chlH5) { return this.h5_g_chlH5.isGuestLogin(); } } /** * 是否在频道内 */ isInChannel():boolean { if (this.h5_g_chlH5) { return this.h5_g_chlH5.isInChannel(); } } /** * 获取微信本地的udbInfo,返回Promise,支持链式调用 */ getUdbInfo():Promise<{}> { if (!this.h5_g_globals.isMiniProgram) { logger.warn('NewH5.getUdbInfo is available in MiniProgram only!!!'); return Promise.reject('NewH5.getUdbInfo is available in MiniProgram only!!!');; } let udbInfo = Utils.getCookie("osudbInfo", this.h5_g_globals.isMiniProgram); if (udbInfo) { return Promise.resolve(udbInfo); } return Promise.reject('osudbInfo not exists in wx cookie!!!'); } start() { if (this.h5_g_chlH5) { this.h5_g_chlH5.start(); } } /** * 停止服务,具体包括:退频道,清空globalvars,并断掉ws连接 */ stop() { if (this.h5_g_chlH5) { this.leaveChannel(); if (this.h5_g_globals.uid != 0) { this.h5_g_chlH5.stop(Utils.number2ProtoUInt64(this.h5_g_globals.uid), "Graceful exit!"); } } } /** * 登录,返回Promise,支持链式调用 */ login():Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.login(); } } /** * 登出,仅用于实名logout至匿名 * @param notDelCookie 不删除cookie标识 */ logout(notDelCookie:boolean):Promise<{}> { if (this.h5_g_chlH5) { return this.h5_g_chlH5.logout(notDelCookie); } } /** * 查询个人信息,返回Promise,支持链式调用 */ myInfo():Promise<{}> { return Promise.resolve({ uid: this.h5_g_globals.uid, instanceId: this.h5_g_globals.instId, isAnonymous: this.h5_g_globals.userType == 0, appid: this.h5_g_globals.appid, domain: this.h5_g_globals.domain, topSid: this.h5_g_globals.topSid, subSid: this.h5_g_globals.subSid }); } /** * 注册回调 * @param cb */ setCallback(cb: Function) { if (this.h5_g_chlH5) { this.h5_g_chlH5.setCallback(cb); } } /** * ws通道是否可用 * 与ap的ws connected && logined ap => true; 否则false */ isWsChannelReady():boolean { if (this.h5_g_chlH5) { this.h5_g_chlH5.isWsChannelReady(); } return false; } /** * 设置Metrics系统专用的服务名称 */ setScode(scode: number) { if (!Utils.isNumber(scode)) { logger.error("NewH5.setScode scode must be a number"); return; } if (scode <= 0) { scode = 0; } logger.warn("NewH5.setScode scode=" + scode); this.h5_g_globals.scode = scode; } /** * 匿名情况下,同个浏览器开多个tab页,设置是否允许共享匿名uid。默认共享,可在一定程度上防止刷人气 * @param flag */ shareAnonymousUid(flag: boolean) { if (this.h5_g_globals.isMiniProgram) { logger.warn('NewH5.shareAnonymousUid is not available in MiniProgram!!!'); return; } this.h5_g_globals.bShareAnonymousUid = flag; logger.log("NewH5.shareAnonymousUid flag=" + flag); } setDefaultHeader(header: Map) { if (!Utils.isMap(header)) { logger.error("NewH5.setDefaultHeader argument should be a map!!!"); return; } for (let [k, v] of header) { this.h5_g_globals.defaultHeaderMap.set(k, v); //copy一份 } } /** * svn版本号,业务展示用 */ get sdkVersion():number { return this.svn; } } export default NewH5;