mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 10:42:52 +01:00
socket: Start overhaul of sockets and writing
This commit is contained in:
parent
73d406ccd6
commit
de4db1c6ef
@ -75,6 +75,7 @@ type Client struct {
|
||||
func NewClient(server *Server, conn net.Conn, isTLS bool) *Client {
|
||||
now := time.Now()
|
||||
socket := NewSocket(conn)
|
||||
go socket.RunSocketWriter()
|
||||
client := &Client{
|
||||
atime: now,
|
||||
authorized: server.password == nil,
|
||||
|
@ -10,9 +10,11 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -27,23 +29,25 @@ type Socket struct {
|
||||
Closed bool
|
||||
conn net.Conn
|
||||
reader *bufio.Reader
|
||||
|
||||
lineToSendExists chan bool
|
||||
linesToSend []string
|
||||
linesToSendMutex sync.Mutex
|
||||
}
|
||||
|
||||
// NewSocket returns a new Socket.
|
||||
func NewSocket(conn net.Conn) Socket {
|
||||
return Socket{
|
||||
conn: conn,
|
||||
reader: bufio.NewReader(conn),
|
||||
conn: conn,
|
||||
reader: bufio.NewReader(conn),
|
||||
lineToSendExists: make(chan bool),
|
||||
}
|
||||
}
|
||||
|
||||
// Close stops a Socket from being able to send/receive any more data.
|
||||
func (socket *Socket) Close() {
|
||||
if socket.Closed {
|
||||
return
|
||||
}
|
||||
socket.Closed = true
|
||||
socket.conn.Close()
|
||||
// socket will close once all data has been sent
|
||||
}
|
||||
|
||||
// CertFP returns the fingerprint of the certificate provided by the client.
|
||||
@ -104,15 +108,57 @@ func (socket *Socket) Write(data string) error {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
// write data
|
||||
_, err := socket.conn.Write([]byte(data))
|
||||
if err != nil {
|
||||
socket.Close()
|
||||
return err
|
||||
}
|
||||
socket.linesToSendMutex.Lock()
|
||||
socket.linesToSend = append(socket.linesToSend, data)
|
||||
socket.linesToSendMutex.Unlock()
|
||||
go socket.fillLineToSendExists()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// fillLineToSendExists only exists because you can't goroutine single statements.
|
||||
func (socket *Socket) fillLineToSendExists() {
|
||||
socket.lineToSendExists <- true
|
||||
}
|
||||
|
||||
// RunSocketWriter starts writing messages to the outgoing socket.
|
||||
func (socket *Socket) RunSocketWriter() {
|
||||
var errOut bool
|
||||
for {
|
||||
// wait for new lines
|
||||
select {
|
||||
case <-socket.lineToSendExists:
|
||||
socket.linesToSendMutex.Lock()
|
||||
|
||||
// get data
|
||||
data := socket.linesToSend[0]
|
||||
if len(socket.linesToSend) > 1 {
|
||||
socket.linesToSend = socket.linesToSend[1:]
|
||||
} else {
|
||||
socket.linesToSend = []string{}
|
||||
}
|
||||
|
||||
// write data
|
||||
_, err := socket.conn.Write([]byte(data))
|
||||
if err != nil {
|
||||
errOut = true
|
||||
fmt.Println(err.Error())
|
||||
break
|
||||
}
|
||||
socket.linesToSendMutex.Unlock()
|
||||
}
|
||||
if errOut {
|
||||
// error out, bad stuff happened
|
||||
break
|
||||
}
|
||||
}
|
||||
//TODO(dan): empty socket.lineToSendExists queue
|
||||
socket.conn.Close()
|
||||
if !socket.Closed {
|
||||
socket.Closed = true
|
||||
}
|
||||
}
|
||||
|
||||
// WriteLine writes the given line out of Socket.
|
||||
func (socket *Socket) WriteLine(line string) error {
|
||||
return socket.Write(line + "\r\n")
|
||||
|
Loading…
Reference in New Issue
Block a user