Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
G
getty
Project
Project
Details
Activity
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
wei.xuan
getty
Commits
4cf247e1
Commit
4cf247e1
authored
Feb 03, 2017
by
AlexStocks
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add compression type and delete this
parent
8abb0aa7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
399 additions
and
383 deletions
+399
-383
change_log.md
change_log.md
+5
-1
client.go
client.go
+62
-62
conn.go
conn.go
+101
-89
server.go
server.go
+46
-46
session.go
session.go
+185
-185
No files found.
change_log.md
View file @
4cf247e1
...
@@ -14,7 +14,11 @@
...
@@ -14,7 +14,11 @@
-
2017/02/03
-
2017/02/03
> 1 Session struct -> session struct and add Session interface
> 1 Session struct -> session struct and add Session interface
>
>
> 2 version: 0.7.0
> 2 change receiver name from this to a alphabet letter
>
> 3 add compression type
>
> 4 version: 0.7.0
-
2016/11/19
-
2016/11/19
> 1 add conn.go:(*gettyWSConn) setCompressType to add zip compress feature for ws connection
> 1 add conn.go:(*gettyWSConn) setCompressType to add zip compress feature for ws connection
...
...
client.go
View file @
4cf247e1
...
@@ -97,17 +97,17 @@ func NewWSSClient(connNum int, connInterval time.Duration, serverAddr string, ce
...
@@ -97,17 +97,17 @@ func NewWSSClient(connNum int, connInterval time.Duration, serverAddr string, ce
}
}
}
}
func
(
this
*
Client
)
dialTCP
()
Session
{
func
(
c
*
Client
)
dialTCP
()
Session
{
var
(
var
(
err
error
err
error
conn
net
.
Conn
conn
net
.
Conn
)
)
for
{
for
{
if
this
.
IsClosed
()
{
if
c
.
IsClosed
()
{
return
nil
return
nil
}
}
conn
,
err
=
net
.
DialTimeout
(
"tcp"
,
this
.
addr
,
connectTimeout
)
conn
,
err
=
net
.
DialTimeout
(
"tcp"
,
c
.
addr
,
connectTimeout
)
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
err
=
errSelfConnect
err
=
errSelfConnect
}
}
...
@@ -115,13 +115,13 @@ func (this *Client) dialTCP() Session {
...
@@ -115,13 +115,13 @@ func (this *Client) dialTCP() Session {
return
NewTCPSession
(
conn
)
return
NewTCPSession
(
conn
)
}
}
log
.
Info
(
"net.DialTimeout(addr:%s, timeout:%v) = error{%v}"
,
this
.
addr
,
err
)
log
.
Info
(
"net.DialTimeout(addr:%s, timeout:%v) = error{%v}"
,
c
.
addr
,
err
)
time
.
Sleep
(
this
.
interval
)
time
.
Sleep
(
c
.
interval
)
continue
continue
}
}
}
}
func
(
this
*
Client
)
dialWS
()
Session
{
func
(
c
*
Client
)
dialWS
()
Session
{
var
(
var
(
err
error
err
error
dialer
websocket
.
Dialer
dialer
websocket
.
Dialer
...
@@ -131,10 +131,10 @@ func (this *Client) dialWS() Session {
...
@@ -131,10 +131,10 @@ func (this *Client) dialWS() Session {
dialer
.
EnableCompression
=
true
dialer
.
EnableCompression
=
true
for
{
for
{
if
this
.
IsClosed
()
{
if
c
.
IsClosed
()
{
return
nil
return
nil
}
}
conn
,
_
,
err
=
dialer
.
Dial
(
this
.
addr
,
nil
)
conn
,
_
,
err
=
dialer
.
Dial
(
c
.
addr
,
nil
)
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
err
=
errSelfConnect
err
=
errSelfConnect
}
}
...
@@ -147,13 +147,13 @@ func (this *Client) dialWS() Session {
...
@@ -147,13 +147,13 @@ func (this *Client) dialWS() Session {
return
session
return
session
}
}
log
.
Info
(
"websocket.dialer.Dial(addr:%s) = error{%v}"
,
this
.
addr
,
err
)
log
.
Info
(
"websocket.dialer.Dial(addr:%s) = error{%v}"
,
c
.
addr
,
err
)
time
.
Sleep
(
this
.
interval
)
time
.
Sleep
(
c
.
interval
)
continue
continue
}
}
}
}
func
(
this
*
Client
)
dialWSS
()
Session
{
func
(
c
*
Client
)
dialWSS
()
Session
{
var
(
var
(
err
error
err
error
certPem
[]
byte
certPem
[]
byte
...
@@ -164,9 +164,9 @@ func (this *Client) dialWSS() Session {
...
@@ -164,9 +164,9 @@ func (this *Client) dialWSS() Session {
)
)
dialer
.
EnableCompression
=
true
dialer
.
EnableCompression
=
true
certPem
,
err
=
ioutil
.
ReadFile
(
this
.
certFile
)
certPem
,
err
=
ioutil
.
ReadFile
(
c
.
certFile
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"ioutil.ReadFile(certFile{%s}) = err{%#v}"
,
this
.
certFile
,
err
))
panic
(
fmt
.
Errorf
(
"ioutil.ReadFile(certFile{%s}) = err{%#v}"
,
c
.
certFile
,
err
))
}
}
certPool
=
x509
.
NewCertPool
()
certPool
=
x509
.
NewCertPool
()
if
ok
:=
certPool
.
AppendCertsFromPEM
(
certPem
);
!
ok
{
if
ok
:=
certPool
.
AppendCertsFromPEM
(
certPem
);
!
ok
{
...
@@ -176,10 +176,10 @@ func (this *Client) dialWSS() Session {
...
@@ -176,10 +176,10 @@ func (this *Client) dialWSS() Session {
// dialer.EnableCompression = true
// dialer.EnableCompression = true
dialer
.
TLSClientConfig
=
&
tls
.
Config
{
RootCAs
:
certPool
}
dialer
.
TLSClientConfig
=
&
tls
.
Config
{
RootCAs
:
certPool
}
for
{
for
{
if
this
.
IsClosed
()
{
if
c
.
IsClosed
()
{
return
nil
return
nil
}
}
conn
,
_
,
err
=
dialer
.
Dial
(
this
.
addr
,
nil
)
conn
,
_
,
err
=
dialer
.
Dial
(
c
.
addr
,
nil
)
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
if
err
==
nil
&&
conn
.
LocalAddr
()
.
String
()
==
conn
.
RemoteAddr
()
.
String
()
{
err
=
errSelfConnect
err
=
errSelfConnect
}
}
...
@@ -192,56 +192,56 @@ func (this *Client) dialWSS() Session {
...
@@ -192,56 +192,56 @@ func (this *Client) dialWSS() Session {
return
session
return
session
}
}
log
.
Info
(
"websocket.dialer.Dial(addr:%s) = error{%v}"
,
this
.
addr
,
err
)
log
.
Info
(
"websocket.dialer.Dial(addr:%s) = error{%v}"
,
c
.
addr
,
err
)
time
.
Sleep
(
this
.
interval
)
time
.
Sleep
(
c
.
interval
)
continue
continue
}
}
}
}
func
(
this
*
Client
)
dial
()
Session
{
func
(
c
*
Client
)
dial
()
Session
{
if
strings
.
HasPrefix
(
this
.
addr
,
"ws"
)
{
if
strings
.
HasPrefix
(
c
.
addr
,
"ws"
)
{
return
this
.
dialWS
()
return
c
.
dialWS
()
}
else
if
strings
.
HasPrefix
(
this
.
addr
,
"wss"
)
{
}
else
if
strings
.
HasPrefix
(
c
.
addr
,
"wss"
)
{
return
this
.
dialWSS
()
return
c
.
dialWSS
()
}
}
return
this
.
dialTCP
()
return
c
.
dialTCP
()
}
}
func
(
this
*
Client
)
sessionNum
()
int
{
func
(
c
*
Client
)
sessionNum
()
int
{
var
num
int
var
num
int
this
.
Lock
()
c
.
Lock
()
for
s
:=
range
this
.
sessionMap
{
for
s
:=
range
c
.
sessionMap
{
if
s
.
IsClosed
()
{
if
s
.
IsClosed
()
{
delete
(
this
.
sessionMap
,
s
)
delete
(
c
.
sessionMap
,
s
)
}
}
}
}
num
=
len
(
this
.
sessionMap
)
num
=
len
(
c
.
sessionMap
)
this
.
Unlock
()
c
.
Unlock
()
return
num
return
num
}
}
func
(
this
*
Client
)
connect
()
{
func
(
c
*
Client
)
connect
()
{
var
(
var
(
err
error
err
error
session
Session
session
Session
)
)
for
{
for
{
session
=
this
.
dial
()
session
=
c
.
dial
()
if
session
==
nil
{
if
session
==
nil
{
// client has been closed
// client has been closed
break
break
}
}
err
=
this
.
newSession
(
session
)
err
=
c
.
newSession
(
session
)
if
err
==
nil
{
if
err
==
nil
{
// session.RunEventLoop()
// session.RunEventLoop()
session
.
(
*
session
)
.
run
()
session
.
(
*
session
)
.
run
()
this
.
Lock
()
c
.
Lock
()
this
.
sessionMap
[
session
]
=
gxsync
.
Empty
{}
c
.
sessionMap
[
session
]
=
gxsync
.
Empty
{}
this
.
Unlock
()
c
.
Unlock
()
break
break
}
}
// don't distinguish between tcp connection and websocket connection. Because
// don't distinguish between tcp connection and websocket connection. Because
...
@@ -250,27 +250,27 @@ func (this *Client) connect() {
...
@@ -250,27 +250,27 @@ func (this *Client) connect() {
}
}
}
}
func
(
this
*
Client
)
RunEventLoop
(
newSession
NewSessionCallback
)
{
func
(
c
*
Client
)
RunEventLoop
(
newSession
NewSessionCallback
)
{
this
.
Lock
()
c
.
Lock
()
this
.
newSession
=
newSession
c
.
newSession
=
newSession
this
.
Unlock
()
c
.
Unlock
()
this
.
wg
.
Add
(
1
)
c
.
wg
.
Add
(
1
)
go
func
()
{
go
func
()
{
var
num
,
max
,
times
int
var
num
,
max
,
times
int
defer
this
.
wg
.
Done
()
defer
c
.
wg
.
Done
()
this
.
Lock
()
c
.
Lock
()
max
=
this
.
number
max
=
c
.
number
this
.
Unlock
()
c
.
Unlock
()
// log.Info("maximum client connection number:%d", max)
// log.Info("maximum client connection number:%d", max)
for
{
for
{
if
this
.
IsClosed
()
{
if
c
.
IsClosed
()
{
log
.
Warn
(
"client{peer:%s} goroutine exit now."
,
this
.
addr
)
log
.
Warn
(
"client{peer:%s} goroutine exit now."
,
c
.
addr
)
break
break
}
}
num
=
this
.
sessionNum
()
num
=
c
.
sessionNum
()
// log.Info("current client connction number:%d", num)
// log.Info("current client connction number:%d", num)
if
max
<=
num
{
if
max
<=
num
{
times
++
times
++
...
@@ -281,39 +281,39 @@ func (this *Client) RunEventLoop(newSession NewSessionCallback) {
...
@@ -281,39 +281,39 @@ func (this *Client) RunEventLoop(newSession NewSessionCallback) {
continue
continue
}
}
times
=
0
times
=
0
this
.
connect
()
c
.
connect
()
// time.Sleep(
this.interval) // build this
.number connections asap
// time.Sleep(
c.interval) // build c
.number connections asap
}
}
}()
}()
}
}
func
(
this
*
Client
)
stop
()
{
func
(
c
*
Client
)
stop
()
{
select
{
select
{
case
<-
this
.
done
:
case
<-
c
.
done
:
return
return
default
:
default
:
this
.
Once
.
Do
(
func
()
{
c
.
Once
.
Do
(
func
()
{
close
(
this
.
done
)
close
(
c
.
done
)
this
.
Lock
()
c
.
Lock
()
for
s
:=
range
this
.
sessionMap
{
for
s
:=
range
c
.
sessionMap
{
s
.
Close
()
s
.
Close
()
}
}
this
.
sessionMap
=
nil
c
.
sessionMap
=
nil
this
.
Unlock
()
c
.
Unlock
()
})
})
}
}
}
}
func
(
this
*
Client
)
IsClosed
()
bool
{
func
(
c
*
Client
)
IsClosed
()
bool
{
select
{
select
{
case
<-
this
.
done
:
case
<-
c
.
done
:
return
true
return
true
default
:
default
:
return
false
return
false
}
}
}
}
func
(
this
*
Client
)
Close
()
{
func
(
c
*
Client
)
Close
()
{
this
.
stop
()
c
.
stop
()
this
.
wg
.
Wait
()
c
.
wg
.
Wait
()
}
}
conn.go
View file @
4cf247e1
...
@@ -36,12 +36,15 @@ var (
...
@@ -36,12 +36,15 @@ var (
// compress
// compress
/////////////////////////////////////////
/////////////////////////////////////////
type
CompressType
byte
type
CompressType
int
const
(
const
(
CompressNone
CompressType
=
0x00
CompressNone
CompressType
=
flate
.
NoCompression
// 0
CompressZip
=
0x01
CompressZip
=
flate
.
DefaultCompression
// -1
CompressSnappy
=
0x02
CompressBestSpeed
=
flate
.
BestSpeed
// 1
CompressBestCompression
=
flate
.
BestCompression
// 9
CompressHuffman
=
flate
.
HuffmanOnly
// -2
CompressSnappy
=
10
)
)
/////////////////////////////////////////
/////////////////////////////////////////
...
@@ -95,65 +98,65 @@ type gettyConn struct {
...
@@ -95,65 +98,65 @@ type gettyConn struct {
peer
string
// peer address
peer
string
// peer address
}
}
func
(
this
*
gettyConn
)
ID
()
uint32
{
func
(
c
*
gettyConn
)
ID
()
uint32
{
return
this
.
id
return
c
.
id
}
}
func
(
this
*
gettyConn
)
LocalAddr
()
string
{
func
(
c
*
gettyConn
)
LocalAddr
()
string
{
return
this
.
local
return
c
.
local
}
}
func
(
this
*
gettyConn
)
RemoteAddr
()
string
{
func
(
c
*
gettyConn
)
RemoteAddr
()
string
{
return
this
.
peer
return
c
.
peer
}
}
func
(
this
*
gettyConn
)
incReadPkgCount
()
{
func
(
c
*
gettyConn
)
incReadPkgCount
()
{
atomic
.
AddUint32
(
&
this
.
readPkgCount
,
1
)
atomic
.
AddUint32
(
&
c
.
readPkgCount
,
1
)
}
}
func
(
this
*
gettyConn
)
incWritePkgCount
()
{
func
(
c
*
gettyConn
)
incWritePkgCount
()
{
atomic
.
AddUint32
(
&
this
.
writePkgCount
,
1
)
atomic
.
AddUint32
(
&
c
.
writePkgCount
,
1
)
}
}
func
(
this
*
gettyConn
)
UpdateActive
()
{
func
(
c
*
gettyConn
)
UpdateActive
()
{
atomic
.
StoreInt64
(
&
(
this
.
active
),
int64
(
time
.
Since
(
launchTime
)))
atomic
.
StoreInt64
(
&
(
c
.
active
),
int64
(
time
.
Since
(
launchTime
)))
}
}
func
(
this
*
gettyConn
)
GetActive
()
time
.
Time
{
func
(
c
*
gettyConn
)
GetActive
()
time
.
Time
{
return
launchTime
.
Add
(
time
.
Duration
(
atomic
.
LoadInt64
(
&
(
this
.
active
))))
return
launchTime
.
Add
(
time
.
Duration
(
atomic
.
LoadInt64
(
&
(
c
.
active
))))
}
}
func
(
this
*
gettyConn
)
Write
([]
byte
)
error
{
func
(
c
*
gettyConn
)
Write
([]
byte
)
error
{
return
nil
return
nil
}
}
func
(
this
*
gettyConn
)
close
(
int
)
{}
func
(
c
*
gettyConn
)
close
(
int
)
{}
func
(
this
gettyConn
)
readDeadline
()
time
.
Duration
{
func
(
c
gettyConn
)
readDeadline
()
time
.
Duration
{
return
this
.
rDeadline
return
c
.
rDeadline
}
}
func
(
this
*
gettyConn
)
SetReadDeadline
(
rDeadline
time
.
Duration
)
{
func
(
c
*
gettyConn
)
SetReadDeadline
(
rDeadline
time
.
Duration
)
{
if
rDeadline
<
1
{
if
rDeadline
<
1
{
panic
(
"@rDeadline < 1"
)
panic
(
"@rDeadline < 1"
)
}
}
this
.
rDeadline
=
rDeadline
c
.
rDeadline
=
rDeadline
if
this
.
wDeadline
==
0
{
if
c
.
wDeadline
==
0
{
this
.
wDeadline
=
rDeadline
c
.
wDeadline
=
rDeadline
}
}
}
}
func
(
this
gettyConn
)
writeDeadline
()
time
.
Duration
{
func
(
c
gettyConn
)
writeDeadline
()
time
.
Duration
{
return
this
.
wDeadline
return
c
.
wDeadline
}
}
func
(
this
*
gettyConn
)
SetWriteDeadline
(
wDeadline
time
.
Duration
)
{
func
(
c
*
gettyConn
)
SetWriteDeadline
(
wDeadline
time
.
Duration
)
{
if
wDeadline
<
1
{
if
wDeadline
<
1
{
panic
(
"@wDeadline < 1"
)
panic
(
"@wDeadline < 1"
)
}
}
this
.
wDeadline
=
wDeadline
c
.
wDeadline
=
wDeadline
}
}
/////////////////////////////////////////
/////////////////////////////////////////
...
@@ -199,17 +202,17 @@ type writeFlusher struct {
...
@@ -199,17 +202,17 @@ type writeFlusher struct {
flusher
*
flate
.
Writer
flusher
*
flate
.
Writer
}
}
func
(
t
his
*
writeFlusher
)
Write
(
p
[]
byte
)
(
int
,
error
)
{
func
(
t
*
writeFlusher
)
Write
(
p
[]
byte
)
(
int
,
error
)
{
var
(
var
(
n
int
n
int
err
error
err
error
)
)
n
,
err
=
t
his
.
flusher
.
Write
(
p
)
n
,
err
=
t
.
flusher
.
Write
(
p
)
if
err
!=
nil
{
if
err
!=
nil
{
return
n
,
err
return
n
,
err
}
}
if
err
:=
t
his
.
flusher
.
Flush
();
err
!=
nil
{
if
err
:=
t
.
flusher
.
Flush
();
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
...
@@ -217,60 +220,69 @@ func (this *writeFlusher) Write(p []byte) (int, error) {
...
@@ -217,60 +220,69 @@ func (this *writeFlusher) Write(p []byte) (int, error) {
}
}
// set compress type(tcp: zip/snappy, websocket:zip)
// set compress type(tcp: zip/snappy, websocket:zip)
func
(
t
his
*
gettyTCPConn
)
SetCompressType
(
t
CompressType
)
{
func
(
t
*
gettyTCPConn
)
SetCompressType
(
c
CompressType
)
{
switch
{
switch
c
{
case
t
==
CompressZip
:
case
CompressNone
,
CompressZip
,
CompressBestSpeed
,
CompressBestCompression
,
CompressHuffman
:
t
his
.
reader
=
flate
.
NewReader
(
this
.
conn
)
t
.
reader
=
flate
.
NewReader
(
t
.
conn
)
w
,
err
:=
flate
.
NewWriter
(
t
his
.
conn
,
flate
.
DefaultCompression
)
w
,
err
:=
flate
.
NewWriter
(
t
.
conn
,
int
(
c
)
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"flate.NewReader(flate.DefaultCompress) = err(%s)"
,
err
))
panic
(
fmt
.
Sprintf
(
"flate.NewReader(flate.DefaultCompress) = err(%s)"
,
err
))
}
}
t
his
.
writer
=
&
writeFlusher
{
flusher
:
w
}
t
.
writer
=
&
writeFlusher
{
flusher
:
w
}
case
t
==
CompressSnappy
:
case
CompressSnappy
:
this
.
reader
=
snappy
.
NewReader
(
this
.
conn
)
t
.
reader
=
snappy
.
NewReader
(
t
.
conn
)
this
.
writer
=
snappy
.
NewWriter
(
this
.
conn
)
// t.writer = snappy.NewWriter(t.conn)
t
.
writer
=
snappy
.
NewBufferedWriter
(
t
.
conn
)
default
:
panic
(
fmt
.
Sprintf
(
"illegal comparess type %d"
,
c
))
}
}
}
}
// tcp connection read
// tcp connection read
func
(
t
his
*
gettyTCPConn
)
read
(
p
[]
byte
)
(
int
,
error
)
{
func
(
t
*
gettyTCPConn
)
read
(
p
[]
byte
)
(
int
,
error
)
{
// if t
his
.conn == nil {
// if t.conn == nil {
// return 0, ErrInvalidConnection
// return 0, ErrInvalidConnection
// }
// }
// atomic.AddUint32(&t
his
.readCount, 1)
// atomic.AddUint32(&t.readCount, 1)
// l, e := t
his
.conn.Read(p)
// l, e := t.conn.Read(p)
l
,
e
:=
t
his
.
reader
.
Read
(
p
)
l
,
e
:=
t
.
reader
.
Read
(
p
)
atomic
.
AddUint32
(
&
t
his
.
readCount
,
uint32
(
l
))
atomic
.
AddUint32
(
&
t
.
readCount
,
uint32
(
l
))
return
l
,
e
return
l
,
e
}
}
// tcp connection write
// tcp connection write
func
(
t
his
*
gettyTCPConn
)
Write
(
p
[]
byte
)
error
{
func
(
t
*
gettyTCPConn
)
Write
(
p
[]
byte
)
error
{
// if t
his
.conn == nil {
// if t.conn == nil {
// return 0, ErrInvalidConnection
// return 0, ErrInvalidConnection
// }
// }
// atomic.AddUint32(&t
his
.writeCount, 1)
// atomic.AddUint32(&t.writeCount, 1)
atomic
.
AddUint32
(
&
t
his
.
writeCount
,
(
uint32
)(
len
(
p
)))
atomic
.
AddUint32
(
&
t
.
writeCount
,
(
uint32
)(
len
(
p
)))
// _, err := t
his
.conn.Write(p)
// _, err := t.conn.Write(p)
_
,
err
:=
t
his
.
writer
.
Write
(
p
)
_
,
err
:=
t
.
writer
.
Write
(
p
)
return
err
return
err
}
}
// close tcp connection
// close tcp connection
func
(
t
his
*
gettyTCPConn
)
close
(
waitSec
int
)
{
func
(
t
*
gettyTCPConn
)
close
(
waitSec
int
)
{
// if tcpConn, ok := t
his
.conn.(*net.TCPConn); ok {
// if tcpConn, ok := t.conn.(*net.TCPConn); ok {
// tcpConn.SetLinger(0)
// tcpConn.SetLinger(0)
// }
// }
if
this
.
conn
!=
nil
{
if
t
.
conn
!=
nil
{
this
.
conn
.
(
*
net
.
TCPConn
)
.
SetLinger
(
waitSec
)
if
writer
,
ok
:=
t
.
writer
.
(
*
snappy
.
Writer
);
ok
{
this
.
conn
.
Close
()
if
err
:=
writer
.
Close
();
err
!=
nil
{
this
.
conn
=
nil
log
.
Error
(
"snappy.Writer.Close() = error{%v}"
,
err
)
}
}
t
.
conn
.
(
*
net
.
TCPConn
)
.
SetLinger
(
waitSec
)
t
.
conn
.
Close
()
t
.
conn
=
nil
}
}
}
}
...
@@ -312,44 +324,44 @@ func newGettyWSConn(conn *websocket.Conn) *gettyWSConn {
...
@@ -312,44 +324,44 @@ func newGettyWSConn(conn *websocket.Conn) *gettyWSConn {
return
gettyWSConn
return
gettyWSConn
}
}
// set compress type
(tcp: zip/snappy, websocket:zip)
// set compress type
func
(
this
*
gettyWSConn
)
SetCompressType
(
t
CompressType
)
{
func
(
w
*
gettyWSConn
)
SetCompressType
(
c
CompressType
)
{
switch
{
switch
c
{
case
t
==
CompressZip
:
case
CompressNone
,
CompressZip
,
CompressBestSpeed
,
CompressBestCompression
,
CompressHuffman
:
this
.
conn
.
EnableWriteCompression
(
true
)
w
.
conn
.
EnableWriteCompression
(
true
)
case
t
==
CompressSnappy
:
w
.
conn
.
SetCompressionLevel
(
int
(
c
))
this
.
conn
.
EnableWriteCompression
(
true
)
default
:
default
:
this
.
conn
.
EnableWriteCompression
(
false
)
panic
(
fmt
.
Sprintf
(
"illegal comparess type %d"
,
c
)
)
}
}
}
}
func
(
this
*
gettyWSConn
)
handlePing
(
message
string
)
error
{
func
(
w
*
gettyWSConn
)
handlePing
(
message
string
)
error
{
err
:=
this
.
conn
.
WriteMessage
(
websocket
.
PongMessage
,
[]
byte
(
message
))
err
:=
w
.
conn
.
WriteMessage
(
websocket
.
PongMessage
,
[]
byte
(
message
))
if
err
==
websocket
.
ErrCloseSent
{
if
err
==
websocket
.
ErrCloseSent
{
err
=
nil
err
=
nil
}
else
if
e
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
e
.
Temporary
()
{
}
else
if
e
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
e
.
Temporary
()
{
err
=
nil
err
=
nil
}
}
if
err
==
nil
{
if
err
==
nil
{
this
.
UpdateActive
()
w
.
UpdateActive
()
}
}
return
err
return
err
}
}
func
(
this
*
gettyWSConn
)
handlePong
(
string
)
error
{
func
(
w
*
gettyWSConn
)
handlePong
(
string
)
error
{
this
.
UpdateActive
()
w
.
UpdateActive
()
return
nil
return
nil
}
}
// websocket connection read
// websocket connection read
func
(
this
*
gettyWSConn
)
read
()
([]
byte
,
error
)
{
func
(
w
*
gettyWSConn
)
read
()
([]
byte
,
error
)
{
//
this.conn.SetReadDeadline(time.Now().Add(this
.rDeadline))
//
w.conn.SetReadDeadline(time.Now().Add(w
.rDeadline))
_
,
b
,
e
:=
this
.
conn
.
ReadMessage
()
// the first return value is message type.
_
,
b
,
e
:=
w
.
conn
.
ReadMessage
()
// the first return value is message type.
if
e
==
nil
{
if
e
==
nil
{
// atomic.AddUint32(&
this
.readCount, (uint32)(l))
// atomic.AddUint32(&
w
.readCount, (uint32)(l))
atomic
.
AddUint32
(
&
this
.
readPkgCount
,
1
)
atomic
.
AddUint32
(
&
w
.
readPkgCount
,
1
)
}
else
{
}
else
{
if
websocket
.
IsUnexpectedCloseError
(
e
,
websocket
.
CloseGoingAway
)
{
if
websocket
.
IsUnexpectedCloseError
(
e
,
websocket
.
CloseGoingAway
)
{
log
.
Warn
(
"websocket unexpected close error: %v"
,
e
)
log
.
Warn
(
"websocket unexpected close error: %v"
,
e
)
...
@@ -360,20 +372,20 @@ func (this *gettyWSConn) read() ([]byte, error) {
...
@@ -360,20 +372,20 @@ func (this *gettyWSConn) read() ([]byte, error) {
}
}
// websocket connection write
// websocket connection write
func
(
this
*
gettyWSConn
)
Write
(
p
[]
byte
)
error
{
func
(
w
*
gettyWSConn
)
Write
(
p
[]
byte
)
error
{
// atomic.AddUint32(&
this
.writeCount, 1)
// atomic.AddUint32(&
w
.writeCount, 1)
atomic
.
AddUint32
(
&
this
.
writeCount
,
(
uint32
)(
len
(
p
)))
atomic
.
AddUint32
(
&
w
.
writeCount
,
(
uint32
)(
len
(
p
)))
//
this.conn.SetWriteDeadline(time.Now().Add(this
.wDeadline))
//
w.conn.SetWriteDeadline(time.Now().Add(w
.wDeadline))
return
this
.
conn
.
WriteMessage
(
websocket
.
BinaryMessage
,
p
)
return
w
.
conn
.
WriteMessage
(
websocket
.
BinaryMessage
,
p
)
}
}
func
(
this
*
gettyWSConn
)
writePing
()
error
{
func
(
w
*
gettyWSConn
)
writePing
()
error
{
return
this
.
conn
.
WriteMessage
(
websocket
.
PingMessage
,
[]
byte
{})
return
w
.
conn
.
WriteMessage
(
websocket
.
PingMessage
,
[]
byte
{})
}
}
// close websocket connection
// close websocket connection
func
(
this
*
gettyWSConn
)
close
(
waitSec
int
)
{
func
(
w
*
gettyWSConn
)
close
(
waitSec
int
)
{
this
.
conn
.
WriteMessage
(
websocket
.
CloseMessage
,
[]
byte
(
"bye-bye!!!"
))
w
.
conn
.
WriteMessage
(
websocket
.
CloseMessage
,
[]
byte
(
"bye-bye!!!"
))
this
.
conn
.
UnderlyingConn
()
.
(
*
net
.
TCPConn
)
.
SetLinger
(
waitSec
)
w
.
conn
.
UnderlyingConn
()
.
(
*
net
.
TCPConn
)
.
SetLinger
(
waitSec
)
this
.
conn
.
Close
()
w
.
conn
.
Close
()
}
}
server.go
View file @
4cf247e1
...
@@ -43,23 +43,23 @@ func NewServer() *Server {
...
@@ -43,23 +43,23 @@ func NewServer() *Server {
return
&
Server
{
done
:
make
(
chan
gxsync
.
Empty
)}
return
&
Server
{
done
:
make
(
chan
gxsync
.
Empty
)}
}
}
func
(
thi
s
*
Server
)
stop
()
{
func
(
s
*
Server
)
stop
()
{
select
{
select
{
case
<-
thi
s
.
done
:
case
<-
s
.
done
:
return
return
default
:
default
:
thi
s
.
Once
.
Do
(
func
()
{
s
.
Once
.
Do
(
func
()
{
close
(
thi
s
.
done
)
close
(
s
.
done
)
// 把listener.Close放在这里,既能防止多次关闭调用,
// 把listener.Close放在这里,既能防止多次关闭调用,
// 又能及时让Server因accept返回错误而从RunEventloop退出
// 又能及时让Server因accept返回错误而从RunEventloop退出
thi
s
.
listener
.
Close
()
s
.
listener
.
Close
()
})
})
}
}
}
}
func
(
thi
s
*
Server
)
IsClosed
()
bool
{
func
(
s
*
Server
)
IsClosed
()
bool
{
select
{
select
{
case
<-
thi
s
.
done
:
case
<-
s
.
done
:
return
true
return
true
default
:
default
:
return
false
return
false
...
@@ -67,46 +67,46 @@ func (this *Server) IsClosed() bool {
...
@@ -67,46 +67,46 @@ func (this *Server) IsClosed() bool {
}
}
// (Server)Bind's functionality is equal to (Server)Listen.
// (Server)Bind's functionality is equal to (Server)Listen.
func
(
thi
s
*
Server
)
Bind
(
network
string
,
host
string
,
port
int
)
error
{
func
(
s
*
Server
)
Bind
(
network
string
,
host
string
,
port
int
)
error
{
if
port
<=
0
{
if
port
<=
0
{
return
errors
.
New
(
"port<=0 illegal"
)
return
errors
.
New
(
"port<=0 illegal"
)
}
}
return
thi
s
.
Listen
(
network
,
gxnet
.
HostAddress
(
host
,
port
))
return
s
.
Listen
(
network
,
gxnet
.
HostAddress
(
host
,
port
))
}
}
// net.ipv4.tcp_max_syn_backlog
// net.ipv4.tcp_max_syn_backlog
// net.ipv4.tcp_timestamps
// net.ipv4.tcp_timestamps
// net.ipv4.tcp_tw_recycle
// net.ipv4.tcp_tw_recycle
func
(
thi
s
*
Server
)
Listen
(
network
string
,
addr
string
)
error
{
func
(
s
*
Server
)
Listen
(
network
string
,
addr
string
)
error
{
listener
,
err
:=
net
.
Listen
(
network
,
addr
)
listener
,
err
:=
net
.
Listen
(
network
,
addr
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
thi
s
.
addr
=
addr
s
.
addr
=
addr
thi
s
.
listener
=
listener
s
.
listener
=
listener
return
nil
return
nil
}
}
func
(
thi
s
*
Server
)
RunEventloop
(
newSession
NewSessionCallback
)
{
func
(
s
*
Server
)
RunEventloop
(
newSession
NewSessionCallback
)
{
thi
s
.
wg
.
Add
(
1
)
s
.
wg
.
Add
(
1
)
go
func
()
{
go
func
()
{
defer
thi
s
.
wg
.
Done
()
defer
s
.
wg
.
Done
()
var
(
var
(
err
error
err
error
client
Session
client
Session
delay
time
.
Duration
delay
time
.
Duration
)
)
for
{
for
{
if
thi
s
.
IsClosed
()
{
if
s
.
IsClosed
()
{
log
.
Warn
(
"Server{%s} stop acceptting client connect request."
,
thi
s
.
addr
)
log
.
Warn
(
"Server{%s} stop acceptting client connect request."
,
s
.
addr
)
return
return
}
}
if
delay
!=
0
{
if
delay
!=
0
{
time
.
Sleep
(
delay
)
time
.
Sleep
(
delay
)
}
}
client
,
err
=
thi
s
.
accept
(
newSession
)
client
,
err
=
s
.
accept
(
newSession
)
if
err
!=
nil
{
if
err
!=
nil
{
if
netErr
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
netErr
.
Temporary
()
{
if
netErr
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
netErr
.
Temporary
()
{
if
delay
==
0
{
if
delay
==
0
{
...
@@ -119,7 +119,7 @@ func (this *Server) RunEventloop(newSession NewSessionCallback) {
...
@@ -119,7 +119,7 @@ func (this *Server) RunEventloop(newSession NewSessionCallback) {
}
}
continue
continue
}
}
log
.
Warn
(
"Server{%s}.Accept() = err {%#v}"
,
thi
s
.
addr
,
err
)
log
.
Warn
(
"Server{%s}.Accept() = err {%#v}"
,
s
.
addr
,
err
)
continue
continue
}
}
delay
=
0
delay
=
0
...
@@ -149,20 +149,20 @@ func newWSHandler(server *Server, newSession NewSessionCallback) *wsHandler {
...
@@ -149,20 +149,20 @@ func newWSHandler(server *Server, newSession NewSessionCallback) *wsHandler {
}
}
}
}
func
(
thi
s
*
wsHandler
)
serveWSRequest
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
s
*
wsHandler
)
serveWSRequest
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
r
.
Method
!=
"GET"
{
if
r
.
Method
!=
"GET"
{
// w.WriteHeader(http.StatusMethodNotAllowed)
// w.WriteHeader(http.StatusMethodNotAllowed)
http
.
Error
(
w
,
"Method not allowed"
,
405
)
http
.
Error
(
w
,
"Method not allowed"
,
405
)
return
return
}
}
if
thi
s
.
server
.
IsClosed
()
{
if
s
.
server
.
IsClosed
()
{
http
.
Error
(
w
,
"HTTP server is closed(code:500-11)."
,
500
)
http
.
Error
(
w
,
"HTTP server is closed(code:500-11)."
,
500
)
log
.
Warn
(
"Server{%s} stop acceptting client connect request."
,
thi
s
.
server
.
addr
)
log
.
Warn
(
"Server{%s} stop acceptting client connect request."
,
s
.
server
.
addr
)
return
return
}
}
conn
,
err
:=
thi
s
.
upgrader
.
Upgrade
(
w
,
r
,
nil
)
conn
,
err
:=
s
.
upgrader
.
Upgrade
(
w
,
r
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Warn
(
"upgrader.Upgrader(http.Request{%#v}) = error{%#v}"
,
r
,
err
)
log
.
Warn
(
"upgrader.Upgrader(http.Request{%#v}) = error{%#v}"
,
r
,
err
)
return
return
...
@@ -173,10 +173,10 @@ func (this *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
...
@@ -173,10 +173,10 @@ func (this *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
}
}
// conn.SetReadLimit(int64(handler.maxMsgLen))
// conn.SetReadLimit(int64(handler.maxMsgLen))
session
:=
NewWSSession
(
conn
)
session
:=
NewWSSession
(
conn
)
err
=
thi
s
.
newSession
(
session
)
err
=
s
.
newSession
(
session
)
if
err
!=
nil
{
if
err
!=
nil
{
conn
.
Close
()
conn
.
Close
()
log
.
Warn
(
"Server{%s}.newSession(session{%#v}) = err {%#v}"
,
thi
s
.
server
.
addr
,
session
,
err
)
log
.
Warn
(
"Server{%s}.newSession(session{%#v}) = err {%#v}"
,
s
.
server
.
addr
,
session
,
err
)
return
return
}
}
if
session
.
(
*
session
)
.
maxMsgLen
>
0
{
if
session
.
(
*
session
)
.
maxMsgLen
>
0
{
...
@@ -189,24 +189,24 @@ func (this *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
...
@@ -189,24 +189,24 @@ func (this *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
// RunWSEventLoop serve websocket client request
// RunWSEventLoop serve websocket client request
// @newSession: new websocket connection callback
// @newSession: new websocket connection callback
// @path: websocket request url path
// @path: websocket request url path
func
(
thi
s
*
Server
)
RunWSEventLoop
(
newSession
NewSessionCallback
,
path
string
)
{
func
(
s
*
Server
)
RunWSEventLoop
(
newSession
NewSessionCallback
,
path
string
)
{
thi
s
.
wg
.
Add
(
1
)
s
.
wg
.
Add
(
1
)
go
func
()
{
go
func
()
{
defer
thi
s
.
wg
.
Done
()
defer
s
.
wg
.
Done
()
var
(
var
(
err
error
err
error
handler
*
wsHandler
handler
*
wsHandler
)
)
handler
=
newWSHandler
(
thi
s
,
newSession
)
handler
=
newWSHandler
(
s
,
newSession
)
handler
.
HandleFunc
(
path
,
handler
.
serveWSRequest
)
handler
.
HandleFunc
(
path
,
handler
.
serveWSRequest
)
err
=
(
&
http
.
Server
{
err
=
(
&
http
.
Server
{
Addr
:
thi
s
.
addr
,
Addr
:
s
.
addr
,
Handler
:
handler
,
Handler
:
handler
,
// ReadTimeout: server.HTTPTimeout,
// ReadTimeout: server.HTTPTimeout,
// WriteTimeout: server.HTTPTimeout,
// WriteTimeout: server.HTTPTimeout,
})
.
Serve
(
thi
s
.
listener
)
})
.
Serve
(
s
.
listener
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Error
(
"http.Server.Serve(addr{%s}) = err{%#v}"
,
thi
s
.
addr
,
err
)
log
.
Error
(
"http.Server.Serve(addr{%s}) = err{%#v}"
,
s
.
addr
,
err
)
// panic(err)
// panic(err)
}
}
}()
}()
...
@@ -215,10 +215,10 @@ func (this *Server) RunWSEventLoop(newSession NewSessionCallback, path string) {
...
@@ -215,10 +215,10 @@ func (this *Server) RunWSEventLoop(newSession NewSessionCallback, path string) {
// RunWSEventLoopWithTLS serve websocket client request
// RunWSEventLoopWithTLS serve websocket client request
// @newSession: new websocket connection callback
// @newSession: new websocket connection callback
// @path: websocket request url path
// @path: websocket request url path
func
(
thi
s
*
Server
)
RunWSEventLoopWithTLS
(
newSession
NewSessionCallback
,
path
string
,
cert
string
,
priv
string
)
{
func
(
s
*
Server
)
RunWSEventLoopWithTLS
(
newSession
NewSessionCallback
,
path
string
,
cert
string
,
priv
string
)
{
thi
s
.
wg
.
Add
(
1
)
s
.
wg
.
Add
(
1
)
go
func
()
{
go
func
()
{
defer
thi
s
.
wg
.
Done
()
defer
s
.
wg
.
Done
()
var
(
var
(
err
error
err
error
config
*
tls
.
Config
config
*
tls
.
Config
...
@@ -233,29 +233,29 @@ func (this *Server) RunWSEventLoopWithTLS(newSession NewSessionCallback, path st
...
@@ -233,29 +233,29 @@ func (this *Server) RunWSEventLoopWithTLS(newSession NewSessionCallback, path st
return
return
}
}
handler
=
newWSHandler
(
thi
s
,
newSession
)
handler
=
newWSHandler
(
s
,
newSession
)
handler
.
HandleFunc
(
path
,
handler
.
serveWSRequest
)
handler
.
HandleFunc
(
path
,
handler
.
serveWSRequest
)
server
=
&
http
.
Server
{
server
=
&
http
.
Server
{
Addr
:
thi
s
.
addr
,
Addr
:
s
.
addr
,
Handler
:
handler
,
Handler
:
handler
,
// ReadTimeout: server.HTTPTimeout,
// ReadTimeout: server.HTTPTimeout,
// WriteTimeout: server.HTTPTimeout,
// WriteTimeout: server.HTTPTimeout,
}
}
server
.
SetKeepAlivesEnabled
(
true
)
server
.
SetKeepAlivesEnabled
(
true
)
err
=
server
.
Serve
(
tls
.
NewListener
(
thi
s
.
listener
,
config
))
err
=
server
.
Serve
(
tls
.
NewListener
(
s
.
listener
,
config
))
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Error
(
"http.Server.Serve(addr{%s}) = err{%#v}"
,
thi
s
.
addr
,
err
)
log
.
Error
(
"http.Server.Serve(addr{%s}) = err{%#v}"
,
s
.
addr
,
err
)
panic
(
err
)
panic
(
err
)
}
}
}()
}()
}
}
func
(
thi
s
*
Server
)
Listener
()
net
.
Listener
{
func
(
s
*
Server
)
Listener
()
net
.
Listener
{
return
thi
s
.
listener
return
s
.
listener
}
}
func
(
thi
s
*
Server
)
accept
(
newSession
NewSessionCallback
)
(
Session
,
error
)
{
func
(
s
*
Server
)
accept
(
newSession
NewSessionCallback
)
(
Session
,
error
)
{
conn
,
err
:=
thi
s
.
listener
.
Accept
()
conn
,
err
:=
s
.
listener
.
Accept
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -274,7 +274,7 @@ func (this *Server) accept(newSession NewSessionCallback) (Session, error) {
...
@@ -274,7 +274,7 @@ func (this *Server) accept(newSession NewSessionCallback) (Session, error) {
return
session
,
nil
return
session
,
nil
}
}
func
(
thi
s
*
Server
)
Close
()
{
func
(
s
*
Server
)
Close
()
{
thi
s
.
stop
()
s
.
stop
()
thi
s
.
wg
.
Wait
()
s
.
wg
.
Wait
()
}
}
session.go
View file @
4cf247e1
This diff is collapsed.
Click to expand it.
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