use persistent connections
Some checks failed
Build and Publish / BuildAndDeployAmd64 (push) Failing after 27s
Build and Publish / BuildAndDeploy (push) Successful in 2m19s

This commit is contained in:
matst80
2024-11-12 17:09:46 +01:00
parent 1c42cf0976
commit 98d9b2451e
4 changed files with 69 additions and 201 deletions

View File

@@ -3,6 +3,7 @@ package main
import (
"encoding/binary"
"fmt"
"log"
"net"
"time"
)
@@ -24,54 +25,66 @@ func Dial(address string) (*Client, error) {
}
type TCPClient struct {
net.Conn
*PersistentConnection
ErrorCount int
address string
*PacketQueue
}
func NewTCPClient(address string) (*TCPClient, error) {
type PersistentConnection struct {
net.Conn
address string
}
func NewPersistentConnection(address string) (*PersistentConnection, error) {
connection, err := net.Dial("tcp", address)
if err != nil {
return nil, err
}
return &TCPClient{
ErrorCount: 0,
Conn: connection,
address: address,
PacketQueue: NewPacketQueue(connection),
return &PersistentConnection{
Conn: connection,
address: address,
}, nil
}
func (m *TCPClient) Connect() error {
if m.Conn == nil {
connection, err := net.Dial("tcp", m.address)
if err != nil {
return err
}
m.ErrorCount = 0
m.Conn = connection
func (m *PersistentConnection) Connect() error {
connection, err := net.Dial("tcp", m.address)
if err != nil {
return err
}
m.Conn = connection
return nil
}
func (m *TCPClient) HandleConnectionError(err error) error {
func (m *PersistentConnection) Close() {
m.Conn.Close()
}
func (m *PersistentConnection) HandleConnectionError(err error) error {
if err != nil {
m.ErrorCount++
m.Conn.Close()
m.Connect()
}
return err
}
func (m *TCPClient) Close() {
m.Conn.Close()
func NewTCPClient(address string) (*TCPClient, error) {
connection, err := NewPersistentConnection(address)
if err != nil {
return nil, err
}
return &TCPClient{
ErrorCount: 0,
PersistentConnection: connection,
address: address,
PacketQueue: NewPacketQueue(connection),
}, nil
}
func (m *TCPClient) SendPacket(messageType uint32, data []byte) error {
err := m.Connect()
if err != nil {
return err
}
err = binary.Write(m.Conn, binary.LittleEndian, Packet{
err := binary.Write(m.Conn, binary.LittleEndian, Packet{
Version: CurrentPacketVersion,
MessageType: messageType,
StatusCode: 0,
@@ -81,29 +94,22 @@ func (m *TCPClient) SendPacket(messageType uint32, data []byte) error {
return m.HandleConnectionError(err)
}
_, err = m.Conn.Write(data)
m.Conn.SetDeadline(time.Now().Add(time.Second * 10))
return m.HandleConnectionError(err)
}
// func (m *TCPClient) SendPacketFn(messageType uint32, datafn func(w io.Writer) error) error {
// data, err := GetData(datafn)
// if err != nil {
// return err
// }
// return m.SendPacket(messageType, data)
// }
func (m *TCPClient) Call(messageType uint32, responseType uint32, data []byte) (*CallResult, error) {
packetChan := m.Expect(responseType)
err := m.SendPacket(messageType, data)
if err != nil {
return nil, err
m.RemoveListeners()
return nil, m.HandleConnectionError(err)
}
select {
case ret := <-packetChan:
return &ret, nil
case <-time.After(time.Second * 10):
return nil, fmt.Errorf("timeout")
case <-time.After(time.Second):
log.Printf("Timeout waiting for cart response to message type %d\n", responseType)
return nil, m.HandleConnectionError(fmt.Errorf("timeout"))
}
}