ing
This commit is contained in:
parent
3b3f53cfa2
commit
ec72c171fb
20
server_context.go
Normal file
20
server_context.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
cuc "git.loafle.net/commons_go/util/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServerContext interface {
|
||||||
|
cuc.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type serverContext struct {
|
||||||
|
cuc.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServerContext() ServerContext {
|
||||||
|
sCTX := &serverContext{}
|
||||||
|
sCTX.Context = cuc.NewContext(nil)
|
||||||
|
|
||||||
|
return sCTX
|
||||||
|
}
|
|
@ -5,13 +5,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerHandler interface {
|
type ServerHandler interface {
|
||||||
Listen() (net.Listener, error)
|
ServerContext() ServerContext
|
||||||
OnAccept(conn net.Conn) (net.Conn, error)
|
Init(serverCTX ServerContext) error
|
||||||
|
Listen(serverCTX ServerContext) (net.Listener, error)
|
||||||
|
OnStart(serverCTX ServerContext)
|
||||||
|
|
||||||
OnStart()
|
OnError(serverCTX ServerContext, conn net.Conn, status int, reason error)
|
||||||
OnStop()
|
|
||||||
|
|
||||||
Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{})
|
OnStop(serverCTX ServerContext)
|
||||||
|
|
||||||
IsClientDisconnect(err error) bool
|
IsClientDisconnect(err error) bool
|
||||||
|
|
||||||
|
|
|
@ -10,18 +10,38 @@ import (
|
||||||
type ServerHandlers struct {
|
type ServerHandlers struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *ServerHandlers) OnStart() {
|
func (sh *ServerHandlers) ServerContext() ServerContext {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) Init(serverCTX ServerContext) error {
|
||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *ServerHandlers) OnStop() {
|
func (sh *ServerHandlers) Listen(serverCTX ServerContext) (net.Listener, error) {
|
||||||
// no op
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sh *ServerHandlers) Listen() (net.Listener, error) {
|
|
||||||
return nil, errors.New("Server: Handler method[Listen] of Server is not implement")
|
return nil, errors.New("Server: Handler method[Listen] of Server is not implement")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) OnStart(serverCTX ServerContext) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) Handle(serverCTX ServerContext, conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) OnError(serverCTX ServerContext, conn net.Conn, status int, reason error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *ServerHandlers) OnStop(serverCTX ServerContext) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) {
|
func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
75
socket.go
Normal file
75
socket.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
type Socket interface {
|
||||||
|
// ID returns the identity of the client.
|
||||||
|
ID() string
|
||||||
|
Context() SocketContext
|
||||||
|
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSocket(socketHandler SocketHandler, socketCTX SocketContext, conn net.Conn, id string) Socket {
|
||||||
|
s := retainSocket()
|
||||||
|
s.Conn = conn
|
||||||
|
s.sh = socketHandler
|
||||||
|
s.id = id
|
||||||
|
s.SetReadLimit(socketHandler.GetMaxMessageSize())
|
||||||
|
if 0 < socketHandler.GetReadTimeout() {
|
||||||
|
s.SetReadDeadline(time.Now().Add(socketHandler.GetReadTimeout() * time.Second))
|
||||||
|
}
|
||||||
|
s.ctx = socketCTX
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type netSocket struct {
|
||||||
|
net.Conn
|
||||||
|
|
||||||
|
ctx SocketContext
|
||||||
|
sh SocketHandler
|
||||||
|
|
||||||
|
id string
|
||||||
|
|
||||||
|
// sc *SocketConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *netSocket) Context() SocketContext {
|
||||||
|
return s.ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *netSocket) ID() string {
|
||||||
|
return s.id
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *netSocket) Close() error {
|
||||||
|
err := s.Conn.Close()
|
||||||
|
releaseSocket(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var socketPool sync.Pool
|
||||||
|
|
||||||
|
func retainSocket() *netSocket {
|
||||||
|
v := socketPool.Get()
|
||||||
|
if v == nil {
|
||||||
|
return &netSocket{}
|
||||||
|
}
|
||||||
|
return v.(*netSocket)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseSocket(s *netSocket) {
|
||||||
|
s.sh = nil
|
||||||
|
s.ctx = nil
|
||||||
|
s.id = ""
|
||||||
|
|
||||||
|
socketPool.Put(s)
|
||||||
|
}
|
28
socket_context.go
Normal file
28
socket_context.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
cuc "git.loafle.net/commons_go/util/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocketContext interface {
|
||||||
|
cuc.Context
|
||||||
|
ServerContext() ServerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSocketContext(serverCTX ServerContext) SocketContext {
|
||||||
|
sCTX := &socketContext{}
|
||||||
|
sCTX.Context = cuc.NewContext(serverCTX)
|
||||||
|
sCTX.serverCTX = serverCTX
|
||||||
|
|
||||||
|
return sCTX
|
||||||
|
}
|
||||||
|
|
||||||
|
type socketContext struct {
|
||||||
|
cuc.Context
|
||||||
|
|
||||||
|
serverCTX ServerContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *socketContext) ServerContext() ServerContext {
|
||||||
|
return sc.serverCTX
|
||||||
|
}
|
70
socket_handler.go
Normal file
70
socket_handler.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocketHandler interface {
|
||||||
|
SocketContext(serverCTX ServerContext) SocketContext
|
||||||
|
// Init invoked when server is stated
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandler) Init() error {
|
||||||
|
// if err := sh.SocketHandlers.Init(); nil != err {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// ...
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
Init(serverCTX ServerContext) error
|
||||||
|
// Handshake do handshake client and server
|
||||||
|
// id is identity of client socket. if id is "", disallow connection
|
||||||
|
Handshake(serverCTX ServerContext, conn net.Conn) (id string)
|
||||||
|
// OnConnect invoked when client is connected
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandler) OnConnect(soc cwf.Socket) cwf.Socket {
|
||||||
|
// soc = sh.SocketHandlers.OnConnect(newSoc)
|
||||||
|
// newSoc := ...
|
||||||
|
// return newSoc
|
||||||
|
// }
|
||||||
|
OnConnect(soc Socket)
|
||||||
|
Handle(soc Socket, stopChan <-chan struct{}, doneChan chan<- error)
|
||||||
|
// OnDisconnect invoked when client is disconnected
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandler) OnDisconnect(soc cwf.Socket) {
|
||||||
|
// ...
|
||||||
|
// sh.SocketHandlers.OnDisconnect(soc)
|
||||||
|
// }
|
||||||
|
OnDisconnect(soc Socket)
|
||||||
|
// Destroy invoked when server is stopped
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandler) Destroy() {
|
||||||
|
// ...
|
||||||
|
// sh.SocketHandlers.Destroy()
|
||||||
|
// }
|
||||||
|
Destroy()
|
||||||
|
|
||||||
|
GetSocket(id string) Socket
|
||||||
|
GetSockets() map[string]Socket
|
||||||
|
|
||||||
|
GetMaxMessageSize() int64
|
||||||
|
GetWriteTimeout() time.Duration
|
||||||
|
GetReadTimeout() time.Duration
|
||||||
|
|
||||||
|
// Validate is check handler value
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandlers) Validate() {
|
||||||
|
// sh.SocketHandlers.Validate()
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
Validate()
|
||||||
|
|
||||||
|
addSocket(soc Socket)
|
||||||
|
removeSocket(soc Socket)
|
||||||
|
}
|
92
socket_handlers.go
Normal file
92
socket_handlers.go
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocketHandlers struct {
|
||||||
|
// MaxMessageSize is the maximum size for a message read from the peer. If a
|
||||||
|
// message exceeds the limit, the connection sends a close frame to the peer
|
||||||
|
// and returns ErrReadLimit to the application.
|
||||||
|
MaxMessageSize int64
|
||||||
|
// WriteTimeout is the write deadline on the underlying network
|
||||||
|
// connection. After a write has timed out, the websocket state is corrupt and
|
||||||
|
// all future writes will return an error. A zero value for t means writes will
|
||||||
|
// not time out.
|
||||||
|
WriteTimeout time.Duration
|
||||||
|
// ReadTimeout is the read deadline on the underlying network connection.
|
||||||
|
// After a read has timed out, the websocket connection state is corrupt and
|
||||||
|
// all future reads will return an error. A zero value for t means reads will
|
||||||
|
// not time out.
|
||||||
|
ReadTimeout time.Duration
|
||||||
|
|
||||||
|
sockets map[string]Socket
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) Init(serverCTX ServerContext) error {
|
||||||
|
sh.sockets = make(map[string]Socket)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) Handshake(serverCTX ServerContext, conn net.Conn) (id string) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) SocketContext(serverCTX ServerContext) SocketContext {
|
||||||
|
return newSocketContext(serverCTX)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) OnConnect(soc Socket) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) Handle(soc Socket, stopChan <-chan struct{}, doneChan chan<- error) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) OnDisconnect(soc Socket) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) Destroy() {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) GetSocket(id string) Socket {
|
||||||
|
return sh.sockets[id]
|
||||||
|
}
|
||||||
|
func (sh *SocketHandlers) GetSockets() map[string]Socket {
|
||||||
|
return sh.sockets
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) GetMaxMessageSize() int64 {
|
||||||
|
return sh.MaxMessageSize
|
||||||
|
}
|
||||||
|
func (sh *SocketHandlers) GetWriteTimeout() time.Duration {
|
||||||
|
return sh.WriteTimeout
|
||||||
|
}
|
||||||
|
func (sh *SocketHandlers) GetReadTimeout() time.Duration {
|
||||||
|
return sh.ReadTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) Validate() {
|
||||||
|
if sh.MaxMessageSize <= 0 {
|
||||||
|
sh.MaxMessageSize = DefaultMaxMessageSize
|
||||||
|
}
|
||||||
|
if sh.WriteTimeout <= 0 {
|
||||||
|
sh.WriteTimeout = DefaultWriteTimeout
|
||||||
|
}
|
||||||
|
if sh.ReadTimeout <= 0 {
|
||||||
|
sh.ReadTimeout = DefaultReadTimeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) addSocket(soc Socket) {
|
||||||
|
sh.sockets[soc.ID()] = soc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *SocketHandlers) removeSocket(soc Socket) {
|
||||||
|
delete(sh.sockets, soc.ID())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user