Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit a72920e

Browse files
committed
Create chat, and finalises the dashboard API, #68
Moves the websocket handler from main.go to its own package, chat. Move the logs for the dashboard and the chat to their own packages.
1 parent 087043c commit a72920e

File tree

4 files changed

+139
-116
lines changed

4 files changed

+139
-116
lines changed

chat/websocket.go

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package chat
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"reflect"
8+
"time"
9+
10+
"github.com/olivia-ai/olivia/network"
11+
12+
"github.com/gookit/color"
13+
"github.com/gorilla/websocket"
14+
"github.com/olivia-ai/olivia/analysis"
15+
"github.com/olivia-ai/olivia/user"
16+
"github.com/olivia-ai/olivia/util"
17+
gocache "github.com/patrickmn/go-cache"
18+
)
19+
20+
var (
21+
// Create the neural network variable to use it everywhere
22+
neuralNetwork network.Network
23+
// Initiatizes the cache with a 5 minute lifetime
24+
cache = gocache.New(5*time.Minute, 5*time.Minute)
25+
)
26+
27+
// Configure the upgrader
28+
var upgrader = websocket.Upgrader{
29+
CheckOrigin: func(r *http.Request) bool {
30+
return true
31+
},
32+
}
33+
34+
// RequestMessage is the structure that uses entry connections to chat with the websocket
35+
type RequestMessage struct {
36+
Content string `json:"content"`
37+
Token string `json:"user_token"`
38+
Information user.Information `json:"information"`
39+
}
40+
41+
// ResponseMessage is the structure used to reply to the user through the websocket
42+
type ResponseMessage struct {
43+
Content string `json:"content"`
44+
Tag string `json:"tag"`
45+
Information user.Information `json:"information"`
46+
}
47+
48+
// Serve serves the websocket in the given port
49+
func Serve(_neuralNetwork network.Network, port string) {
50+
// Set the current global network as a global variable
51+
neuralNetwork = _neuralNetwork
52+
53+
http.HandleFunc("/", Handle)
54+
55+
magenta := color.FgMagenta.Render
56+
fmt.Printf("\nChat Websocket listening on the port %s...\n", magenta(port))
57+
58+
// Serves the chat
59+
err := http.ListenAndServe(":"+port, nil)
60+
if err != nil {
61+
panic(err)
62+
}
63+
}
64+
65+
// Handle manages the entry connections and reply with the neural network
66+
func Handle(w http.ResponseWriter, r *http.Request) {
67+
conn, _ := upgrader.Upgrade(w, r, nil)
68+
fmt.Println(color.FgGreen.Render("A new connection has been opened"))
69+
70+
for {
71+
// Read message from browser
72+
msgType, msg, err := conn.ReadMessage()
73+
if err != nil {
74+
continue
75+
}
76+
77+
// Unserialize the json content of the message
78+
var request RequestMessage
79+
if err = json.Unmarshal(msg, &request); err != nil {
80+
continue
81+
}
82+
83+
// Set the informations from the client into the cache
84+
if reflect.DeepEqual(user.GetUserInformation(request.Token), user.Information{}) {
85+
user.SetUserInformation(request.Token, request.Information)
86+
}
87+
88+
// Write message back to browser
89+
response := Reply(request)
90+
if err = conn.WriteMessage(msgType, response); err != nil {
91+
continue
92+
}
93+
}
94+
}
95+
96+
// Reply takes the entry message and returns an array of bytes for the answer
97+
func Reply(request RequestMessage) []byte {
98+
var responseSentence, responseTag string
99+
100+
// Send a message from res/messages.json if it is too long
101+
if len(request.Content) > 500 {
102+
responseTag = "too long"
103+
responseSentence = util.GetMessage(responseTag)
104+
} else {
105+
responseTag, responseSentence = analysis.NewSentence(
106+
request.Content,
107+
).Calculate(*cache, neuralNetwork, request.Token)
108+
}
109+
110+
// Marshall the response in json
111+
response := ResponseMessage{
112+
Content: responseSentence,
113+
Tag: responseTag,
114+
Information: user.GetUserInformation(request.Token),
115+
}
116+
117+
bytes, err := json.Marshal(response)
118+
if err != nil {
119+
panic(err)
120+
}
121+
122+
return bytes
123+
}

dashboard/api.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package dashboard
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"log"
67
"net/http"
78

9+
"github.com/gookit/color"
10+
811
"github.com/gorilla/mux"
912
"github.com/olivia-ai/olivia/network"
1013
)
@@ -29,7 +32,7 @@ type Training struct {
2932
}
3033

