123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package websocket
- import (
- "bytes"
- "net"
- "sync"
- "time"
- )
- type PreparedMessage struct {
- messageType int
- data []byte
- err error
- mu sync.Mutex
- frames map[prepareKey]*preparedFrame
- }
- type prepareKey struct {
- isServer bool
- compress bool
- compressionLevel int
- }
- type preparedFrame struct {
- once sync.Once
- data []byte
- }
- func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
- pm := &PreparedMessage{
- messageType: messageType,
- frames: make(map[prepareKey]*preparedFrame),
- data: data,
- }
-
- _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
- if err != nil {
- return nil, err
- }
-
-
- pm.data = frameData[len(frameData)-len(data):]
- return pm, nil
- }
- func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
- pm.mu.Lock()
- frame, ok := pm.frames[key]
- if !ok {
- frame = &preparedFrame{}
- pm.frames[key] = frame
- }
- pm.mu.Unlock()
- var err error
- frame.once.Do(func() {
-
-
-
- mu := make(chan bool, 1)
- mu <- true
- var nc prepareConn
- c := &Conn{
- conn: &nc,
- mu: mu,
- isServer: key.isServer,
- compressionLevel: key.compressionLevel,
- enableWriteCompression: true,
- writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
- }
- if key.compress {
- c.newCompressionWriter = compressNoContextTakeover
- }
- err = c.WriteMessage(pm.messageType, pm.data)
- frame.data = nc.buf.Bytes()
- })
- return pm.messageType, frame.data, err
- }
- type prepareConn struct {
- buf bytes.Buffer
- net.Conn
- }
- func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) }
- func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
|