ing
This commit is contained in:
parent
57a60490c6
commit
6440d89d72
221
client/socket.go
Normal file
221
client/socket.go
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.loafle.net/commons_go/websocket_fasthttp/websocket"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Socket interface {
|
||||||
|
// Subprotocol returns the negotiated protocol for the connection.
|
||||||
|
Subprotocol() string
|
||||||
|
|
||||||
|
// Close closes the underlying network connection without sending or waiting for a close frame.
|
||||||
|
Close() error
|
||||||
|
|
||||||
|
// LocalAddr returns the local network address.
|
||||||
|
LocalAddr() net.Addr
|
||||||
|
|
||||||
|
// RemoteAddr returns the remote network address.
|
||||||
|
RemoteAddr() net.Addr
|
||||||
|
|
||||||
|
// WriteControl writes a control message with the given deadline. The allowed
|
||||||
|
// message types are CloseMessage, PingMessage and PongMessage.
|
||||||
|
WriteControl(messageType int, data []byte, deadline time.Time) error
|
||||||
|
|
||||||
|
// NextWriter returns a writer for the next message to send. The writer's Close
|
||||||
|
// method flushes the complete message to the network.
|
||||||
|
//
|
||||||
|
// There can be at most one open writer on a connection. NextWriter closes the
|
||||||
|
// previous writer if the application has not already done so.
|
||||||
|
NextWriter(messageType int) (io.WriteCloser, error)
|
||||||
|
|
||||||
|
// WritePreparedMessage writes prepared message into connection.
|
||||||
|
WritePreparedMessage(pm *websocket.PreparedMessage) error
|
||||||
|
|
||||||
|
// WriteMessage is a helper method for getting a writer using NextWriter,
|
||||||
|
// writing the message and closing the writer.
|
||||||
|
WriteMessage(messageType int, data []byte) error
|
||||||
|
|
||||||
|
// SetWriteDeadline sets 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.
|
||||||
|
SetWriteDeadline(t time.Time) error
|
||||||
|
|
||||||
|
// NextReader returns the next data message received from the peer. The
|
||||||
|
// returned messageType is either TextMessage or BinaryMessage.
|
||||||
|
//
|
||||||
|
// There can be at most one open reader on a connection. NextReader discards
|
||||||
|
// the previous message if the application has not already consumed it.
|
||||||
|
//
|
||||||
|
// Applications must break out of the application's read loop when this method
|
||||||
|
// returns a non-nil error value. Errors returned from this method are
|
||||||
|
// permanent. Once this method returns a non-nil error, all subsequent calls to
|
||||||
|
// this method return the same error.
|
||||||
|
NextReader() (messageType int, r io.Reader, err error)
|
||||||
|
|
||||||
|
// ReadMessage is a helper method for getting a reader using NextReader and
|
||||||
|
// reading from that reader to a buffer.
|
||||||
|
ReadMessage() (messageType int, p []byte, err error)
|
||||||
|
|
||||||
|
// SetReadDeadline sets 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.
|
||||||
|
SetReadDeadline(t time.Time) error
|
||||||
|
|
||||||
|
// SetReadLimit sets 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.
|
||||||
|
SetReadLimit(limit int64)
|
||||||
|
|
||||||
|
// CloseHandler returns the current close handler
|
||||||
|
CloseHandler() func(code int, text string) error
|
||||||
|
|
||||||
|
// SetCloseHandler sets the handler for close messages received from the peer.
|
||||||
|
// The code argument to h is the received close code or CloseNoStatusReceived
|
||||||
|
// if the close message is empty. The default close handler sends a close frame
|
||||||
|
// back to the peer.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process close messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
|
//
|
||||||
|
// The connection read methods return a CloseError when a close frame is
|
||||||
|
// received. Most applications should handle close messages as part of their
|
||||||
|
// normal error handling. Applications should only set a close handler when the
|
||||||
|
// application must perform some action before sending a close frame back to
|
||||||
|
// the peer.
|
||||||
|
SetCloseHandler(h func(code int, text string) error)
|
||||||
|
|
||||||
|
// PingHandler returns the current ping handler
|
||||||
|
PingHandler() func(appData string) error
|
||||||
|
|
||||||
|
// SetPingHandler sets the handler for ping messages received from the peer.
|
||||||
|
// The appData argument to h is the PING frame application data. The default
|
||||||
|
// ping handler sends a pong to the peer.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process ping messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
|
SetPingHandler(h func(appData string) error)
|
||||||
|
|
||||||
|
// PongHandler returns the current pong handler
|
||||||
|
PongHandler() func(appData string) error
|
||||||
|
|
||||||
|
// SetPongHandler sets the handler for pong messages received from the peer.
|
||||||
|
// The appData argument to h is the PONG frame application data. The default
|
||||||
|
// pong handler does nothing.
|
||||||
|
//
|
||||||
|
// The application must read the connection to process ping messages as
|
||||||
|
// described in the section on Control Frames above.
|
||||||
|
SetPongHandler(h func(appData string) error)
|
||||||
|
|
||||||
|
// UnderlyingConn returns the internal net.Conn. This can be used to further
|
||||||
|
// modifications to connection specific flags.
|
||||||
|
UnderlyingConn() net.Conn
|
||||||
|
|
||||||
|
// EnableWriteCompression enables and disables write compression of
|
||||||
|
// subsequent text and binary messages. This function is a noop if
|
||||||
|
// compression was not negotiated with the peer.
|
||||||
|
EnableWriteCompression(enable bool)
|
||||||
|
|
||||||
|
// SetCompressionLevel sets the flate compression level for subsequent text and
|
||||||
|
// binary messages. This function is a noop if compression was not negotiated
|
||||||
|
// with the peer. See the compress/flate package for a description of
|
||||||
|
// compression levels.
|
||||||
|
SetCompressionLevel(level int) error
|
||||||
|
|
||||||
|
// SetHeaders sets response headers
|
||||||
|
SetHeaders(h *fasthttp.ResponseHeader)
|
||||||
|
|
||||||
|
// Header returns header by key
|
||||||
|
Header(key string) (value string)
|
||||||
|
|
||||||
|
// Headers returns the RequestHeader struct
|
||||||
|
Headers() *fasthttp.ResponseHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSocket(socketHandler SocketHandler, socketCTX SocketContext, conn *websocket.Conn, id string) Socket {
|
||||||
|
s := retainSocket()
|
||||||
|
s.Conn = conn
|
||||||
|
s.sh = socketHandler
|
||||||
|
s.ctx = socketCTX
|
||||||
|
|
||||||
|
s.SetReadLimit(socketHandler.GetMaxMessageSize())
|
||||||
|
if 0 < socketHandler.GetReadTimeout() {
|
||||||
|
s.SetReadDeadline(time.Now().Add(socketHandler.GetReadTimeout() * time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type fasthttpWebSocket struct {
|
||||||
|
*websocket.Conn
|
||||||
|
|
||||||
|
ctx SocketContext
|
||||||
|
sh SocketHandler
|
||||||
|
|
||||||
|
resHeaders *fasthttp.ResponseHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) Context() SocketContext {
|
||||||
|
return s.ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) NextWriter(messageType int) (io.WriteCloser, error) {
|
||||||
|
if 0 < s.sh.GetWriteTimeout() {
|
||||||
|
s.SetWriteDeadline(time.Now().Add(s.sh.GetWriteTimeout() * time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Conn.NextWriter(messageType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) WriteMessage(messageType int, data []byte) error {
|
||||||
|
if 0 < s.sh.GetWriteTimeout() {
|
||||||
|
s.SetWriteDeadline(time.Now().Add(s.sh.GetWriteTimeout() * time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Conn.WriteMessage(messageType, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) SetHeaders(h *fasthttp.ResponseHeader) {
|
||||||
|
s.resHeaders = h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) Header(key string) (value string) {
|
||||||
|
if nil == s.resHeaders {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(s.resHeaders.Peek(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) Headers() *fasthttp.ResponseHeader {
|
||||||
|
return s.resHeaders
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fasthttpWebSocket) Close() error {
|
||||||
|
err := s.Conn.Close()
|
||||||
|
releaseSocket(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var socketPool sync.Pool
|
||||||
|
|
||||||
|
func retainSocket() *fasthttpWebSocket {
|
||||||
|
v := socketPool.Get()
|
||||||
|
if v == nil {
|
||||||
|
return &fasthttpWebSocket{}
|
||||||
|
}
|
||||||
|
return v.(*fasthttpWebSocket)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseSocket(s *fasthttpWebSocket) {
|
||||||
|
s.sh = nil
|
||||||
|
s.ctx = nil
|
||||||
|
|
||||||
|
socketPool.Put(s)
|
||||||
|
}
|
20
client/socket_context.go
Normal file
20
client/socket_context.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
cuc "git.loafle.net/commons_go/util/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocketContext interface {
|
||||||
|
cuc.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSocketContext() SocketContext {
|
||||||
|
sCTX := &socketContext{}
|
||||||
|
sCTX.Context = cuc.NewContext(nil)
|
||||||
|
|
||||||
|
return sCTX
|
||||||
|
}
|
||||||
|
|
||||||
|
type socketContext struct {
|
||||||
|
cuc.Context
|
||||||
|
}
|
21
client/socket_handler.go
Normal file
21
client/socket_handler.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type SocketHandler interface {
|
||||||
|
GetMaxMessageSize() int64
|
||||||
|
GetWriteTimeout() time.Duration
|
||||||
|
GetReadTimeout() time.Duration
|
||||||
|
GetPongTimeout() time.Duration
|
||||||
|
GetPingTimeout() time.Duration
|
||||||
|
GetPingPeriod() time.Duration
|
||||||
|
|
||||||
|
// Validate is check handler value
|
||||||
|
// If you override ths method, must call
|
||||||
|
//
|
||||||
|
// func (sh *SocketHandlers) Validate() {
|
||||||
|
// sh.SocketHandlers.Validate()
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
Validate()
|
||||||
|
}
|
66
client/socket_handlers.go
Normal file
66
client/socket_handlers.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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
|
||||||
|
|
||||||
|
PongTimeout time.Duration
|
||||||
|
PingTimeout time.Duration
|
||||||
|
PingPeriod time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
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) GetPongTimeout() time.Duration {
|
||||||
|
return sh.PongTimeout
|
||||||
|
}
|
||||||
|
func (sh *SocketHandlers) GetPingTimeout() time.Duration {
|
||||||
|
return sh.PingTimeout
|
||||||
|
}
|
||||||
|
func (sh *SocketHandlers) GetPingPeriod() time.Duration {
|
||||||
|
return sh.PingPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
if sh.PongTimeout <= 0 {
|
||||||
|
sh.PongTimeout = DefaultPongTimeout
|
||||||
|
}
|
||||||
|
if sh.PingTimeout <= 0 {
|
||||||
|
sh.PingTimeout = DefaultPingTimeout
|
||||||
|
}
|
||||||
|
if sh.PingPeriod <= 0 {
|
||||||
|
sh.PingPeriod = DefaultPingPeriod
|
||||||
|
}
|
||||||
|
}
|
99
socket.go
99
socket.go
|
@ -14,9 +14,6 @@ type Socket interface {
|
||||||
// ID returns the identity of the client.
|
// ID returns the identity of the client.
|
||||||
ID() string
|
ID() string
|
||||||
|
|
||||||
// // WaitRequest wait request of client.
|
|
||||||
// WaitRequest() (*SocketConn, error)
|
|
||||||
|
|
||||||
// Subprotocol returns the negotiated protocol for the connection.
|
// Subprotocol returns the negotiated protocol for the connection.
|
||||||
Subprotocol() string
|
Subprotocol() string
|
||||||
|
|
||||||
|
@ -180,28 +177,6 @@ func (s *fasthttpWebSocket) ID() string {
|
||||||
return s.id
|
return s.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (s *fasthttpWebSocket) WaitRequest() (*SocketConn, error) {
|
|
||||||
// if nil != s.sc {
|
|
||||||
// releaseSocketConn(s.sc)
|
|
||||||
// s.sc = nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var mt int
|
|
||||||
// var err error
|
|
||||||
// var r io.Reader
|
|
||||||
|
|
||||||
// if mt, r, err = s.NextReader(); nil != err {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// s.sc = retainSocketConn()
|
|
||||||
// s.sc.s = s
|
|
||||||
// s.sc.MessageType = mt
|
|
||||||
// s.sc.r = r
|
|
||||||
|
|
||||||
// return s.sc, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (s *fasthttpWebSocket) NextWriter(messageType int) (io.WriteCloser, error) {
|
func (s *fasthttpWebSocket) NextWriter(messageType int) (io.WriteCloser, error) {
|
||||||
if 0 < s.sh.GetWriteTimeout() {
|
if 0 < s.sh.GetWriteTimeout() {
|
||||||
s.SetWriteDeadline(time.Now().Add(s.sh.GetWriteTimeout() * time.Second))
|
s.SetWriteDeadline(time.Now().Add(s.sh.GetWriteTimeout() * time.Second))
|
||||||
|
@ -224,62 +199,6 @@ func (s *fasthttpWebSocket) Close() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// type SocketConn struct {
|
|
||||||
// net.Conn
|
|
||||||
|
|
||||||
// s *fasthttpWebSocket
|
|
||||||
|
|
||||||
// MessageType int
|
|
||||||
// r io.Reader
|
|
||||||
// wc io.WriteCloser
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sc *SocketConn) Read(b []byte) (n int, err error) {
|
|
||||||
// return sc.r.Read(b)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sc *SocketConn) Write(b []byte) (n int, err error) {
|
|
||||||
// if nil == sc.wc {
|
|
||||||
// var err error
|
|
||||||
// if sc.wc, err = sc.s.NextWriter(sc.MessageType); nil != err {
|
|
||||||
// return 0, err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return sc.wc.Write(b)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sc *SocketConn) Close() error {
|
|
||||||
// var err error
|
|
||||||
// if sc.wc != nil {
|
|
||||||
// err = sc.wc.Close()
|
|
||||||
// }
|
|
||||||
// sc.s.sc = nil
|
|
||||||
// releaseSocketConn(sc)
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sc *SocketConn) LocalAddr() net.Addr {
|
|
||||||
// return sc.s.LocalAddr()
|
|
||||||
// }
|
|
||||||
// func (sc *SocketConn) RemoteAddr() net.Addr {
|
|
||||||
// return sc.s.RemoteAddr()
|
|
||||||
// }
|
|
||||||
// func (sc *SocketConn) SetDeadline(t time.Time) error {
|
|
||||||
// if err := sc.s.SetReadDeadline(t); nil != err {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if err := sc.s.SetWriteDeadline(t); nil != err {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
// func (sc *SocketConn) SetReadDeadline(t time.Time) error {
|
|
||||||
// return sc.s.SetReadDeadline(t)
|
|
||||||
// }
|
|
||||||
// func (sc *SocketConn) SetWriteDeadline(t time.Time) error {
|
|
||||||
// return sc.s.SetWriteDeadline(t)
|
|
||||||
// }
|
|
||||||
|
|
||||||
var socketPool sync.Pool
|
var socketPool sync.Pool
|
||||||
|
|
||||||
func retainSocket() *fasthttpWebSocket {
|
func retainSocket() *fasthttpWebSocket {
|
||||||
|
@ -297,21 +216,3 @@ func releaseSocket(s *fasthttpWebSocket) {
|
||||||
|
|
||||||
socketPool.Put(s)
|
socketPool.Put(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// var socketConnPool sync.Pool
|
|
||||||
|
|
||||||
// func retainSocketConn() *SocketConn {
|
|
||||||
// v := socketConnPool.Get()
|
|
||||||
// if v == nil {
|
|
||||||
// return &SocketConn{}
|
|
||||||
// }
|
|
||||||
// return v.(*SocketConn)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func releaseSocketConn(sc *SocketConn) {
|
|
||||||
// sc.s = nil
|
|
||||||
// sc.r = nil
|
|
||||||
// sc.wc = nil
|
|
||||||
|
|
||||||
// socketConnPool.Put(sc)
|
|
||||||
// }
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user