zocket/server_conn.go

124 lines
2.5 KiB
Go
Raw Normal View History

//go:build !js || !wasm
package zocket
2020-03-11 16:07:14 +01:00
import (
"bytes"
"errors"
"fmt"
"net"
"time"
2024-08-31 13:08:44 +02:00
"udico.de/util/log"
2020-03-11 16:07:14 +01:00
)
// ServerConnection is the serverside part of the ws abstraction
type ServerConnection struct {
conn net.Conn // The underlying REAL connection.
2020-03-11 16:07:14 +01:00
buffered []byte
}
// Read gets some bytes from a ws frame. Blocks.
func (c ServerConnection) Read(b []byte) (int, error) {
if len(c.buffered) > 0 {
for i, _ := range b {
if i >= len(c.buffered) {
c.buffered = nil
return i, nil
}
b[i] = c.buffered[i]
}
if len(c.buffered) > len(b) {
c.buffered = c.buffered[len(b):]
}
return len(b), nil
}
buf := &bytes.Buffer{} //
datloop:
2020-03-11 16:07:14 +01:00
for {
tFrame, err := ReadFrame(c.conn)
if err != nil {
return 0, err
}
2020-03-11 16:07:14 +01:00
switch tFrame.Opcode {
case FrameType_Ping:
// send pong
tFrame.Opcode = FrameType_Pong
tFrame.WriteTo(c.conn)
case FrameType_Pong:
// decide
case FrameType_Close:
c.Close()
return 0, errors.New(fmt.Sprintf("connection closed: %v", tFrame.Payload[:]))
case FrameType_Binary:
buf.Write(tFrame.Payload)
if tFrame.Fin {
break datloop
}
default:
2024-08-31 13:08:44 +02:00
log.ERROR.To(logger).Msg("uhandled frame type: %v", tFrame.Opcode)
2020-03-11 16:07:14 +01:00
}
}
bytes := buf.Bytes()
for i, _ := range b {
if i >= len(bytes) {
return i, nil
}
b[i] = bytes[i]
}
if len(bytes) > len(b) {
c.buffered = bytes[len(b):]
}
return len(b), nil
}
// Write puts some bytes packed into websocket frames on the wire.
func (c ServerConnection) Write(b []byte) (int, error) {
tFrame := &Frame{
Fin: true,
Opcode: FrameType_Binary,
Masked: false,
Mask: [4]byte{},
Len: uint64(len(b)),
Payload: b,
}
err := tFrame.WriteTo(c.conn)
return len(b), err
}
// Close terminates the connection nicely.
func (c ServerConnection) Close() error {
2024-08-31 13:08:44 +02:00
log.TRACE.To(logger).Msg("serverconn_close %v", c)
2020-03-11 16:07:14 +01:00
//debug.PrintStack()
tFrame := &Frame{
Fin: true,
Opcode: FrameType_Close,
Masked: false,
Mask: [4]byte{},
Len: 0,
Payload: nil,
}
_ = tFrame.WriteTo(c.conn)
return c.conn.Close()
}
func (c ServerConnection) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
func (c ServerConnection) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
func (c ServerConnection) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
func (c ServerConnection) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
func (c ServerConnection) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}