3134
// Serve serves the dashboard REST API on the port 8081 by default.
32-
func Serve(_neuralNetwork network.Network) {
35+
func Serve(_neuralNetwork network.Network, port string) {
3336
// Set the current global network as a global variable
3437
neuralNetwork = _neuralNetwork
3538

@@ -38,7 +41,11 @@ func Serve(_neuralNetwork network.Network) {
3841
// Create the routes
3942
router.HandleFunc("/dashboard", GetDashboardData).Methods("GET")
4043

41-
log.Fatal(http.ListenAndServe(":8081", router))
44+
magenta := color.FgMagenta.Render
45+
fmt.Printf("Dashboard API listening on the port %s...\n", magenta(port))
46+
47+
// Serves the dashboard
48+
log.Fatal(http.ListenAndServe(":"+port, router))
4249
}
4350

4451
// GetDashboardData encodes the json for the dashboard data

main.go

+6-113
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,22 @@
11
package main
22

33
import (
4-
"encoding/json"
5-
"fmt"
6-
"net/http"
7-
"os"
8-
"reflect"
9-
"time"
10-
4+
"github.com/olivia-ai/olivia/chat"
115
"github.com/olivia-ai/olivia/dashboard"
12-
13-
"github.com/gookit/color"
14-
"github.com/gorilla/websocket"
15-
"github.com/olivia-ai/olivia/analysis"
166
"github.com/olivia-ai/olivia/training"
17-
"github.com/olivia-ai/olivia/user"
18-
"github.com/olivia-ai/olivia/util"
19-
gocache "github.com/patrickmn/go-cache"
207
)
218

229
var (
23-
model = training.CreateNeuralNetwork()
24-
cache = gocache.New(5*time.Minute, 5*time.Minute)
10+
// Initialize the neural network by training it
11+
neuralNetwork = training.CreateNeuralNetwork()
2512
)
2613

27-
// Configure the upgrader
28-
var upgrader = websocket.Upgrader{
29-
CheckOrigin: func(r *http.Request) bool {
30-
return true
31-
},
32-
}
33-
34-
type RequestMessage struct {
35-
Content string `json:"content"`
36-
Token string `json:"user_token"`
37-
Information user.Information `json:"information"`
38-
}
39-
40-
type ResponseMessage struct {
41-
Content string `json:"content"`
42-
Tag string `json:"tag"`
43-
Information user.Information `json:"information"`
44-
}
45-
4614
func main() {
47-
http.HandleFunc("/", Handle)
48-
49-
port := "8080"
50-
if os.Getenv("PORT") != "" {
51-
port = os.Getenv("PORT")
52-
}
53-
54-
magenta := color.FgMagenta.Render
55-
5615
// Serve the REST API inside a go routine
5716
go func() {
58-
fmt.Printf("Dashboard API listening on the port %s...\n", magenta(8081))
59-
60-
// Serve the API
61-
dashboard.Serve(model)
17+
dashboard.Serve(neuralNetwork, "8081")
6218
}()
6319

64-
fmt.Printf("\nChat Websocket listening on the port %s...\n", magenta(port))
65-
66-
// Serves the websocket
67-
err := http.ListenAndServe(":"+port, nil)
68-
if err != nil {
69-
panic(err)
70-
}
71-
}
72-
73-
func Handle(w http.ResponseWriter, r *http.Request) {
74-
conn, _ := upgrader.Upgrade(w, r, nil)
75-
fmt.Println(color.FgGreen.Render("A new connection has been opened"))
76-
77-
for {
78-
// Read message from browser
79-
msgType, msg, err := conn.ReadMessage()
80-
if err != nil {
81-
continue
82-
}
83-
84-
// Unserialize the json content of the message
85-
var request RequestMessage
86-
if err = json.Unmarshal(msg, &request); err != nil {
87-
continue
88-
}
89-
90-
// Set the informations from the client into the cache
91-
if reflect.DeepEqual(user.GetUserInformation(request.Token), user.Information{}) {
92-
user.SetUserInformation(request.Token, request.Information)
93-
}
94-
95-
// Write message back to browser
96-
response := Reply(request)
97-
if err = conn.WriteMessage(msgType, response); err != nil {
98-
continue
99-
}
100-
}
101-
}
102-
103-
func Reply(request RequestMessage) []byte {
104-
var responseSentence, responseTag string
105-
106-
// Send a message from res/messages.json if it is too long
107-
if len(request.Content) > 500 {
108-
responseTag = "too long"
109-
responseSentence = util.GetMessage(responseTag)
110-
} else {
111-
responseTag, responseSentence = analysis.NewSentence(
112-
request.Content,
113-
).Calculate(*cache, model, request.Token)
114-
}
115-
116-
// Marshall the response in json
117-
response := ResponseMessage{
118-
Content: responseSentence,
119-
Tag: responseTag,
120-
Information: user.GetUserInformation(request.Token),
121-
}
122-
123-
bytes, err := json.Marshal(response)
124-
if err != nil {
125-
panic(err)
126-
}
127-
128-
return bytes
20+
// Serves the chat
21+
chat.Serve(neuralNetwork, "8080")
12922
}

res/training.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)