Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
rip
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fanxuehui
rip
Commits
20ceeb35
Commit
20ceeb35
authored
Jul 25, 2019
by
aiduck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
74890fea
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
158 additions
and
153 deletions
+158
-153
package-lock.json
package-lock.json
+2
-1
package.json
package.json
+0
-1
common.js
src/lib/common.js
+0
-59
counter.js
src/lib/counter.js
+1
-0
monitor.js
src/lib/monitor.js
+40
-10
reporter.js
src/lib/reporter.js
+93
-20
tracks.worker.js
src/lib/tracks.worker.js
+19
-53
utils.js
src/lib/utils.js
+3
-9
No files found.
package-lock.json
View file @
20ceeb35
...
...
@@ -3205,7 +3205,8 @@
"lodash"
:
{
"version"
:
"4.17.15"
,
"resolved"
:
"https://registry.npm.taobao.org/lodash/download/lodash-4.17.15.tgz"
,
"integrity"
:
"sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg="
"integrity"
:
"sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg="
,
"dev"
:
true
},
"loose-envify"
:
{
"version"
:
"1.4.0"
,
...
...
package.json
View file @
20ceeb35
...
...
@@ -22,7 +22,6 @@
"author"
:
"Dec-F"
,
"license"
:
"
ISC
"
,
"dependencies"
:
{
"
lodash
"
:
"
^4.17.15
"
,
"
md5
"
:
"
^2.2.1
"
,
"
rrweb
"
:
"
^0.7.18
"
,
"
whatwg-fetch
"
:
"
^3.0.0
"
...
...
src/lib/common.js
deleted
100644 → 0
View file @
74890fea
import
"whatwg-fetch"
;
import
utils
from
"./utils"
;
/**
* fetch请求封装
* @param {*} action 请求线上地址
* @param {*} params 请求入参
* @param {*} method 请求方式,默认get
* @param {*} options 其他参数
* options为对象格式,值:
* isLoading(是否激活请求加载动画)
* isJson(是否设置post请求头contentType为application/json)
* content 自定义请求参数
*/
export
function
fetch
(
action
,
params
=
{},
method
=
"get"
,
options
=
{})
{
const
token
=
utils
.
getCookie
(
"token"
);
const
XCsrfToken
=
utils
.
getCookie
(
"csrf_token"
);
let
url
=
action
;
let
option
=
{
method
,
credentials
:
"same-origin"
,
headers
:
{
Accept
:
"application/json"
,
"Content-Type"
:
"application/json"
,
token
:
token
,
"X-Csrf-Token"
:
XCsrfToken
,
},
};
if
(
options
&&
options
.
content
)
{
option
=
Object
.
assign
({},
option
,
options
.
content
);
}
if
(
method
===
"post"
)
{
if
(
options
&&
options
.
isJson
)
{
option
.
body
=
JSON
.
stringify
(
params
);
}
else
{
option
=
Object
.
assign
({},
option
,
{
headers
:
{
Accept
:
"application/json,text/plain,*/*"
,
"Content-Type"
:
"application/x-www-form-urlencoded;charset=utf-8"
,
token
:
token
,
"X-Csrf-Token"
:
XCsrfToken
,
},
});
option
.
body
=
utils
.
serialize
(
params
);
}
}
if
(
method
===
"get"
)
{
url
=
Object
.
keys
(
params
).
length
?
url
+
"?"
+
utils
.
serialize
(
params
)
:
url
;
}
return
fetch
(
url
,
option
).
then
(
response
=>
{
if
(
response
.
status
>=
200
&&
response
.
status
<
300
)
{
return
response
;
}
else
{
let
error
=
new
Error
(
response
.
statusText
);
error
.
response
=
response
;
throw
error
;
}
});
}
src/lib/counter.js
View file @
20ceeb35
// 分片计数器
class
Counter
{
count
=
0
;
...
...
src/lib/monitor.js
View file @
20ceeb35
...
...
@@ -3,16 +3,36 @@ import TracksWorker from "./tracks.worker";
export
default
class
Monitor
{
rrwebHandler
=
null
;
tracksWorker
=
new
TracksWorker
();
// 记录
constructor
()
{
this
.
tracksWorker
.
onmessage
=
({
data
})
=>
{
console
.
log
(
"local"
,
data
);
window
.
localStorage
.
setItem
(
"rrevents"
,
JSON
.
stringify
(
data
));
// common.fetch('https://manager.tuiatest.cn/homePage/data','get');
this
.
tracksWorker
.
onmessage
=
({
data
:
{
type
,
payload
}
})
=>
{
switch
(
type
)
{
case
"localData"
:
window
.
localStorage
.
setItem
(
"rrevents"
,
JSON
.
stringify
(
payload
));
break
;
default
:
console
.
log
(
"monitor unknow action"
);
}
};
}
re
cord
()
{
re
setRrwebHandler
()
{
this
.
rrwebHandler
&&
this
.
rrwebHandler
();
}
/**
* 初始化
* @param {*} event
* @memberof Monitor
*/
init
(
event
)
{
this
.
resetRrwebHandler
();
console
.
log
(
"初始化系统信息"
);
this
.
tracksWorker
.
postMessage
({
type
:
"init"
,
payload
:
event
});
}
/**
* 录制
* @memberof Monitor
*/
record
()
{
this
.
resetRrwebHandler
();
console
.
log
(
"开始录制"
);
this
.
rrwebHandler
=
rrweb
.
record
({
emit
:
event
=>
{
...
...
@@ -20,7 +40,10 @@ export default class Monitor {
},
});
}
// 停止
/**
* 停止录制
* @memberof Monitor
*/
stop
()
{
if
(
!
this
.
rrwebHandler
)
{
throw
new
Error
(
"没有正在录制的实例"
);
...
...
@@ -28,13 +51,20 @@ export default class Monitor {
console
.
log
(
"停止录制"
);
this
.
rrwebHandler
();
}
// 重置
/**
* 重置
* @param {*} event
*/
reset
(
event
)
{
this
.
r
rwebHandler
&&
this
.
r
rwebHandler
();
this
.
r
esetR
rwebHandler
();
console
.
log
(
"重置数据"
);
this
.
tracksWorker
.
postMessage
({
type
:
"reset"
,
payload
:
event
});
}
// 发送信息
/**
* 发送信息
* @param {*} action
* @memberof Monitor
*/
postMessage
(
action
)
{
this
.
tracksWorker
.
postMessage
(
action
);
}
...
...
src/lib/reporter.js
View file @
20ceeb35
// 数据维护,上报
import
{
fetch
}
from
"./common"
;
import
utils
from
'./utils'
;
import
Counter
from
"./counter"
;
class
Reporter
{
isUploading
=
false
;
bus
=
[];
counter
=
new
Counter
();
system
=
''
;
//系统名
userIdentifier
=
''
;
//用户标示
path
=
''
;
// 当前路径
isUploading
=
false
;
// 是否在上传cdn
bus
=
[];
// 上传分片数据
counter
=
new
Counter
();
// 计数器和recordKey一起重置
cache
=
[]
// cdn数据缓存
constructor
(
recordKey
)
{
this
.
recordKey
=
recordKey
;
}
toCDN
()
{
// 设置系统名
setSystem
(
system
)
{
this
.
system
=
system
;
}
// 设置用户标示
setUserIdentifier
(
userIdentifier
)
{
this
.
userIdentifier
=
userIdentifier
;
}
// 设置当前访问路径
setPath
(
url
)
{
this
.
path
=
url
}
// 上传CDN
toCDN
(
payload
)
{
this
.
isUploading
=
true
;
let
index
=
this
.
bus
.
length
;
let
blob
=
new
Blob
([
JSON
.
stringify
(
payload
)],
{
type
:
'application/json'
});
let
formData
=
new
FormData
();
let
trackId
=
this
.
counter
.
next
();
let
recordKey
=
this
.
recordKey
;
return
fetch
(
"cdn"
).
then
(
res
=>
{
formData
.
append
(
'file'
,
blob
,
`
${
this
.
recordKey
+
trackId
}
.json`
);
try
{
fetch
(
`http://hunter.duibadev.com.cn/upload`
,
{
method
:
'POST'
,
credentials
:
'include'
,
body
:
formData
}).
then
(
res
=>
{
return
res
.
json
();
}).
then
(
res
=>
{
// 如果cache中有数据,说明是多次提交并且数据缓存在了cache中,那么我们全量快照可能在cache[0]
let
index
=
this
.
bus
.
findIndex
(
v
=>
v
.
track
.
type
===
2
);
console
.
log
(
index
);
let
extra
=
{
system
:
this
.
system
,
userIdentifier
:
this
.
userIdentifier
,
path
:
this
.
path
,
recordKey
:
this
.
recordKey
,
trackId
:
trackId
,
isCdn
:
true
}
this
.
bus
.
splice
(
index
,
1
,
utils
.
dataWrapper
(
extra
,
res
.
url
));
this
.
isUploading
=
false
;
if
(
recordKey
!==
this
.
recordKey
)
{
return
;
// 如果cache里面有数据需要上传的,那么先上传
if
(
this
.
cache
&&
this
.
cache
.
length
>
0
)
{
this
.
cache
.
map
(
item
=>
{
this
.
report
(
item
);
});
this
.
cache
=
[];
}
return
res
;
});
}
catch
(
e
)
{
console
.
log
(
'上传失败,原因:'
);
console
.
log
(
e
.
message
);
}
}
toBus
(
data
)
{
let
trackId
=
this
.
counter
.
next
();
data
.
trackId
=
trackId
;
this
.
bus
.
push
(
data
);
let
extra
=
{
system
:
this
.
system
,
userIdentifier
:
this
.
userIdentifier
,
path
:
this
.
path
,
recordKey
:
this
.
recordKey
,
trackId
:
this
.
counter
.
next
(),
isCdn
:
false
}
this
.
bus
.
push
(
utils
.
dataWrapper
(
extra
,
data
));
}
// 上传
report
(
data
)
{
console
.
log
(
'上传数据'
,
data
);
let
reportData
=
data
;
this
.
bus
=
[];
if
(
this
.
isUploading
)
{
console
.
log
(
'cdn数据正在上传,先将内容存到cache'
);
this
.
cache
.
push
(
reportData
);
return
;
}
return
fetch
(
"report"
);
try
{
fetch
(
`http://hunter.duibadev.com.cn/behavior/record`
,
{
method
:
'POST'
,
credentials
:
'include'
,
headers
:
{
'Content-Type'
:
'application/json; charset=utf-8'
},
body
:
JSON
.
stringify
({
tracks
:
data
})
}).
then
(
res
=>
{
console
.
log
(
res
);
});
}
catch
(
e
)
{
console
.
log
(
'上传失败,原因:'
);
console
.
log
(
e
.
message
);
}
}
// 重置数据(分条使用)
reset
(
recordKey
)
{
this
.
cache
=
[];
this
.
bus
=
[];
this
.
counter
.
reset
();
this
.
recordKey
=
recordKey
;
...
...
src/lib/tracks.worker.js
View file @
20ceeb35
// 入口,格式化数据,模块管理
import
md5
from
"md5"
;
import
utils
from
"./utils"
;
import
_
from
"lodash"
;
import
Reporter
from
"./reporter"
;
const
reporter
=
new
Reporter
(
"recordKey"
);
// 原始数据数组
let
events
=
[];
// 包装后的数据对象
let
wrapData
=
[];
// 分条视频id
let
recordKey
=
""
;
// 全量快照是否已经返回
let
isCdnReturn
=
false
;
onmessage
=
({
data
:
{
type
,
payload
}
})
=>
{
switch
(
type
)
{
case
"init"
:
reporter
.
setSystem
(
payload
);
break
;
case
"record"
:
// todo : 数据本地存储
console
.
log
(
wrapData
);
wrapData
.
push
(
utils
.
dataWrapper
(
{
recordKey
,
isCdn
:
false
,
},
payload
,
),
);
events
.
push
(
payload
);
reporter
.
toBus
(
payload
);
console
.
log
(
reporter
.
bus
);
// todo : 全量快照上传cdn
if
(
payload
.
type
===
2
)
{
const
cdnIndex
=
_
.
findIndex
(
events
,
{
type
:
2
});
setTimeout
(()
=>
{
wrapData
.
splice
(
cdnIndex
,
1
,
utils
.
dataWrapper
(
{
recordKey
,
isCdn
:
true
,
},
payload
,
),
);
isCdnReturn
=
true
;
},
1000
);
reporter
.
toCDN
(
payload
);
}
// todo : 数据压缩
// todo : 根据事件类型优先级触发上传策略(click)
if
(
payload
.
data
.
source
===
2
&&
isCdnReturn
)
{
console
.
log
(
"点击上上传events"
,
wrapData
);
postMessage
(
wrapData
);
events
=
[];
wrapData
=
[];
if
(
payload
.
data
.
source
===
2
&&
!
reporter
.
isUploading
)
{
postMessage
({
type
:
"localData"
,
payload
:
reporter
.
bus
})
reporter
.
report
(
reporter
.
bus
);
}
// todo : 数据超出100条上线,自动上传
if
(
wrapData
.
length
>
100
&&
isCdnReturn
)
{
console
.
log
(
"超出线上100条上传events"
,
wrapData
);
postMessage
(
wrapData
);
events
=
[];
wrapData
=
[];
if
(
reporter
.
bus
.
length
>
100
&&
!
reporter
.
isUploading
)
{
postMessage
({
type
:
"localData"
,
payload
:
reporter
.
bus
})
reporter
.
report
(
reporter
.
bus
);
}
break
;
case
"reset"
:
// todo : 重置参数,重新生成recordKey
events
=
[];
wrapData
=
[];
recordKey
=
""
;
isCdnReturn
=
false
;
const
{
url
,
email
}
=
payload
;
recordKey
=
md5
(
url
+
email
+
Date
.
parse
(
new
Date
()));
console
.
log
(
url
,
"分片id"
,
recordKey
);
reporter
.
setUserIdentifier
(
email
);
reporter
.
setPath
(
url
);
let
recordKey
=
md5
(
url
+
email
+
Date
.
parse
(
new
Date
()));
reporter
.
reset
(
recordKey
);
console
.
log
(
url
,
"分片id"
,
reporter
.
recordKey
);
break
;
default
:
console
.
log
(
"unknow action"
);
...
...
src/lib/utils.js
View file @
20ceeb35
...
...
@@ -3,25 +3,19 @@ const utils = {
dataWrapper
(
extraData
,
event
)
{
return
{
...
extraData
,
event
track
:
event
}
},
// 判断是否有值
isNothing
(
value
)
{
return
value
===
''
||
value
===
undefined
||
value
===
null
||
(
typeof
value
===
'number'
&&
(
isNaN
(
value
)
||
!
isFinite
(
value
)));
},
// 获取token
getCookie
(
name
)
{
const
regexp
=
new
RegExp
(
'(^| )'
+
name
+
'=([^;]*)(;|$)'
);
const
matches
=
regexp
.
exec
(
document
.
cookie
);
return
matches
?
matches
[
2
]
:
null
;
},
// 拼接URL请求参数
serialize
(
obj
)
{
const
str
=
[];
for
(
let
p
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
p
))
{
str
.
push
(
encodeURIComponent
(
p
)
+
'='
+
encodeURIComponent
(
this
.
isNothing
(
obj
[
p
])
?
''
:
obj
[
p
])
);
str
.
push
(
p
+
'='
+
this
.
isNothing
(
obj
[
p
])
?
''
:
obj
[
p
]
);
}
}
return
str
.
join
(
'&'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment