Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Alderaan
pan-light
提交
b220f2fd
P
pan-light
项目概览
Alderaan
/
pan-light
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
pan-light
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b220f2fd
编写于
6月 13, 2019
作者:
P
peterq
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
finish: 完成在线聊天室
上级
33c500c0
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
393 addition
and
305 deletion
+393
-305
demo/demo-online-front/src/app.js
demo/demo-online-front/src/app.js
+105
-19
demo/demo-online-front/src/comp/chat/chat-main.vue
demo/demo-online-front/src/comp/chat/chat-main.vue
+57
-0
demo/demo-online-front/src/comp/chat/room.vue
demo/demo-online-front/src/comp/chat/room.vue
+73
-0
demo/demo-online-front/src/comp/layout.vue
demo/demo-online-front/src/comp/layout.vue
+12
-3
demo/demo-online-front/src/realtime/realtime.js
demo/demo-online-front/src/realtime/realtime.js
+48
-0
demo/demo-online-front/src/util/state.js
demo/demo-online-front/src/util/state.js
+26
-4
server/demo/demo-init.go
server/demo/demo-init.go
+1
-1
server/demo/nickname/avatar.go
server/demo/nickname/avatar.go
+0
-229
server/demo/nickname/get-nickname.go
server/demo/nickname/get-nickname.go
+42
-27
server/demo/rpc/host-handler.go
server/demo/rpc/host-handler.go
+5
-4
server/demo/rpc/roles.go
server/demo/rpc/roles.go
+2
-0
server/demo/rpc/rpc-init.go
server/demo/rpc/rpc-init.go
+1
-1
server/demo/rpc/user-handler.go
server/demo/rpc/user-handler.go
+7
-12
server/realtime/room.go
server/realtime/room.go
+5
-5
server/realtime/server.go
server/realtime/server.go
+7
-0
server/static/.gitignore
server/static/.gitignore
+2
-0
未找到文件。
demo/demo-online-front/src/app.js
浏览文件 @
b220f2fd
import
{
newPeerConnection
}
from
"
./realtime/webRtc
"
import
{
newPeerConnection
}
from
"
./realtime/webRtc
"
import
RealTime
from
"
./realtime/realtime
"
import
RealTime
from
"
./realtime/realtime
"
import
Vue
from
"
vue
"
import
Vue
from
"
vue
"
import
State
from
"
./util/state
"
import
State
,
{
dataTemplate
}
from
"
./util/state
"
import
{
registerProxyChannelResolver
}
from
"
./lib/vnc/core/RtcWebSocket
"
import
{
registerProxyChannelResolver
}
from
"
./lib/vnc/core/RtcWebSocket
"
import
whatJpg
from
'
./assets/what.jpeg
'
import
whatJpg
from
'
./assets/what.jpeg
'
...
@@ -54,26 +54,103 @@ $rt.onRemote("host.candidate.ok", data => {
...
@@ -54,26 +54,103 @@ $rt.onRemote("host.candidate.ok", data => {
handler
.
pc
.
continueWithRemote
(
candidate
)
handler
.
pc
.
continueWithRemote
(
candidate
)
})
})
function
roomHandleUserBroadCast
(
room
,
data
)
{
if
(
data
.
event
===
'
chat
'
)
{
room
.
messages
=
room
.
messages
.
concat
([{
id
:
+
new
Date
,
type
:
'
chat
'
,
msg
:
data
.
payload
,
from
:
data
.
from
}])
}
}
function
roomHandleUserTicketTurn
(
room
,
data
)
{
console
.
log
(
data
,
$state
.
ticket
)
const
{
order
}
=
data
if
(
$state
.
ticket
&&
$state
.
ticket
.
order
===
order
)
{
$state
.
ticket
.
inService
=
true
let
{
host
,
slave
}
=
data
$state
.
connectVnc
=
{
host
,
slave
,
viewOnly
:
false
,
password
:
$state
.
ticket
.
ticket
}
$event
.
fire
(
'
operate.turn
'
,
data
)
console
.
log
(
data
)
}
room
.
messages
=
room
.
messages
.
concat
([{
id
:
+
new
Date
,
type
:
'
system
'
,
evt
:
'
turn
'
,
sessionId
:
data
.
sessionId
,
ticket
:
data
}])
}
$rt
.
on
(
'
room.new
'
,
room
=>
{
$rt
.
on
(
'
room.new
'
,
room
=>
{
// 全员群
async
function
getSessionInfo
(
ids
)
{
if
(
room
.
name
===
'
room.all.user
'
)
{
let
newOnes
=
[]
room
.
onRemote
(
'
ticket.turn
'
,
data
=>
{
ids
.
forEach
(
id
=>
{
console
.
log
(
data
,
$state
.
ticket
)
if
(
!
$state
.
userSessionInfo
[
id
])
{
const
{
order
}
=
data
newOnes
.
push
(
id
)
if
(
$state
.
ticket
&&
$state
.
ticket
.
order
===
order
)
{
Vue
.
set
(
$state
.
userSessionInfo
,
id
,
dataTemplate
.
deppClone
(
'
userSessionInfo
'
))
$state
.
ticket
.
inService
=
true
let
{
host
,
slave
}
=
data
$state
.
connectVnc
=
{
host
,
slave
,
viewOnly
:
false
,
password
:
$state
.
ticket
.
ticket
}
$event
.
fire
(
'
operate.turn
'
,
data
)
console
.
log
(
data
)
}
}
})
})
let
infoMap
=
await
$rt
.
call
(
'
session.public.info
'
,
{
sessionIds
:
newOnes
})
for
(
let
id
in
infoMap
)
{
$state
.
userSessionInfo
[
id
]
=
infoMap
[
id
]
}
}
room
.
messages
=
[]
room
.
members
=
[]
room
.
sendMsg
=
function
(
msg
)
{
room
.
broadcast
(
'
chat
'
,
msg
)
room
.
messages
=
room
.
messages
.
concat
([{
id
:
+
new
Date
,
type
:
'
chat
'
,
msg
,
from
:
$state
.
userSessionInfo
.
self
.
sessionId
}])
}
$rt
.
call
(
'
room.members
'
,
{
room
:
room
.
name
})
.
then
(
members
=>
room
.
members
=
members
)
.
then
(()
=>
{
getSessionInfo
(
room
.
members
)
})
room
.
on
(
'
leave
'
,
()
=>
{
Vue
.
delete
(
$state
.
roomMap
,
room
.
name
)
})
room
.
onRemote
(
'
room.member.join
'
,
sessionId
=>
{
getSessionInfo
([
sessionId
])
room
.
messages
=
room
.
messages
.
concat
([{
id
:
+
new
Date
,
type
:
'
system
'
,
evt
:
'
join
'
,
sessionId
}])
room
.
members
=
room
.
members
.
concat
([
sessionId
])
})
room
.
onRemote
(
'
room.member.remove
'
,
sessionId
=>
{
room
.
members
=
room
.
members
.
filter
(
id
=>
id
!==
sessionId
)
room
.
messages
=
room
.
messages
.
concat
([{
id
:
+
new
Date
,
type
:
'
system
'
,
evt
:
'
leave
'
,
sessionId
}])
})
room
.
onRemote
(
'
broadcast.user
'
,
data
=>
roomHandleUserBroadCast
(
room
,
data
))
Vue
.
set
(
$state
.
roomMap
,
room
.
name
,
room
)
// 全员群
if
(
room
.
name
===
'
room.all.user
'
)
{
room
.
onRemote
(
'
ticket.turn
'
,
data
=>
roomHandleUserTicketTurn
(
room
,
data
))
}
}
// slave 全员群
// slave 全员群
...
@@ -98,6 +175,13 @@ $rt.on('room.new', room => {
...
@@ -98,6 +175,13 @@ $rt.on('room.new', room => {
})
})
$rt
.
onRemote
(
'
session.new
'
,
async
session
=>
{
$state
.
resetData
()
let
infoMap
=
await
$rt
.
call
(
'
session.public.info
'
,
{
sessionIds
:
[
session
.
id
]})
$state
.
userSessionInfo
.
self
=
{...
infoMap
[
session
.
id
],
sessionId
:
session
.
id
}
$state
.
connected
=
true
})
class
Host
{
class
Host
{
/**
/**
* @type RTCDataChannel
* @type RTCDataChannel
...
@@ -315,8 +399,10 @@ async function canStart() {
...
@@ -315,8 +399,10 @@ async function canStart() {
var
element
=
new
Image
()
var
element
=
new
Image
()
Object
.
defineProperty
(
element
,
'
id
'
,
{
Object
.
defineProperty
(
element
,
'
id
'
,
{
get
:
function
()
{
get
:
function
()
{
fuckDebug
()
setTimeout
(()
=>
{
location
.
reload
()
fuckDebug
()
location
.
reload
()
})
return
0
return
0
}
}
})
})
...
...
demo/demo-online-front/src/comp/chat/chat-main.vue
0 → 100644
浏览文件 @
b220f2fd
<
template
>
<div
style=
"display: flex; flex-direction: column;"
>
<h2
style=
"text-align: center"
>
在线聊天
</h2>
<hr>
<div
style=
"display: flex; align-items: center; padding: 10px 20px;"
>
<img
:src=
"$state.userSessionInfo.self.avatar"
style=
"border-radius: 50%;"
alt=
"avatar"
width=
"50"
height=
"50"
/>
<p>
{{
$state
.
userSessionInfo
.
self
.
nickname
}}
</p>
</div>
<hr>
<el-tabs
v-model=
"activeRoom"
style=
"padding: 5px; flex: 1;"
>
<el-tab-pane
v-for=
"(room, roomName) in $state.roomMap"
:key=
"roomName"
:label=
"getRoomLabel(roomName)"
:name=
"roomName"
>
<room
:room=
"room"
style=
"height: 100%"
></room>
</el-tab-pane>
</el-tabs>
</div>
</
template
>
<
script
>
import
room
from
'
./room
'
export
default
{
data
()
{
return
{
activeRoom
:
'
room.all.user
'
}
},
computed
:
{},
components
:
{
room
},
methods
:
{
getRoomLabel
(
name
)
{
if
(
name
===
'
room.all.user
'
)
{
return
'
全员群
'
}
return
'
围观群
'
+
name
.
replace
(
'
room.slave.all.user.
'
,
''
)
}
}
}
</
script
>
<
style
>
.el-tabs__content
{
flex
:
1
;
}
.el-tabs
{
display
:
flex
;
flex-direction
:
column
;
}
.el-tab-pane
{
height
:
100%
;
}
</
style
>
demo/demo-online-front/src/comp/chat/room.vue
0 → 100644
浏览文件 @
b220f2fd
<
template
>
<div
style=
"display: flex; flex-direction: column;"
>
<el-scrollbar
ref=
"scroll"
class=
"msg-con"
style=
"height: 100%;"
:native=
"false"
tag=
"section"
>
<div
v-for=
"(item) in room.messages"
:key=
"item.id"
>
<system-msg
v-if=
"item.type === 'system'"
:message=
"item"
></system-msg>
<user-msg
v-else-if=
"item.type==='chat'"
:message=
"item"
></user-msg>
</div>
</el-scrollbar>
<div
style=
"height: 80px; display: flex;"
>
<el-input
style=
"height: 100%"
type=
"textarea"
placeholder=
"在此输入消息"
v-model=
"inputMsg"
>
</el-input>
<el-button
type=
"primary"
@
click=
"clickSend"
style=
"height: 100%; border-radius: 0"
>
发 送
</el-button>
</div>
</div>
</
template
>
<
script
>
import
UserMsg
from
"
./user-msg
"
import
SystemMsg
from
"
./system-msg
"
export
default
{
props
:
[
'
room
'
],
data
()
{
return
{
inputMsg
:
'
hello world
'
}
},
mounted
()
{
console
.
log
(
this
.
$refs
.
scroll
)
},
computed
:
{},
methods
:
{
clickSend
()
{
if
(
!
this
.
inputMsg
)
return
this
.
room
.
sendMsg
(
this
.
inputMsg
)
this
.
inputMsg
=
''
}
},
components
:
{
SystemMsg
,
UserMsg
},
watch
:
{
async
[
'
room.messages
'
]()
{
await
this
.
$nextTick
()
let
div
=
this
.
$refs
.
scroll
.
$el
.
querySelector
(
'
.el-scrollbar__wrap
'
)
div
.
scrollTop
=
div
.
scrollHeight
this
.
$refs
.
scroll
.
update
()
}
}
}
</
script
>
<
style
>
.el-textarea__inner
{
height
:
100%
;
}
.msg-con
{
height
:
calc
(
100%
-
80px
);
}
.el-scrollbar__wrap
{
overflow-x
:
hidden
!important
;
}
</
style
>
demo/demo-online-front/src/comp/layout.vue
浏览文件 @
b220f2fd
...
@@ -3,13 +3,18 @@
...
@@ -3,13 +3,18 @@
<el-header>
<el-header>
pan-light 在线体验
pan-light 在线体验
</el-header>
</el-header>
<el-container>
<el-container
class=
"down-con"
>
<el-main
style=
"min-width: 800px"
>
<el-main
style=
"min-width: 800px"
>
<vnc
style=
"flex: 1;"
v-if=
"vncShow"
<vnc
style=
"flex: 1;"
v-if=
"vncShow"
:config=
"connectVnc"
></vnc>
:config=
"connectVnc"
></vnc>
<host-list
v-else
></host-list>
<host-list
v-else
></host-list>
</el-main>
</el-main>
<el-aside
width=
"400px"
>
Aside
</el-aside>
<el-aside
width=
"400px"
>
<div
v-if=
"!$state.connected"
style=
"height: 100%; display: flex; justify-content: center; align-items: center"
>
<p>
聊天室初始化中...
</p>
</div>
<chat-main
v-else
style=
"height: 100%"
></chat-main>
</el-aside>
</el-container>
</el-container>
</el-container>
</el-container>
</
template
>
</
template
>
...
@@ -18,6 +23,7 @@
...
@@ -18,6 +23,7 @@
import
vnc
from
'
./vnc
'
import
vnc
from
'
./vnc
'
import
hostList
from
'
./hostList
'
import
hostList
from
'
./hostList
'
import
{
$state
}
from
"
../app
"
import
{
$state
}
from
"
../app
"
import
chatMain
from
'
./chat/chat-main
'
export
default
{
export
default
{
data
()
{
data
()
{
...
@@ -43,7 +49,7 @@
...
@@ -43,7 +49,7 @@
watch
:
{
watch
:
{
},
},
components
:
{
vnc
,
hostList
}
components
:
{
vnc
,
hostList
,
chatMain
}
}
}
</
script
>
</
script
>
...
@@ -58,5 +64,8 @@
...
@@ -58,5 +64,8 @@
text-align
:
center
;
text-align
:
center
;
line-height
:
60px
;
line-height
:
60px
;
}
}
.down-con
{
height
:
calc
(
100vh
-
60px
);
}
</
style
>
</
style
>
demo/demo-online-front/src/realtime/realtime.js
浏览文件 @
b220f2fd
...
@@ -31,6 +31,29 @@ class EventEmitter {
...
@@ -31,6 +31,29 @@ class EventEmitter {
}
}
}
}
function
ch2Unicdoe
(
str
)
{
if
(
!
str
)
{
return
}
let
unicode
=
''
for
(
let
i
=
0
;
i
<
str
.
length
;
i
++
)
{
let
temp
=
str
.
charAt
(
i
)
if
(
isChinese
(
temp
))
{
unicode
+=
'
\\
u
'
+
temp
.
charCodeAt
(
0
).
toString
(
16
)
}
else
{
unicode
+=
temp
}
}
return
unicode
}
// 判断字符是否为汉字,
function
isChinese
(
s
)
{
return
/
[\u
4e00-
\u
9fa5
]
/
.
test
(
s
)
}
export
default
class
Rpc
extends
EventEmitter
{
export
default
class
Rpc
extends
EventEmitter
{
openPromise
openPromise
...
@@ -127,6 +150,7 @@ export default class Rpc extends EventEmitter {
...
@@ -127,6 +150,7 @@ export default class Rpc extends EventEmitter {
if
(
!
(
data
.
type
===
'
call
'
&&
data
.
method
===
'
user.ping
'
))
if
(
!
(
data
.
type
===
'
call
'
&&
data
.
method
===
'
user.ping
'
))
console
.
log
(
'
ws ->
'
,
data
)
console
.
log
(
'
ws ->
'
,
data
)
let
str
=
JSON
.
stringify
(
data
)
let
str
=
JSON
.
stringify
(
data
)
str
=
ch2Unicdoe
(
str
)
let
send
=
this
.
_encrypt
(
str
)
let
send
=
this
.
_encrypt
(
str
)
this
.
ws
.
send
(
send
)
this
.
ws
.
send
(
send
)
}
}
...
@@ -181,6 +205,23 @@ export default class Rpc extends EventEmitter {
...
@@ -181,6 +205,23 @@ export default class Rpc extends EventEmitter {
return
promise
return
promise
}
}
emit
(
event
,
payload
=
{})
{
event
=
'
user.
'
+
event
this
.
wsSend
({
type
:
'
event
'
,
event
,
payload
,
})
}
broadcast
(
room
,
event
,
payload
)
{
this
.
emit
(
'
broadcast
'
,
{
room
,
event
,
payload
})
}
getRoom
(
name
)
{
getRoom
(
name
)
{
return
Room
.
roomMap
[
name
]
return
Room
.
roomMap
[
name
]
}
}
...
@@ -235,6 +276,9 @@ class Room extends EventEmitter {
...
@@ -235,6 +276,9 @@ class Room extends EventEmitter {
super
()
super
()
this
.
name
=
name
this
.
name
=
name
rt
.
fire
(
'
room.new
'
,
this
)
rt
.
fire
(
'
room.new
'
,
this
)
this
.
rt
=
function
()
{
return
rt
}
}
}
onRemote
(
name
,
cb
)
{
onRemote
(
name
,
cb
)
{
...
@@ -244,4 +288,8 @@ class Room extends EventEmitter {
...
@@ -244,4 +288,8 @@ class Room extends EventEmitter {
handleMsg
(
data
)
{
handleMsg
(
data
)
{
this
.
fire
(
'
$remote.
'
+
data
.
event
,
data
.
payload
)
this
.
fire
(
'
$remote.
'
+
data
.
event
,
data
.
payload
)
}
}
broadcast
(
event
,
payload
)
{
this
.
rt
().
broadcast
(
this
.
name
,
event
,
payload
)
}
}
}
demo/demo-online-front/src/util/state.js
浏览文件 @
b220f2fd
const
dataTemplate
=
{
export
const
dataTemplate
=
{
ticket
:
{
ticket
:
{
order
:
1
,
order
:
1
,
ticket
:
'
23
'
,
ticket
:
'
23
'
,
...
@@ -7,21 +7,35 @@ const dataTemplate = {
...
@@ -7,21 +7,35 @@ const dataTemplate = {
roomMap
:
{
roomMap
:
{
'
room.user.all
'
:
{
'
room.user.all
'
:
{
name
:
'
room.user.all
'
,
name
:
'
room.user.all
'
,
members
:
[
'
234
'
]
members
:
[],
messages
:
[],
}
}
},
},
connectVnc
:
{
connectVnc
:
{
host
:
''
,
host
:
''
,
slave
:
''
,
slave
:
''
,
viewOnly
:
true
viewOnly
:
true
},
userSessionInfo
:
{
_role
:
'
user
'
,
nickname
:
''
,
avatar
:
''
,
sessionId
:
''
},
deppClone
(
key
)
{
return
JSON
.
parse
(
JSON
.
stringify
(
this
[
key
]))
}
}
}
}
function
d
ata
()
{
function
initialD
ata
()
{
return
{
return
{
connected
:
false
,
loading
:
{
loading
:
{
getTicket
:
false
,
getTicket
:
false
,
},
},
userSessionInfo
:
{
self
:
{...
dataTemplate
.
userSessionInfo
},
},
ticket
:
null
,
// tpl: ticket
ticket
:
null
,
// tpl: ticket
roomMap
:
{},
// tpl roomMap
roomMap
:
{},
// tpl roomMap
timestamp
:
0
,
timestamp
:
0
,
...
@@ -37,12 +51,20 @@ function data() {
...
@@ -37,12 +51,20 @@ function data() {
export
default
{
export
default
{
data
()
{
data
()
{
return
d
ata
()
return
initialD
ata
()
},
},
created
()
{
created
()
{
window
.
debugObj
.
$state
=
this
window
.
debugObj
.
$state
=
this
setInterval
(()
=>
{
setInterval
(()
=>
{
this
.
timestamp
++
this
.
timestamp
++
},
100
)
},
100
)
},
methods
:
{
resetData
()
{
let
data
=
initialData
()
for
(
let
k
in
data
)
{
this
[
k
]
=
data
[
k
]
}
}
}
}
}
}
server/demo/demo-init.go
浏览文件 @
b220f2fd
...
@@ -7,7 +7,7 @@ import (
...
@@ -7,7 +7,7 @@ import (
func
Init
(
router
iris
.
Party
,
conf
map
[
interface
{}]
interface
{})
{
func
Init
(
router
iris
.
Party
,
conf
map
[
interface
{}]
interface
{})
{
// 静态页
// 静态页
router
.
StaticWeb
(
"/"
,
".
./static/noVNC
"
)
router
.
StaticWeb
(
"/"
,
".
/static/demo
"
)
hosts
:=
map
[
string
]
string
{}
hosts
:=
map
[
string
]
string
{}
for
_
,
host
:=
range
conf
[
"hosts"
]
.
([]
interface
{})
{
for
_
,
host
:=
range
conf
[
"hosts"
]
.
([]
interface
{})
{
hosts
[
host
.
(
map
[
interface
{}]
interface
{})[
"name"
]
.
(
string
)]
=
host
.
(
map
[
interface
{}]
interface
{})[
"password"
]
.
(
string
)
hosts
[
host
.
(
map
[
interface
{}]
interface
{})[
"name"
]
.
(
string
)]
=
host
.
(
map
[
interface
{}]
interface
{})[
"password"
]
.
(
string
)
...
...
server/demo/nickname/avatar.go
已删除
100644 → 0
浏览文件 @
33c500c0
package
nickname
import
(
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"sync"
"time"
)
type
taskItem
struct
{
book
string
nickname
string
images
[]
string
img
[]
byte
}
// 搜索图像
func
FetchAndSaveAvatarFromInternet
()
{
avatarInit
()
nicknameChan
:=
make
(
chan
*
taskItem
)
imageChan
:=
make
(
chan
*
taskItem
)
resultChan
:=
make
(
chan
*
taskItem
)
searchGroup
:=
new
(
sync
.
WaitGroup
)
searchGroup
.
Add
(
10
)
for
i
:=
0
;
i
<
10
;
i
++
{
go
searchImageLoop
(
nicknameChan
,
imageChan
,
searchGroup
)
}
faceCheckGroup
:=
new
(
sync
.
WaitGroup
)
faceCheckGroup
.
Add
(
10
)
for
i
:=
0
;
i
<
10
;
i
++
{
go
faceCheckLoop
(
imageChan
,
resultChan
,
faceCheckGroup
)
}
nicknameChan
<-
&
taskItem
{
book
:
"飞狐外传"
,
nickname
:
"马春花"
,
images
:
[]
string
{},
}
close
(
nicknameChan
)
go
func
()
{
// 处理完成关闭相关通道
searchGroup
.
Wait
()
close
(
imageChan
)
faceCheckGroup
.
Wait
()
close
(
resultChan
)
}()
for
itemResult
:=
range
resultChan
{
handleItemResult
(
itemResult
)
}
log
.
Println
(
"处理完成"
)
}
func
handleItemResult
(
item
*
taskItem
)
{
log
.
Println
(
"result"
,
item
.
nickname
)
}
func
searchImageLoop
(
nicknameChan
chan
*
taskItem
,
imageChan
chan
*
taskItem
,
wg
*
sync
.
WaitGroup
)
{
go
func
()
{
for
item
:=
range
nicknameChan
{
log
.
Println
(
"search item"
,
item
.
nickname
)
item
.
images
=
searchImage
(
item
.
book
+
" "
+
item
.
nickname
)
imageChan
<-
item
}
wg
.
Done
()
}()
return
}
func
faceCheckLoop
(
imageChan
chan
*
taskItem
,
resultChan
chan
*
taskItem
,
wg
*
sync
.
WaitGroup
)
{
go
func
()
{
for
item
:=
range
imageChan
{
log
.
Println
(
"check face"
,
item
.
nickname
,
item
.
images
)
for
_
,
img
:=
range
item
.
images
{
resp
,
err
:=
http
.
Get
(
img
)
if
err
!=
nil
{
continue
}
bin
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
continue
}
item
.
img
=
bin
checkFace
(
bin
)
break
}
resultChan
<-
item
}
wg
.
Done
()
}()
return
}
var
searchHttpClient
http
.
Client
var
faceHttpClient
http
.
Client
func
avatarInit
()
{
jar
,
_
:=
cookiejar
.
New
(
nil
)
jar1
,
_
:=
cookiejar
.
New
(
nil
)
parallel
:=
20
searchHttpClient
=
http
.
Client
{
Transport
:
&
http
.
Transport
{
MaxIdleConns
:
parallel
,
MaxConnsPerHost
:
parallel
,
},
CheckRedirect
:
nil
,
Jar
:
jar
,
Timeout
:
0
,
}
faceHttpClient
=
searchHttpClient
faceHttpClient
.
Jar
=
jar1
req
:=
&
http
.
Request
{}
req
.
URL
,
_
=
url
.
Parse
(
"http://kan.msxiaobing.com/V3/Portal?task=yanzhi&ftid="
)
req
.
Method
=
"GET"
req
.
Header
=
http
.
Header
{}
req
.
Header
.
Set
(
"Referer"
,
"http://kan.msxiaobing.com/V3/Portal?task=yanzhi&ftid="
)
req
.
Header
.
Set
(
"User-Agent"
,
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Mobile Safari/537.36"
)
faceHttpClient
.
Do
(
req
)
}
type
gson
=
map
[
string
]
interface
{}
func
searchImage
(
keyword
string
)
(
result
[]
string
)
{
req
:=
&
http
.
Request
{}
req
.
URL
,
_
=
url
.
Parse
(
"https://m.baidu.com/sf/vsearch/image/search/wisesearchresult"
)
params
:=
map
[
string
]
interface
{}{
"tn"
:
"wisejsonala"
,
"ie"
:
"utf-8"
,
"fromsf"
:
"1"
,
"word"
:
keyword
,
"pn"
:
0
,
"rn"
:
3
,
"gsm"
:
"3c"
,
"searchtype"
:
"0"
,
"prefresh"
:
"undefined"
,
"fromfilter"
:
"0"
,
}
q
:=
req
.
URL
.
Query
()
for
k
,
v
:=
range
params
{
q
.
Set
(
k
,
fmt
.
Sprint
(
v
))
req
.
URL
.
RawQuery
=
q
.
Encode
()
}
req
.
Method
=
"GET"
req
.
Header
=
http
.
Header
{}
req
.
Header
.
Set
(
"Referer"
,
"https://m.baidu.com/sf/vsearch"
)
req
.
Header
.
Set
(
"User-Agent"
,
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Mobile Safari/537.36"
)
resp
,
err
:=
searchHttpClient
.
Do
(
req
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
defer
resp
.
Body
.
Close
()
bin
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
var
data
gson
err
=
json
.
Unmarshal
(
bin
,
&
data
)
if
err
!=
nil
{
log
.
Println
(
err
,
string
(
bin
))
return
}
linkData
:=
data
[
"linkData"
]
.
([]
interface
{})
for
_
,
item
:=
range
linkData
{
result
=
append
(
result
,
item
.
(
gson
)[
"objurl"
]
.
(
string
))
}
return
}
func
checkFace
(
img
[]
byte
)
(
result
[]
string
)
{
link
:=
upImg
(
img
)
formData
:=
url
.
Values
{}
formData
.
Add
(
"MsgId"
,
fmt
.
Sprint
(
time
.
Now
()
.
Unix
()
*
1000
))
formData
.
Add
(
"CreateTime"
,
fmt
.
Sprint
(
time
.
Now
()
.
Unix
()))
formData
.
Add
(
"Content[imageUrl]"
,
link
)
req
,
_
:=
http
.
NewRequest
(
"POST"
,
"https://kan.msxiaobing.com/Api/ImageAnalyze/Process?service=beauty&tid="
,
strings
.
NewReader
(
formData
.
Encode
()))
req
.
Header
.
Set
(
"Referer"
,
"https://kan.msxiaobing.com/ImageGame/Portal?task=beauty&feid="
)
req
.
Header
.
Set
(
"User-Agent"
,
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
)
req
.
Header
.
Set
(
"Content-Type"
,
"application/x-www-form-urlencoded; charset=UTF-8"
)
resp
,
err
:=
faceHttpClient
.
Do
(
req
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
defer
resp
.
Body
.
Close
()
bin
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
var
data
gson
err
=
json
.
Unmarshal
(
bin
,
&
data
)
if
err
!=
nil
{
log
.
Println
(
err
,
string
(
bin
))
return
}
log
.
Println
(
data
,
string
(
bin
))
return
}
func
upImg
(
img
[]
byte
)
(
link
string
)
{
str
:=
base64
.
StdEncoding
.
EncodeToString
(
img
)
req
,
_
:=
http
.
NewRequest
(
"POST"
,
"https://kan.msxiaobing.com/Api/Image/UploadBase64"
,
strings
.
NewReader
(
str
))
req
.
Header
.
Set
(
"Referer"
,
"https://kan.msxiaobing.com/ImageGame/Portal?task=beauty&feid="
)
resp
,
err
:=
faceHttpClient
.
Do
(
req
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
defer
resp
.
Body
.
Close
()
bin
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
var
data
gson
err
=
json
.
Unmarshal
(
bin
,
&
data
)
if
err
!=
nil
{
log
.
Println
(
err
,
string
(
bin
))
return
}
return
data
[
"Host"
]
.
(
string
)
+
data
[
"Url"
]
.
(
string
)
}
server/demo/nickname/nickname.go
→
server/demo/nickname/
get-
nickname.go
浏览文件 @
b220f2fd
package
nickname
package
nickname
import
(
import
(
"fmt"
"math/rand"
"math/rand"
"regexp"
"strings"
"strings"
"sync"
"time"
)
)
var
nickname
s
[]
string
var
nickname
Map
=
map
[
string
][]
string
{}
// 数据格式 {book_name: [person]}
var
idx
=
0
var
doc
=
`
var
doc
=
`
《飞狐外传》人物(共有112人)
《飞狐外传》人物(共有112人)
马行空 马春花 徐铮 商宝震 何思豪 阎基 田归农 苗人凤 南仁通 补锅匠 脚夫 车夫 蒋调侯 店伴 钟兆文 钟兆英 钟兆能 南兰 苗若兰 商老太 平四 胡斐 张总管 王剑英 王剑杰 陈禹 古若般 殷仲翔 福康安 赵半山 孙刚峰 吕小妹 钟四嫂 易吉钟小二 钟阿四 胖商人 瘦商人 凤南天 凤七 俞朝奉 蛇皮张 邝宝官 凤一鸣 大汉 孙伏虎 尉迟连 杨宾 中年武师 程灵素同桌后生 袁紫衣 刘鹤真 崔百胜 曹猛 蓝秦 王仲萍 张飞雄 慕容景岳 姜铁山 薛鹊 王铁匠 姜小铁 田青文 张管家 聂钺 上官 褚轰 汪铁鹗 周铁鹤 曾铁鸥 秦耐之 姬晓峰 张九 任通武 相国夫人 蔡威 汤沛 无青子 海兰弼 大智禅师 欧阳公政 西灵道人 文醉翁 周隆 郭玉堂 齐伯涛 陈高波 安提督 宗雄 桑飞虹 倪不大 倪不小 常赫志 常伯志 上官铁生 哈赤大师 心砚 石双英 刘之余 童怀道 李廷豹 石万嗔 木文察 陈家洛 无尘道长 德布 李沅芷 余鱼同 司徒雷 谢不当 黄希节
马行空 马春花 徐铮 商宝震 何思豪 阎基 田归农 苗人凤 南仁通 补锅匠 脚夫 车夫 蒋调侯 店伴 钟兆文 钟兆英 钟兆能 南兰 苗若兰 商老太 平四 胡斐 张总管 王剑英 王剑杰 陈禹 古若般 殷仲翔 福康安 赵半山 孙刚峰 吕小妹 钟四嫂 易吉钟小二 钟阿四 胖商人 瘦商人 凤南天 凤七 俞朝奉 蛇皮张 邝宝官 凤一鸣 大汉 孙伏虎 尉迟连 杨宾 中年武师 程灵素同桌后生 袁紫衣 刘鹤真 崔百胜 曹猛 蓝秦 王仲萍 张飞雄 慕容景岳 姜铁山 薛鹊 王铁匠 姜小铁 田青文 张管家 聂钺 上官 褚轰 汪铁鹗 周铁鹤 曾铁鸥 秦耐之 姬晓峰 张九 任通武 相国夫人 蔡威 汤沛 无青子 海兰弼 大智禅师 欧阳公政 西灵道人 文醉翁 周隆 郭玉堂 齐伯涛 陈高波 安提督 宗雄 桑飞虹 倪不大 倪不小 常赫志 常伯志 上官铁生 哈赤大师 心砚 石双英 刘之余 童怀道 李廷豹 石万嗔 木文察 陈家洛 无尘道长 德布 李沅芷 余鱼同 司徒雷 谢不当 黄希节
...
@@ -38,35 +42,46 @@ var doc = `
...
@@ -38,35 +42,46 @@ var doc = `
《鸳鸯刀》人物(共有15人)
《鸳鸯刀》人物(共有15人)
任飞燕 刘於义 杨夫人 花剑影 林玉龙 周威信 卓天雄 逍遥子 袁夫人 袁冠南 常长风 盖一鸣 萧半和 萧中慧(杨中慧) 书僮
任飞燕 刘於义 杨夫人 花剑影 林玉龙 周威信 卓天雄 逍遥子 袁夫人 袁冠南 常长风 盖一鸣 萧半和 萧中慧(杨中慧) 书僮
`
`
var
books
=
[]
string
{}
func
init
()
{
func
parseNicknameDoc
()
{
lns
:=
strings
.
Split
(
doc
,
"
\n
"
)
bookReg
:=
regexp
.
MustCompile
(
`《(.*)》`
)
for
i
,
ln
:=
range
lns
{
lns
:=
strings
.
Split
(
strings
.
Trim
(
doc
,
"
\n
"
),
"
\n
"
)
if
i
%
2
==
0
{
bookName
:=
"book"
continue
for
_
,
ln
:=
range
lns
{
find
:=
bookReg
.
FindStringSubmatch
(
ln
)
if
len
(
find
)
==
2
{
bookName
=
find
[
1
]
books
=
append
(
books
,
bookName
)
}
else
{
names
:=
strings
.
Split
(
strings
.
Trim
(
ln
,
" "
),
" "
)
if
old
,
ok
:=
nicknameMap
[
bookName
];
ok
{
nicknameMap
[
bookName
]
=
append
(
old
,
names
...
)
}
else
{
nicknameMap
[
bookName
]
=
names
}
}
}
names
:=
strings
.
Split
(
ln
,
" "
)
nicknames
=
append
(
nicknames
,
names
...
)
}
}
idx
=
rand
.
Intn
(
len
(
nicknames
))
}
}
func
Get
()
string
{
var
l
=
new
(
sync
.
Mutex
)
idx
++
var
bookIdx
,
nicknameIdx
=
0
,
0
if
idx
>=
len
(
nicknames
)
{
idx
=
0
func
init
()
{
}
rand
.
Seed
(
time
.
Now
()
.
UnixNano
())
return
nicknames
[
idx
]
parseNicknameDoc
()
bookIdx
=
rand
.
Intn
(
len
(
books
))
}
}
var
a
=
`
func
Get
()
(
string
,
string
)
{
GET / HTTP/1.1
l
.
Lock
()
Host: sale.haogu.127.0.0.1.xip.io
defer
l
.
Unlock
()
Connection: keep-alive
if
nicknameIdx
>=
len
(
nicknameMap
[
books
[
bookIdx
]])
{
Upgrade-Insecure-Requests: 1
nicknameIdx
=
0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
bookIdx
=
(
bookIdx
+
1
)
%
len
(
books
)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
}
Accept-Encoding: gzip, deflate
book
:=
books
[
bookIdx
]
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
nickname
:=
nicknameMap
[
book
][
nicknameIdx
]
Cookie: pigcms_sessionid=ec43cd5c99f9cc21b9d4bebf439b9a16
nicknameIdx
++
`
return
nickname
,
fmt
.
Sprintf
(
"/demo/avatar/%s/%s.jpg"
,
book
,
nickname
)
}
server/demo/rpc/host-handler.go
浏览文件 @
b220f2fd
...
@@ -40,12 +40,13 @@ var hostRpcMap = map[string]realtime.RpcHandler{
...
@@ -40,12 +40,13 @@ var hostRpcMap = map[string]realtime.RpcHandler{
"sessionId"
:
state
.
session
.
Id
(),
"sessionId"
:
state
.
session
.
Id
(),
}
}
manager
.
lastInServiceOrder
=
state
.
order
manager
.
lastInServiceOrder
=
state
.
order
server
.
RoomByName
(
"room.slave.all.user."
+
slaveName
)
.
Join
(
state
.
session
.
Id
())
server
.
RoomByName
(
"room.all.user"
)
.
Broadcast
(
"ticket.turn"
,
gson
{
server
.
RoomByName
(
"room.all.user"
)
.
Broadcast
(
"ticket.turn"
,
gson
{
"order"
:
state
.
order
,
"order"
:
state
.
order
,
"host"
:
host
.
name
,
"sessionId"
:
state
.
session
.
Id
(),
"slave"
:
slaveName
,
"host"
:
host
.
name
,
"slave"
:
slaveName
,
})
})
server
.
RoomByName
(
"room.slave.all.user."
+
slaveName
)
.
Join
(
state
.
session
.
Id
())
slave
.
userWaitState
=
state
slave
.
userWaitState
=
state
slave
.
state
=
slaveStateStarting
slave
.
state
=
slaveStateStarting
return
return
...
...
server/demo/rpc/roles.go
浏览文件 @
b220f2fd
...
@@ -29,6 +29,7 @@ type roleUser struct {
...
@@ -29,6 +29,7 @@ type roleUser struct {
session
*
realtime
.
Session
session
*
realtime
.
Session
nickname
string
// 随机分配花名
nickname
string
// 随机分配花名
avatar
string
// 随机分配花名
waitState
*
waitState
waitState
*
waitState
}
}
...
@@ -36,6 +37,7 @@ type roleUser struct {
...
@@ -36,6 +37,7 @@ type roleUser struct {
func
(
user
*
roleUser
)
publicInfo
()
gson
{
func
(
user
*
roleUser
)
publicInfo
()
gson
{
return
gson
{
return
gson
{
"nickname"
:
user
.
nickname
,
"nickname"
:
user
.
nickname
,
"avatar"
:
user
.
avatar
,
}
}
}
}
...
...
server/demo/rpc/rpc-init.go
浏览文件 @
b220f2fd
...
@@ -121,7 +121,7 @@ func onNewSession(ss *realtime.Session) error {
...
@@ -121,7 +121,7 @@ func onNewSession(ss *realtime.Session) error {
if
role
==
"user"
{
if
role
==
"user"
{
server
.
RoomByName
(
"room.all.user"
)
.
Join
(
ss
.
Id
())
server
.
RoomByName
(
"room.all.user"
)
.
Join
(
ss
.
Id
())
ss
.
Data
.
(
*
roleUser
)
.
nickname
=
nickname
.
Get
()
ss
.
Data
.
(
*
roleUser
)
.
nickname
,
ss
.
Data
.
(
*
roleUser
)
.
avatar
=
nickname
.
Get
()
}
}
if
role
==
"host"
{
if
role
==
"host"
{
...
...
server/demo/rpc/user-handler.go
浏览文件 @
b220f2fd
...
@@ -95,21 +95,16 @@ var userRpcMap = map[string]realtime.RpcHandler{
...
@@ -95,21 +95,16 @@ var userRpcMap = map[string]realtime.RpcHandler{
server
.
RoomByName
(
roomName
)
.
Remove
(
ss
.
Id
())
server
.
RoomByName
(
roomName
)
.
Remove
(
ss
.
Id
())
return
return
}),
}),
"user.room.members"
:
realtime
.
RpcHandleFunc
(
func
(
ss
*
realtime
.
Session
,
data
gson
)
(
result
interface
{},
err
error
)
{
roomName
:=
data
[
"room"
]
.
(
string
)
if
server
.
RoomExist
(
roomName
)
{
return
server
.
RoomByName
(
roomName
)
.
Members
(),
nil
}
return
nil
,
errors
.
New
(
"room not exist"
)
}),
"user.session.public.info"
:
sessionPublicInfo
,
"user.session.public.info"
:
sessionPublicInfo
,
}
}
var
userEventMap
=
map
[
string
]
realtime
.
EventHandler
{
var
userEventMap
=
map
[
string
]
realtime
.
EventHandler
{
"user.chat.msg"
:
realtime
.
EventHandleFunc
(
func
(
ss
*
realtime
.
Session
,
data
interface
{})
{
payload
:=
data
.
(
gson
)
room
:=
payload
[
"room"
]
.
(
string
)
msg
:=
payload
[
"msg"
]
if
ss
.
InRoom
(
room
)
{
server
.
RoomByName
(
room
)
.
Broadcast
(
"chat.msg.new"
,
gson
{
"from"
:
ss
.
Id
(),
"msg"
:
msg
,
"room"
:
room
,
},
ss
.
Id
())
}
}),
"user.broadcast"
:
roleBroadcast
,
"user.broadcast"
:
roleBroadcast
,
}
}
server/realtime/room.go
浏览文件 @
b220f2fd
...
@@ -83,6 +83,11 @@ func (r *Room) Remove(id SessionId) {
...
@@ -83,6 +83,11 @@ func (r *Room) Remove(id SessionId) {
return
return
}
}
go
r
.
Broadcast
(
"room.member.remove"
,
id
)
go
r
.
Broadcast
(
"room.member.remove"
,
id
)
go
func
()
{
if
ss
,
ok
:=
r
.
server
.
SessionById
(
id
);
ok
{
ss
.
Emit
(
"room.leave"
,
r
.
name
)
}
}()
if
idx
==
len
(
r
.
members
)
-
1
{
if
idx
==
len
(
r
.
members
)
-
1
{
r
.
members
=
r
.
members
[
:
idx
]
r
.
members
=
r
.
members
[
:
idx
]
return
return
...
@@ -92,11 +97,6 @@ func (r *Room) Remove(id SessionId) {
...
@@ -92,11 +97,6 @@ func (r *Room) Remove(id SessionId) {
return
return
}
}
r
.
members
=
append
(
r
.
members
[
:
idx
],
r
.
members
[
idx
+
1
:
]
...
)
r
.
members
=
append
(
r
.
members
[
:
idx
],
r
.
members
[
idx
+
1
:
]
...
)
go
func
()
{
if
ss
,
ok
:=
r
.
server
.
SessionById
(
id
);
ok
{
ss
.
Emit
(
"room.leave"
,
r
.
name
)
}
}()
}
}
func
(
r
*
Room
)
Members
()
[]
SessionId
{
func
(
r
*
Room
)
Members
()
[]
SessionId
{
...
...
server/realtime/server.go
浏览文件 @
b220f2fd
...
@@ -178,6 +178,13 @@ func (s *Server) RoomByName(name string) *Room {
...
@@ -178,6 +178,13 @@ func (s *Server) RoomByName(name string) *Room {
return
room
return
room
}
}
func
(
s
*
Server
)
RoomExist
(
name
string
)
bool
{
s
.
roomMapLock
.
Lock
()
defer
s
.
roomMapLock
.
Unlock
()
_
,
ok
:=
s
.
roomMap
[
name
]
return
ok
}
func
(
s
*
Server
)
handleWsConn
(
conn
*
websocket
.
Conn
)
{
func
(
s
*
Server
)
handleWsConn
(
conn
*
websocket
.
Conn
)
{
log
.
Println
(
"new ws conn"
,
conn
.
RemoteAddr
())
log
.
Println
(
"new ws conn"
,
conn
.
RemoteAddr
())
var
err
error
var
err
error
...
...
server/static/.gitignore
0 → 100644
浏览文件 @
b220f2fd
*
!.gitignore
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录