From c35f2705dcebfae66ba293371332ab5867e703da Mon Sep 17 00:00:00 2001 From: Kyren223 Date: Wed, 16 Oct 2024 16:10:26 +0300 Subject: feat: basic messaging between client and server --- internal/client/client.go | 32 +++++++++++++++++++++++------- internal/data/chat.go | 36 ++++++++++++++++++++++++++++++++++ internal/packet/messages.go | 29 +++++++++++++++++++++++++++ internal/packet/packet.go | 11 ++++++++++- internal/server/handler.go | 48 ++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 internal/data/chat.go (limited to 'internal') diff --git a/internal/client/client.go b/internal/client/client.go index 80b29a0..83b3d90 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -8,6 +8,7 @@ import ( _ "embed" "fmt" "log" + "net" "os" "strings" "time" @@ -44,7 +45,7 @@ func Run() { } } -func processRequest(request string, tlsConfig *tls.Config) error { +func processRequest(input string, tlsConfig *tls.Config) error { conn, err := tls.Dial("tcp4", ":7223", tlsConfig) if err != nil { return fmt.Errorf("error establishing connection with server: %v", err) @@ -53,8 +54,27 @@ func processRequest(request string, tlsConfig *tls.Config) error { log.Println("established connection with server:", conn.RemoteAddr().String()) - requestMsg := packet.EkoMessage{Message: request} - encoder, err := packet.NewMsgPackEncoder(&requestMsg) + if input == "SHOW" { + request := packet.GetMessagesMessage{} + var response packet.MessagesMessage + if err := SendAndReceive(conn, &request, &response); err != nil { + return err + } + log.Println("server response:", response.Messages) + } else { + request := packet.SendMessageMessage{Content: input} + var response packet.EkoMessage + if err := SendAndReceive(conn, &request, &response); err != nil { + return err + } + log.Println("server response:", response.Message) + } + + return nil +} + +func SendAndReceive(conn net.Conn, request packet.TypedMessage, response packet.TypedMessage) error { + encoder, err := packet.NewMsgPackEncoder(request) if err != nil { return fmt.Errorf("error encoding request: %v", err) } @@ -65,14 +85,13 @@ func processRequest(request string, tlsConfig *tls.Config) error { } log.Println("sent request to server") - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() out, outErr := packet.RunFramer(ctx, conn) - var response packet.EkoMessage select { case responsePacket := <-out: - if err := responsePacket.DecodePayload(&response); err != nil { + if err := responsePacket.DecodePayload(response); err != nil { return fmt.Errorf("error decoding response: %v", err) } @@ -80,6 +99,5 @@ func processRequest(request string, tlsConfig *tls.Config) error { return fmt.Errorf("error receiving response: %v", err) } - log.Println("server response:", response.Message) return nil } diff --git a/internal/data/chat.go b/internal/data/chat.go new file mode 100644 index 0000000..9d2443d --- /dev/null +++ b/internal/data/chat.go @@ -0,0 +1,36 @@ +package data + +import "github.com/kyren223/eko/pkg/snowflake" + +// Represents an Eko Network, equivalent to a "discord server". +type Network struct { + id snowflake.ID + name string + frequencies []snowflake.ID +} + +// Represents an Eko Frequency, equivalent to a "discord channel" within a "discord server". +type Frequency struct { + id snowflake.ID + name string +} + +// Represents an Eko Signal, equivalent to a "discord message" between only 2 people. +type Signal struct { + userId1 snowflake.ID + userId2 snowflake.ID +} + +// Represents a message +type Message struct { + Id snowflake.ID + SenderId snowflake.ID + FrequencyId snowflake.ID + NetworkId snowflake.ID + Contents string +} + +// Represents an Eko User +type User struct { + id snowflake.ID +} diff --git a/internal/packet/messages.go b/internal/packet/messages.go index f8390f8..b1a6598 100644 --- a/internal/packet/messages.go +++ b/internal/packet/messages.go @@ -1,5 +1,9 @@ package packet +import ( + "github.com/kyren223/eko/internal/data" +) + type EkoMessage struct { Message string `msgpack:"message"` } @@ -15,3 +19,28 @@ type ErrorMessage struct { func (m *ErrorMessage) Type() PacketType { return TypeError } + +type GetMessagesMessage struct { + Since *int64 + UpTo *int64 +} + +func (m *GetMessagesMessage) Type() PacketType { + return TypeGetMessages +} + +type SendMessageMessage struct { + Content string +} + +func (m *SendMessageMessage) Type() PacketType { + return TypeSendMessage +} + +type MessagesMessage struct { + Messages []data.Message +} + +func (m *MessagesMessage) Type() PacketType { + return TypeMessages +} diff --git a/internal/packet/packet.go b/internal/packet/packet.go index 068a8f3..3b49249 100644 --- a/internal/packet/packet.go +++ b/internal/packet/packet.go @@ -52,6 +52,12 @@ func (t PacketType) String() string { return "PacketTypeEko" case TypeError: return "PacketTypeError" + case TypeGetMessages: + return "PacketTypeGetMessages" + case TypeSendMessage: + return "PacketTypeSendMessage" + case TypeMessages: + return "PacketTypeMessages" default: return fmt.Sprintf("PacketTypeInvalid(%v)", byte(t)) } @@ -59,7 +65,7 @@ func (t PacketType) String() string { func (e PacketType) IsSupported() bool { switch e { - case TypeEko, TypeError: + case TypeEko, TypeError, TypeGetMessages, TypeSendMessage, TypeMessages: return true default: return false @@ -69,6 +75,9 @@ func (e PacketType) IsSupported() bool { const ( TypeEko PacketType = iota TypeError + TypeGetMessages + TypeSendMessage + TypeMessages ) const ( diff --git a/internal/server/handler.go b/internal/server/handler.go index 61ecbae..cf1eb82 100644 --- a/internal/server/handler.go +++ b/internal/server/handler.go @@ -9,8 +9,9 @@ import ( "sync" "time" + "github.com/kyren223/eko/internal/data" "github.com/kyren223/eko/internal/packet" - "github.com/kyren223/eko/pkg/assert" + "github.com/kyren223/eko/pkg/snowflake" ) func handleConnection(conn net.Conn, wg *sync.WaitGroup) { @@ -42,6 +43,9 @@ outer: } case err := <-outErr: + if err == nil { + continue + } if err == packet.PacketUnsupportedEncoding { err := unsupportedEncodingErrorPacket.Into(conn) log.Printf("client %v: error writing unsupported encoding packet: %v\n", conn.RemoteAddr().String(), err) @@ -74,11 +78,45 @@ func handlePacket(pkt packet.Packet) (packet.Packet, error) { return packet.Packet{}, fmt.Errorf("encode error: %v", err) } return packet.NewPacket(encoder), nil + case packet.TypeSendMessage: + var request packet.SendMessageMessage + if err := pkt.DecodePayload(&request); err != nil { + return packet.Packet{}, fmt.Errorf("decode error: %v", err) + } - case packet.TypeError: - return packet.Packet{}, errors.New("TODO: not implemented yet") + message := data.Message{ + Id: node.Generate(), + SenderId: node.Generate(), + FrequencyId: node.Generate(), + NetworkId: node.Generate(), + Contents: request.Content, + } + messages = append(messages, message) + + response := packet.EkoMessage{Message: "Eko OK"} + encoder, err := packet.NewMsgPackEncoder(&response) + if err != nil { + return packet.Packet{}, fmt.Errorf("encode error: %v", err) + } + return packet.NewPacket(encoder), nil + case packet.TypeGetMessages: + var request packet.GetMessagesMessage + if err := pkt.DecodePayload(&request); err != nil { + return packet.Packet{}, fmt.Errorf("decode error: %v", err) + } + + response := packet.MessagesMessage{Messages: messages} + encoder, err := packet.NewMsgPackEncoder(&response) + if err != nil { + return packet.Packet{}, fmt.Errorf("encode error: %v", err) + } + return packet.NewPacket(encoder), nil default: - assert.Unreachable("type should be checked for validity before handler, packet = %v", pkt.String()) - return packet.Packet{}, nil + return packet.Packet{}, errors.New("TODO: not implemented yet") } } + +var ( + node = snowflake.NewNode(1) + messages []data.Message = make([]data.Message, 10) +) -- cgit v1.3.1