提交 ac70326b 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

more graceful to check injectio and exceptions

上级 5b903d27
......@@ -438,7 +438,7 @@ Github Issue - https://github.com/zixia/wechaty/issues
# See Also
## Other Library
## Similar Project
### Javascript
1. [Weixinbot](https://github.com/feit/Weixinbot) Nodejs 封装网页版微信的接口,可编程控制微信消息
......
......@@ -2035,7 +2035,16 @@ angular.module("Controllers", []),
angular.module("Services", []),
!function() {
"use strict";
angular.module("Services").factory("appFactory", ["$http", "$q", "confFactory", "accountFactory", "loginFactory", "utilFactory", "reportService", "mmHttp", function(e, t, o, n, r, a, i, c) {
angular.module("Services").factory("appFactory", ["$http", "$q", "confFactory", "accountFactory", "loginFactory", "utilFactory", "reportService", "mmHttp", function(
e // $http
, t // $q
, o // confFactory
, n // accountFactory
, r // loginFactory
, a // utilFactory
, i // reportService
, c // mmHttp
) {
var s = {
globalData: {
chatList: []
......
......@@ -58,7 +58,7 @@ class Message {
}
toStringDigest() {
const text = webUtil.digestEmoji(this.obj.digest)
return '{' + this.type() + '}' + text
return '{' + this.typeEx() + '}' + text
}
toStringEx() {
......
......@@ -30,13 +30,32 @@ class Bridge {
init() {
log.verbose('PuppetWebBridge', 'init()')
return this.inject()
.then(r => {
log.verbose('PuppetWebBridge', 'init() inject() return %s', r)
return this
const max = 15
const backoff = 100
// max = (2*totalTime/backoff) ^ (1/2)
// timeout = 11,250 for {max: 15, backoff: 100}
// timeout = 45,000 for {max: 30, backoff: 100}
// timeout = 30,6250 for {max: 35, backoff: 500}
const timeout = max * (backoff * max) / 2
return retryPromise({ max: max, backoff: backoff }, attempt => {
log.silly('PuppetWebBridge', 'init() retryPromise: attampt %s/%s times for timeout %s'
, attempt, max, timeout)
return this.inject()
.then(r => {
log.verbose('PuppetWebBridge', 'init() inject() return %s at attempt %d', r, attempt)
return r
})
.catch(e => {
log.warn('PuppetWebBridge', 'init() inject() attempt %d exception: %s', attempt, e.message)
throw e
})
})
.catch(e => {
log.error('PuppetWebBridge', 'init() inject() exception: %s', e.message)
log.warn('PuppetWebBridge', 'init() inject FINAL fail: %s', e.message)
throw e
})
}
......@@ -78,20 +97,20 @@ class Bridge {
throw e
})
}
getMsgImg(id) {
return this.proxyWechaty('getMsgImg', id)
.catch(e => {
log.silly('PuppetWebBridge', 'proxyWechaty(getMsgImg, %d) exception: %s', id, e.message)
throw e
})
}
getContact(id) {
if (id!==id) { // NaN
const err = new Error('NaN! where does it come from?')
log.error('PuppetWebBridge', 'getContact(NaN): %s', err)
return Promise.reject(err)
}
getMsgImg(id) {
return this.proxyWechaty('getMsgImg', id)
.catch(e => {
log.silly('PuppetWebBridge', 'proxyWechaty(getMsgImg, %d) exception: %s', id, e.message)
throw e
})
}
getContact(id) {
if (id!==id) { // NaN
const err = new Error('NaN! where does it come from?')
log.error('PuppetWebBridge', 'getContact(NaN): %s', err)
return Promise.reject(err)
}
const max = 35
const backoff = 500
......@@ -132,24 +151,32 @@ class Bridge {
, 'utf8'
)
}
inject(attempt) {
inject() {
log.verbose('PuppetWebBridge', 'inject()')
return co.call(this, function* () {
const injectio = this.getInjectio()
let r = yield this.execute(injectio, this.options.port)
log.verbose('PuppetWebBridge', 'inject() injected, got [%s]', r)
r = yield this.proxyWechaty('init')
log.verbose('PuppetWebBridge', 'inject() Wechaty.init() return: %s', r)
return r
let retObj = yield this.execute(injectio, this.options.port)
if (retObj && /^2/.test(retObj.code)) {
log.verbose('PuppetWebBridge', 'inject() injectio injected, with code[%d] message[%s] port[%d]'
, retObj.code, retObj.message, retObj.port)
} else {
throw new Error('execute injectio error: ' + retObj.message)
}
retObj = yield this.proxyWechaty('init')
if (retObj && /^2/.test(retObj.code)) {
log.verbose('PuppetWebBridge', 'inject() injectio inited, with code[%d] message[%s] port[%d]'
, retObj.code, retObj.message, retObj.port)
} else {
throw new Error('execute proxyWechaty(init) error: ' + retObj.message)
}
return true
})
.catch (e => {
log.warn('PuppetWebBridge', 'inject() exception: %s', e.message)
attempt = attempt || 0
if (attempt++ < 9) { // if init fail, retry 9 times
log.warn('PuppetWebBridge', 'inject(%d) retry after 1 second: %s', attempt, e.message)
setTimeout(() => this.inject(attempt), 1000)
return
}
throw e
})
}
......@@ -182,6 +209,14 @@ class Bridge {
throw e
})
}
ding(data) {
return this.proxyWechaty('ding', data)
.catch(e => {
log.error('PuppetWebBridge', 'ding(%s) exception: %s', data, e.message)
throw e
})
}
}
module.exports = Bridge
......@@ -196,26 +231,41 @@ Object.keys(ac).filter(function(k) { return /李/.test(ac[k].NickName) }).map(fu
Object.keys(window._chatContent).filter(function (k) { return window._chatContent[k].length > 0 }).map(function (k) { return window._chatContent[k].map(function (v) {return v.MMDigestTime}) })
.web_wechat_tab_add
.web_wechat_tab_launch-chat
contentChatController
e.getMsgImg = function(e, t, o) {
return o && "undefined" != typeof o.MMStatus && o.MMStatus != u.MSG_SEND_STATUS_SUCC ? void 0 : u.API_webwxgetmsgimg + "?&MsgID=" + e + "&skey=" + encodeURIComponent(c.getSkey()) + (t ? "&type=" + t : "")
}
,
e.getMsgVideo = function(e) {
return u.API_webwxgetvideo + "?msgid=" + e + "&skey=" + encodeURIComponent(c.getSkey())
}
<div class="picture"
ng-init="imageInit(message,message.MMPreviewSrc || message.MMThumbSrc || getMsgImg(message.MsgId,'slave'))">
<img class="msg-img" ng-style="message.MMImgStyle" ng-click="previewImg(message)"
ng-src="/cgi-bin/mmwebwx-bin/webwxgetmsgimg?&amp;MsgID=6944236226252183282&amp;skey=%40crypt_c117402d_2b2a8c58340c8f4b0a4570cb8f11a1e8&amp;type=slave"
src="/cgi-bin/mmwebwx-bin/webwxgetmsgimg?&amp;MsgID=6944236226252183282&amp;skey=%40crypt_c117402d_2b2a8c58340c8f4b0a4570cb8f11a1e8&amp;type=slave"
style="height: 100px; width: 75px;">
*
.web_wechat_tab_launch-chat
contentChatController
e.getMsgImg = function(e, t, o) {
return o && "undefined" != typeof o.MMStatus && o.MMStatus != u.MSG_SEND_STATUS_SUCC ? void 0 : u.API_webwxgetmsgimg + "?&MsgID=" + e + "&skey=" + encodeURIComponent(c.getSkey()) + (t ? "&type=" + t : "")
}
,
e.getMsgVideo = function(e) {
return u.API_webwxgetvideo + "?msgid=" + e + "&skey=" + encodeURIComponent(c.getSkey())
}
<div class="picture"
ng-init="imageInit(message,message.MMPreviewSrc || message.MMThumbSrc || getMsgImg(message.MsgId,'slave'))">
<img class="msg-img" ng-style="message.MMImgStyle" ng-click="previewImg(message)"
ng-src="/cgi-bin/mmwebwx-bin/webwxgetmsgimg?&amp;MsgID=6944236226252183282&amp;skey=%40crypt_c117402d_2b2a8c58340c8f4b0a4570cb8f11a1e8&amp;type=slave"
src="/cgi-bin/mmwebwx-bin/webwxgetmsgimg?&amp;MsgID=6944236226252183282&amp;skey=%40crypt_c117402d_2b2a8c58340c8f4b0a4570cb8f11a1e8&amp;type=slave"
style="height: 100px; width: 75px;">
*
* check the live status of wxapp method 1
*
appFactory = Wechaty.glue.injector.get('appFactory')
appFactory.syncOrig = appFactory.sync
appFactory.syncCheckOrig = appFactory.syncCheck
appFactory.sync = function() { Wechaty.log('appFactory.sync() !!!'); return appFactory.syncOrig(arguments) }
appFactory.syncCheck = function() { Wechaty.log('appFactory.syncCheck() !!!'); return appFactory.syncCheckOrig(arguments) }
// method 2
$.ajaxOrig = $.ajax
$.ajax = function() { Wechaty.log('$.ajax() !!!'); return $.ajaxOrig(arguments) }
// method 3 - mmHttp
mmHttp = Wechaty.glue.injector.get('mmHttp')
mmHttp.getOrig = mmHttp.get
mmHttp.get = function() { Wechaty.log('mmHttp.get() !!!'); return mmHttp.getOrig(arguments) }
*
*/
......@@ -17,8 +17,20 @@
return (function(port) {
port = port || 8788
if (typeof Wechaty !== 'undefined') {
return 'Wechaty already injected?'
/*
* Wechaty injectio must return this object.
* PuppetWebBridge need this to decide if injection is successful.
*/
retObj = {
code: 200 // 2XX ok, 4XX/5XX error. HTTP like
, message: 'any message'
, port: port
}
if (typeof this.Wechaty !== 'undefined') {
retObj.code = 201
retObj.message = 'Wechaty already injected?'
return retObj
}
var Wechaty = {
......@@ -55,27 +67,35 @@ return (function(port) {
, getContact: getContact
, getUserName: getUserName
, getMsgImg: getMsgImg
}
window.Wechaty = Wechaty
// test purpose
, isLogin: isLogin
}
if (isWxLogin()) {
login('page refresh')
}
this.Wechaty = Wechaty
retObj.code = 200
retObj.message = 'Wechaty Inject Succ'
return retObj
/**
* Two return mode of WebDriver (should be one of them at a time)
* 1. a callback. return a value by call callback with args
* 2. direct return
*/
var callback = arguments[arguments.length - 1]
if (typeof callback === 'function') {
return callback('Wechaty')
} else {
return 'Wechaty'
}
// var callback = arguments[arguments.length - 1]
// if (typeof callback === 'function') {
// return callback(retObj)
// } else {
// return retObj
// }
return 'Should not run to here'
retObj.code = 500
retObj.message = 'SHOULD NOT RUN TO HERE'
return retObj
/////////////////////////////////////////////////////////////////////////////
......@@ -95,13 +115,23 @@ return (function(port) {
function init() {
if (Wechaty.vars.inited === true) {
log('Wechaty.init() called twice: already inited')
return 'init: already inited'
retObj.code = 201
retObj.message = 'init() already inited before. returned with do nothing'
return retObj
}
if (!isReady()) {
clog('angular not ready. wait 500ms...')
setTimeout(init, 1000)
return 'init: entered waiting angular loop'// AngularJS not ready, wait 500ms then try again.
retObj.code = 202
retObj.message = 'init() entered waiting angular loop'// AngularJS not ready, wait 500ms then try again.
return retObj
}
if (!initClog()) { // make console.log work (wxapp disabled the console.log)
retObj.code = 501
retObj.message = 'initClog fail'
return retObj
}
clog('init on port:' + port)
......@@ -115,7 +145,10 @@ return (function(port) {
clog('inited!. ;-D')
Wechaty.vars.inited = true
return 'init: success'
retObj.code = 200
retObj.message = 'init(): success on port ' + port
return retObj
}
function heartBeat(firstTime) {
......@@ -231,7 +264,13 @@ return (function(port) {
function slog(msg) {
// keep this emit directly to use socket.emit instead of Wechaty.emit
// to prevent lost log msg if there has any bug in Wechaty.emit
return Wechaty.vars.socket && Wechaty.vars.socket.emit('log', msg)
if (!Wechaty.vars.socket) {
clog('Wechaty.slog() not usable now coz no Wechaty.vars.socket. use clog instead')
clog(msg)
return
} else {
Wechaty.vars.socket.emit('log', msg)
}
}
function ding() { log('recv ding'); return 'dong' }
function send(ToUserName, Content) {
......@@ -339,6 +378,17 @@ return (function(port) {
* Log to console
* http://stackoverflow.com/a/7089553/1123955
*/
function initClog() {
var i = document.createElement('iframe')
if (!i) {
return false
}
i.style.display = 'none'
document.body.appendChild(i)
Wechaty.vars.iframe = i
clog('initClog done')
return true
}
function clog(s) {
var d = new Date()
s = d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + ' <Wechaty> ' + s
......@@ -349,11 +399,11 @@ return (function(port) {
* this will cause the bridge init fail, and retry.
* should it be ignored? or keep this exception to retry is better?
*/
var i = document.createElement('iframe')
i.style.display = 'none'
document.body.appendChild(i)
i.contentWindow.console.log(s)
i.parentNode.removeChild(i)
// var i = document.createElement('iframe')
// i.style.display = 'none'
// document.body.appendChild(i)
Wechaty.vars.iframe.contentWindow.console.log(s)
// i.parentNode.removeChild(i)
}
function getMsgImg(id) {
......@@ -361,4 +411,4 @@ return (function(port) {
var path = Wechaty.glue.contentChatScope.getMsgImg(id)
return location + path
}
}.apply(window, arguments))
}.apply(window, arguments))
\ No newline at end of file
......@@ -497,9 +497,9 @@ class PuppetWeb extends Puppet {
if (!this.bridge) {
return Promise.reject(new Error('ding fail: no bridge(yet)!'))
}
return this.bridge.proxyWechaty('ding', data)
return this.bridge.ding(data)
.catch(e => {
log.warn('PuppetWeb', 'ding(%s) rejected: %s', data, e.message || e)
log.warn('PuppetWeb', 'ding(%s) rejected: %s', data, e.message)
throw e
})
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册