mirror of https://github.com/JustKato/FreePad.git
Compare commits
2 Commits
400fd23b3e
...
4138386fb3
Author | SHA1 | Date |
---|---|---|
Daniel Legt | 4138386fb3 | |
Daniel Legt | cfe2c06dac |
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/mrz1836/go-sanitize v1.1.5
|
||||
github.com/ulule/limiter/v3 v3.10.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -38,6 +38,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package socketmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var wsUpgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024, // TODO: Make it configurable via the .env file
|
||||
WriteBufferSize: 1024, // TODO: Make it configurable via the .env file
|
||||
}
|
||||
|
||||
// TODO: Use generics so that we can take string messages, that'd be nice!
|
||||
type SocketMessage struct {
|
||||
EventType string `json:"eventType"`
|
||||
PadName string `json:"padName"`
|
||||
Message map[string]interface{} `json:"message"`
|
||||
}
|
||||
|
||||
// Bind the websockets to the gin router
|
||||
func BindSocket(router *gin.RouterGroup) {
|
||||
|
||||
router.GET("/get", func(ctx *gin.Context) {
|
||||
webSocketUpgrade(ctx.Writer, ctx.Request)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func webSocketUpgrade(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to set websocket upgrade: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Start listening to this socket
|
||||
for {
|
||||
// Try Read the JSON input from the socket
|
||||
_, msg, err := conn.ReadMessage()
|
||||
|
||||
// Check if a close request was sent
|
||||
if errors.Is(err, websocket.ErrCloseSent) {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// There has been an error reading the message
|
||||
fmt.Println("Failed to read from the socket")
|
||||
// Skip this cycle
|
||||
continue
|
||||
}
|
||||
|
||||
// Init the variable
|
||||
var p SocketMessage
|
||||
// Try and parse the json
|
||||
err = json.Unmarshal([]byte(msg), &p)
|
||||
if err != nil {
|
||||
// There has been an error reading the message
|
||||
fmt.Println("Failed to parse the JSON", err)
|
||||
// Skip this cycle
|
||||
continue
|
||||
}
|
||||
|
||||
// Pass the message to the proper handlers
|
||||
|
||||
handleSocketMessage(p)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the socket's message
|
||||
func handleSocketMessage(msg SocketMessage) {
|
||||
|
||||
// Check the type of message
|
||||
fmt.Println(msg.EventType)
|
||||
|
||||
}
|
||||
|
||||
func BroadcastMessage(padName string, message string) {
|
||||
|
||||
}
|
4
main.go
4
main.go
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/JustKato/FreePad/lib/controllers"
|
||||
"github.com/JustKato/FreePad/lib/objects"
|
||||
"github.com/JustKato/FreePad/lib/routes"
|
||||
"github.com/JustKato/FreePad/lib/socketmanager"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
@ -52,6 +53,9 @@ func main() {
|
|||
// Add Routes
|
||||
routes.HomeRoutes(router)
|
||||
|
||||
// Bind the Web Sockets
|
||||
socketmanager.BindSocket(router.Group("/ws"))
|
||||
|
||||
router.Run(":8080")
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
class PadSocket {
|
||||
|
||||
ws = null;
|
||||
padName = null;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
state = null;
|
||||
|
||||
/**
|
||||
* Create a new PadSocket
|
||||
* @param {string} padName The name of the pad
|
||||
* @param {string} connUrl The URL to the websocket
|
||||
*/
|
||||
constructor(padName, connUrl = null) {
|
||||
|
||||
// Check if a connection URL was mentioned
|
||||
if ( connUrl == null ) {
|
||||
// Try and connect to the local websocket
|
||||
connUrl = `ws://` + window.location.host + "/ws/get";
|
||||
}
|
||||
|
||||
// Connect to the websocket
|
||||
const ws = new WebSocket(connUrl);
|
||||
ws.onopen = () => {
|
||||
// TODO: This is redundant, we could check the websocket status: ws.readyState == WebSocket.OPEN
|
||||
this.state = 'active';
|
||||
}
|
||||
|
||||
// Bind the onMessage function
|
||||
ws.onmessage = this.handleMessage;
|
||||
|
||||
// Assign the websocket
|
||||
this.ws = ws;
|
||||
// Assign the pad name
|
||||
this.padName = padName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Send a message to the server
|
||||
* @param {string} eventType The type of event, this can be anything really, it's just used for routing by the server
|
||||
* @param {Object} message The message to send out to the server, this can only be of format string but JSON is parsed.
|
||||
*/
|
||||
sendMessage = (eventType, message) => {
|
||||
|
||||
if ( this.state != 'active' ) {
|
||||
throw new Error(`The websocket connection is not active`);
|
||||
}
|
||||
|
||||
// Check if the message is a string
|
||||
if ( typeof message == 'string' ) {
|
||||
// Convert the message into a map[string]interface{}
|
||||
message = {
|
||||
"message": message,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Compress the message, usually we will be sending the whole body of the pad from the client to the server or vice-versa.
|
||||
this.ws.send( JSON.stringify({
|
||||
eventType,
|
||||
padName: this.padName,
|
||||
message,
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
handleMessage = ev => {
|
||||
console.log(ev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Test if this is actually necessary or the DOMContentLoaded event would suffice
|
||||
// wait for the whole window to load
|
||||
window.addEventListener(`load`, e => {
|
||||
window.socket = new PadSocket(padTitle);
|
||||
})
|
|
@ -209,6 +209,7 @@
|
|||
{{ template "inc/theme-toggle.html" .}}
|
||||
</body>
|
||||
|
||||
<script src="/static/js/ws.js"></script>
|
||||
<script src="/static/js/fileSaver.js"></script>
|
||||
<script src="/static/js/pad.js"></script>
|
||||
<script src="/static/js/pad-scripts.js"></script>
|
||||
|
|
Loading…
Reference in New Issue