server/client/socket.go

116 lines
2.0 KiB
Go
Raw Normal View History

2017-11-30 09:13:58 +00:00
package client
import (
2017-12-01 03:42:03 +00:00
"crypto/tls"
2017-11-30 09:13:58 +00:00
"net"
"sync"
"git.loafle.net/commons_go/logging"
2017-11-30 09:36:59 +00:00
cuc "git.loafle.net/commons_go/util/context"
2017-11-30 09:13:58 +00:00
)
type Socket interface {
Context() SocketContext
net.Conn
}
func NewSocket(sb SocketBuilder, parentContext cuc.Context) (Socket, error) {
if nil == sb {
2018-03-21 11:07:11 +00:00
logging.Logger().Panicf("Client Socket: SocketBuilder must be specified")
2017-11-30 09:13:58 +00:00
}
sb.Validate()
sc := sb.SocketContext(parentContext)
if nil == sc {
2018-03-21 11:07:11 +00:00
logging.Logger().Panicf("Client Socket: SocketContext must be specified")
2017-11-30 09:13:58 +00:00
}
2017-12-05 07:21:32 +00:00
sh := sb.GetSocketHandler()
2017-11-30 09:13:58 +00:00
if nil == sh {
2018-03-21 11:07:11 +00:00
logging.Logger().Panicf("Client Socket: SocketHandler must be specified")
2017-11-30 09:13:58 +00:00
}
sh.Validate()
network := sb.GetNetwork()
address := sb.GetAddress()
2017-12-01 03:42:03 +00:00
conn, err := sb.Dial(network, address)
2017-11-30 09:13:58 +00:00
if nil != err {
return nil, err
}
2017-12-01 03:42:03 +00:00
tlsConfig := sb.GetTLSConfig()
if nil != tlsConfig {
cfg := tlsConfig.Clone()
tlsConn := tls.Client(conn, cfg)
if err := tlsConn.Handshake(); err != nil {
tlsConn.Close()
return nil, err
}
if !cfg.InsecureSkipVerify {
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
return nil, err
}
}
conn = tlsConn
}
2017-11-30 09:13:58 +00:00
sh.OnConnect(sc, conn)
s := retainSocket()
2017-11-30 10:25:12 +00:00
s.Conn = conn
2017-11-30 09:13:58 +00:00
s.ctx = sc
s.sh = sh
return s, nil
}
type netSocket struct {
net.Conn
ctx SocketContext
sh SocketHandler
}
func (s *netSocket) Context() SocketContext {
return s.ctx
}
2018-03-22 14:09:11 +00:00
func (s *netSocket) Read(b []byte) (n int, err error) {
n, err = s.Conn.Read(b)
logging.Logger().Debugf("Client Socket: read message[%s]", string(b))
return
}
func (s *netSocket) Write(b []byte) (n int, err error) {
logging.Logger().Debugf("Client Socket: write message[%s]", string(b))
return s.Conn.Write(b)
}
2017-11-30 09:13:58 +00:00
func (s *netSocket) Close() error {
err := s.Conn.Close()
s.sh.OnDisconnect(s)
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
socketPool.Put(s)
}