mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 11:59:40 +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 {
|
func NewClient(server *Server, conn net.Conn, isTLS bool) *Client {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
socket := NewSocket(conn)
|
socket := NewSocket(conn)
|
||||||
|
go socket.RunSocketWriter()
|
||||||
client := &Client{
|
client := &Client{
|
||||||
atime: now,
|
atime: now,
|
||||||
authorized: server.password == nil,
|
authorized: server.password == nil,
|
||||||
|
@ -10,9 +10,11 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,23 +29,25 @@ type Socket struct {
|
|||||||
Closed bool
|
Closed bool
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
reader *bufio.Reader
|
reader *bufio.Reader
|
||||||
|
|
||||||
|
lineToSendExists chan bool
|
||||||
|
linesToSend []string
|
||||||
|
linesToSendMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSocket returns a new Socket.
|
// NewSocket returns a new Socket.
|
||||||
func NewSocket(conn net.Conn) Socket {
|
func NewSocket(conn net.Conn) Socket {
|
||||||
return Socket{
|
return Socket{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
reader: bufio.NewReader(conn),
|
reader: bufio.NewReader(conn),
|
||||||
|
lineToSendExists: make(chan bool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close stops a Socket from being able to send/receive any more data.
|
// Close stops a Socket from being able to send/receive any more data.
|
||||||
func (socket *Socket) Close() {
|
func (socket *Socket) Close() {
|
||||||
if socket.Closed {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
socket.Closed = true
|
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.
|
// 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
|
return io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
// write data
|
socket.linesToSendMutex.Lock()
|
||||||
_, err := socket.conn.Write([]byte(data))
|
socket.linesToSend = append(socket.linesToSend, data)
|
||||||
if err != nil {
|
socket.linesToSendMutex.Unlock()
|
||||||
socket.Close()
|
go socket.fillLineToSendExists()
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
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.
|
// WriteLine writes the given line out of Socket.
|
||||||
func (socket *Socket) WriteLine(line string) error {
|
func (socket *Socket) WriteLine(line string) error {
|
||||||
return socket.Write(line + "\r\n")
|
return socket.Write(line + "\r\n")
|
||||||
|
Loading…
Reference in New Issue
Block a user