Commit 8abb0aa7 authored by AlexStocks's avatar AlexStocks

add Session interface

parent f7505d10
......@@ -11,6 +11,11 @@
## develop history ##
---
- 2017/02/03
> 1 Session struct -> session struct and add Session interface
>
> 2 version: 0.7.0
- 2016/11/19
> 1 add conn.go:(*gettyWSConn) setCompressType to add zip compress feature for ws connection
>
......
......@@ -21,6 +21,7 @@ import (
)
import (
"github.com/AlexStocks/goext/sync"
log "github.com/AlexStocks/log4go"
"github.com/gorilla/websocket"
)
......@@ -42,10 +43,10 @@ type Client struct {
interval time.Duration
addr string
newSession NewSessionCallback
sessionMap map[*Session]empty
sessionMap map[Session]gxsync.Empty
sync.Once
done chan empty
done chan gxsync.Empty
wg sync.WaitGroup
// for wss client
......@@ -68,8 +69,8 @@ func NewClient(connNum int, connInterval time.Duration, serverAddr string) *Clie
number: connNum,
interval: connInterval,
addr: serverAddr,
sessionMap: make(map[*Session]empty, connNum),
done: make(chan empty),
sessionMap: make(map[Session]gxsync.Empty, connNum),
done: make(chan gxsync.Empty),
}
}
......@@ -90,13 +91,13 @@ func NewWSSClient(connNum int, connInterval time.Duration, serverAddr string, ce
number: connNum,
interval: connInterval,
addr: serverAddr,
sessionMap: make(map[*Session]empty, connNum),
done: make(chan empty),
sessionMap: make(map[Session]gxsync.Empty, connNum),
done: make(chan gxsync.Empty),
certFile: cert,
}
}
func (this *Client) dialTCP() *Session {
func (this *Client) dialTCP() Session {
var (
err error
conn net.Conn
......@@ -120,12 +121,12 @@ func (this *Client) dialTCP() *Session {
}
}
func (this *Client) dialWS() *Session {
func (this *Client) dialWS() Session {
var (
err error
dialer websocket.Dialer
conn *websocket.Conn
session *Session
session Session
)
dialer.EnableCompression = true
......@@ -139,8 +140,8 @@ func (this *Client) dialWS() *Session {
}
if err == nil {
session = NewWSSession(conn)
if session.maxMsgLen > 0 {
conn.SetReadLimit(int64(session.maxMsgLen))
if session.(*session).maxMsgLen > 0 {
conn.SetReadLimit(int64(session.(*session).maxMsgLen))
}
return session
......@@ -152,14 +153,14 @@ func (this *Client) dialWS() *Session {
}
}
func (this *Client) dialWSS() *Session {
func (this *Client) dialWSS() Session {
var (
err error
certPem []byte
certPool *x509.CertPool
dialer websocket.Dialer
conn *websocket.Conn
session *Session
session Session
)
dialer.EnableCompression = true
......@@ -184,8 +185,8 @@ func (this *Client) dialWSS() *Session {
}
if err == nil {
session = NewWSSession(conn)
if session.maxMsgLen > 0 {
conn.SetReadLimit(int64(session.maxMsgLen))
if session.(*session).maxMsgLen > 0 {
conn.SetReadLimit(int64(session.(*session).maxMsgLen))
}
return session
......@@ -197,7 +198,7 @@ func (this *Client) dialWSS() *Session {
}
}
func (this *Client) dial() *Session {
func (this *Client) dial() Session {
if strings.HasPrefix(this.addr, "ws") {
return this.dialWS()
} else if strings.HasPrefix(this.addr, "wss") {
......@@ -225,7 +226,7 @@ func (this *Client) sessionNum() int {
func (this *Client) connect() {
var (
err error
session *Session
session Session
)
for {
......@@ -237,9 +238,9 @@ func (this *Client) connect() {
err = this.newSession(session)
if err == nil {
// session.RunEventLoop()
session.run()
session.(*session).run()
this.Lock()
this.sessionMap[session] = empty{}
this.sessionMap[session] = gxsync.Empty{}
this.Unlock()
break
}
......
......@@ -12,19 +12,19 @@ package getty
// NewSessionCallback will be invoked when server accepts a new client connection or client connects to server successfully.
// if there are too many client connections or u do not want to connect a server again, u can return non-nil error. And
// then getty will close the new session.
type NewSessionCallback func(*Session) error
type NewSessionCallback func(Session) error
// Reader is used to unmarshal a complete pkg from buffer
type Reader interface {
// Parse tcp pkg from buffer and if possible return a complete pkg
// If length of buf is not long enough, u should return {nil,0, nil}
// The second return value is the length of the pkg.
Read(*Session, []byte) (interface{}, int, error)
Read(Session, []byte) (interface{}, int, error)
}
// Writer is used to marshal pkg and write to session
type Writer interface {
Write(*Session, interface{}) error
Write(Session, interface{}) error
}
// tcp package handler interface
......@@ -37,19 +37,19 @@ type ReadWriter interface {
type EventListener interface {
// invoked when session opened
// If the return error is not nil, @Session will be closed.
OnOpen(*Session) error
OnOpen(Session) error
// invoked when session closed.
OnClose(*Session)
OnClose(Session)
// invoked when got error.
OnError(*Session, error)
OnError(Session, error)
// invoked periodically, its period can be set by (Session)SetCronPeriod
OnCron(*Session)
OnCron(Session)
// invoked when receive packge. Pls attention that do not handle long time logic processing in this func.
// Y'd better set the package's maximum length. If the message's length is greater than it, u should
// should return err in Reader{Read} and getty will close this connection soon.
OnMessage(*Session, interface{})
OnMessage(Session, interface{})
}
......@@ -48,20 +48,24 @@ const (
// connection interfacke
/////////////////////////////////////////
type iConn interface {
id() uint32
setCompressType(t CompressType)
localAddr() string
remoteAddr() string
type Connection interface {
ID() uint32
SetCompressType(t CompressType)
LocalAddr() string
RemoteAddr() string
incReadPkgCount()
incWritePkgCount()
updateActive()
getActive() time.Time
// update session's active time
UpdateActive()
// get session's active time
GetActive() time.Time
readDeadline() time.Duration
setReadDeadline(time.Duration)
// SetReadDeadline sets deadline for the future read calls.
SetReadDeadline(time.Duration)
writeDeadline() time.Duration
setWriteDeadline(time.Duration)
write(p []byte) error
// SetWriteDeadlile sets deadline for the future read calls.
SetWriteDeadline(time.Duration)
Write(p []byte) error
// don't distinguish between tcp connection and websocket connection. Because
// gorilla/websocket/conn.go:(Conn)Close also invoke net.Conn.Close
close(int)
......@@ -76,7 +80,7 @@ var (
)
type gettyConn struct {
ID uint32
id uint32
compress CompressType
padding1 uint8
padding2 uint16
......@@ -91,15 +95,15 @@ type gettyConn struct {
peer string // peer address
}
func (this *gettyConn) id() uint32 {
return this.ID
func (this *gettyConn) ID() uint32 {
return this.id
}
func (this *gettyConn) localAddr() string {
func (this *gettyConn) LocalAddr() string {
return this.local
}
func (this *gettyConn) remoteAddr() string {
func (this *gettyConn) RemoteAddr() string {
return this.peer
}
......@@ -111,15 +115,15 @@ func (this *gettyConn) incWritePkgCount() {
atomic.AddUint32(&this.writePkgCount, 1)
}
func (this *gettyConn) updateActive() {
func (this *gettyConn) UpdateActive() {
atomic.StoreInt64(&(this.active), int64(time.Since(launchTime)))
}
func (this *gettyConn) getActive() time.Time {
func (this *gettyConn) GetActive() time.Time {
return launchTime.Add(time.Duration(atomic.LoadInt64(&(this.active))))
}
func (this *gettyConn) write([]byte) error {
func (this *gettyConn) Write([]byte) error {
return nil
}
......@@ -129,7 +133,7 @@ func (this gettyConn) readDeadline() time.Duration {
return this.rDeadline
}
func (this *gettyConn) setReadDeadline(rDeadline time.Duration) {
func (this *gettyConn) SetReadDeadline(rDeadline time.Duration) {
if rDeadline < 1 {
panic("@rDeadline < 1")
}
......@@ -144,7 +148,7 @@ func (this gettyConn) writeDeadline() time.Duration {
return this.wDeadline
}
func (this *gettyConn) setWriteDeadline(wDeadline time.Duration) {
func (this *gettyConn) SetWriteDeadline(wDeadline time.Duration) {
if wDeadline < 1 {
panic("@wDeadline < 1")
}
......@@ -182,7 +186,7 @@ func newGettyTCPConn(conn net.Conn) *gettyTCPConn {
reader: io.Reader(conn),
writer: io.Writer(conn),
gettyConn: gettyConn{
ID: atomic.AddUint32(&connID, 1),
id: atomic.AddUint32(&connID, 1),
local: localAddr,
peer: peerAddr,
compress: CompressNone,
......@@ -213,7 +217,7 @@ func (this *writeFlusher) Write(p []byte) (int, error) {
}
// set compress type(tcp: zip/snappy, websocket:zip)
func (this *gettyTCPConn) setCompressType(t CompressType) {
func (this *gettyTCPConn) SetCompressType(t CompressType) {
switch {
case t == CompressZip:
this.reader = flate.NewReader(this.conn)
......@@ -244,7 +248,7 @@ func (this *gettyTCPConn) read(p []byte) (int, error) {
}
// tcp connection write
func (this *gettyTCPConn) write(p []byte) error {
func (this *gettyTCPConn) Write(p []byte) error {
// if this.conn == nil {
// return 0, ErrInvalidConnection
// }
......@@ -296,7 +300,7 @@ func newGettyWSConn(conn *websocket.Conn) *gettyWSConn {
gettyWSConn := &gettyWSConn{
conn: conn,
gettyConn: gettyConn{
ID: atomic.AddUint32(&connID, 1),
id: atomic.AddUint32(&connID, 1),
local: localAddr,
peer: peerAddr,
},
......@@ -309,7 +313,7 @@ func newGettyWSConn(conn *websocket.Conn) *gettyWSConn {
}
// set compress type(tcp: zip/snappy, websocket:zip)
func (this *gettyWSConn) setCompressType(t CompressType) {
func (this *gettyWSConn) SetCompressType(t CompressType) {
switch {
case t == CompressZip:
this.conn.EnableWriteCompression(true)
......@@ -328,14 +332,14 @@ func (this *gettyWSConn) handlePing(message string) error {
err = nil
}
if err == nil {
this.updateActive()
this.UpdateActive()
}
return err
}
func (this *gettyWSConn) handlePong(string) error {
this.updateActive()
this.UpdateActive()
return nil
}
......@@ -356,7 +360,7 @@ func (this *gettyWSConn) read() ([]byte, error) {
}
// websocket connection write
func (this *gettyWSConn) write(p []byte) error {
func (this *gettyWSConn) Write(p []byte) error {
// atomic.AddUint32(&this.writeCount, 1)
atomic.AddUint32(&this.writeCount, (uint32)(len(p)))
// this.conn.SetWriteDeadline(time.Now().Add(this.wDeadline))
......
......@@ -20,6 +20,7 @@ import (
import (
"github.com/AlexStocks/goext/net"
"github.com/AlexStocks/goext/sync"
log "github.com/AlexStocks/log4go"
"github.com/gorilla/websocket"
)
......@@ -34,12 +35,12 @@ type Server struct {
listener net.Listener
sync.Once
done chan empty
done chan gxsync.Empty
wg sync.WaitGroup
}
func NewServer() *Server {
return &Server{done: make(chan empty)}
return &Server{done: make(chan gxsync.Empty)}
}
func (this *Server) stop() {
......@@ -94,7 +95,7 @@ func (this *Server) RunEventloop(newSession NewSessionCallback) {
defer this.wg.Done()
var (
err error
client *Session
client Session
delay time.Duration
)
for {
......@@ -123,7 +124,7 @@ func (this *Server) RunEventloop(newSession NewSessionCallback) {
}
delay = 0
// client.RunEventLoop()
client.run()
client.(*session).run()
}
}()
}
......@@ -178,11 +179,11 @@ func (this *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
log.Warn("Server{%s}.newSession(session{%#v}) = err {%#v}", this.server.addr, session, err)
return
}
if session.maxMsgLen > 0 {
conn.SetReadLimit(int64(session.maxMsgLen))
if session.(*session).maxMsgLen > 0 {
conn.SetReadLimit(int64(session.(*session).maxMsgLen))
}
// session.RunEventLoop()
session.run()
session.(*session).run()
}
// RunWSEventLoop serve websocket client request
......@@ -253,7 +254,7 @@ func (this *Server) Listener() net.Listener {
return this.listener
}
func (this *Server) accept(newSession NewSessionCallback) (*Session, error) {
func (this *Server) accept(newSession NewSessionCallback) (Session, error) {
conn, err := this.listener.Accept()
if err != nil {
return nil, err
......
This diff is collapsed.
......@@ -10,9 +10,9 @@
package getty
const (
Version = "0.6.2"
DATE = "2016/11/19"
Version = "0.7.0"
DATE = "2017/02/03"
GETTY_MAJOR = 0
GETTY_MINOR = 6
GETTY_BUILD = 2
GETTY_MINOR = 7
GETTY_BUILD = 0
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment