wip
This commit is contained in:
parent
c89d435b5a
commit
5a53e7069d
10 changed files with 201 additions and 16 deletions
|
@ -1,2 +1,2 @@
|
|||
allowedServers:
|
||||
- "127.0.0.1:16000"
|
||||
- "195.201.123.169:16000"
|
||||
|
|
|
@ -3,7 +3,7 @@ module git.vh7.uk/jakew/echo-web/bridge
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
git.vh7.uk/jakew/echo-go v0.0.0-20220803185705-357282c0e444
|
||||
git.vh7.uk/jakew/echo-go v0.0.0-20220805101505-158189ae7d58
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/rs/zerolog v1.27.0
|
||||
github.com/samber/lo v1.27.0
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
git.vh7.uk/jakew/echo-go v0.0.0-20220803185705-357282c0e444 h1:/GiYRoIHnYqoF9bAHwYXlLCy4praom2KlwBed8pW3ZU=
|
||||
git.vh7.uk/jakew/echo-go v0.0.0-20220803185705-357282c0e444/go.mod h1:Q4YqOodoX+qYvfM0gSf78cCk0o7dkg1GLNYUFgB6qhU=
|
||||
git.vh7.uk/jakew/echo-go v0.0.0-20220805101505-158189ae7d58 h1:gMa91PLcG4jRunbntD/YSt/7U3eSyAHUNxIdWu4ELjU=
|
||||
git.vh7.uk/jakew/echo-go v0.0.0-20220805101505-158189ae7d58/go.mod h1:Q4YqOodoX+qYvfM0gSf78cCk0o7dkg1GLNYUFgB6qhU=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
echo "git.vh7.uk/jakew/echo-go"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/samber/lo"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -26,6 +28,27 @@ var upgrader = websocket.Upgrader{
|
|||
},
|
||||
}
|
||||
|
||||
func (h *websocketHandler) receiver(conn *websocket.Conn, client *echo.Client) {
|
||||
defer conn.Close()
|
||||
|
||||
for {
|
||||
msgs, err := client.Receive()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to receive from server")
|
||||
return
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
log.Info().Interface("msg", msg).Msg("received message")
|
||||
bytes, err := json.Marshal(&msg)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to marshal message")
|
||||
}
|
||||
conn.WriteMessage(websocket.TextMessage, bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *websocketHandler) socketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
|
@ -40,7 +63,7 @@ func (h *websocketHandler) socketHandler(w http.ResponseWriter, r *http.Request)
|
|||
username := r.URL.Query().Get("username")
|
||||
password := r.URL.Query().Get("password")
|
||||
|
||||
if !lo.Contains[string](h.config.AllowedServers, server) {
|
||||
if !lo.Contains(h.config.AllowedServers, server) {
|
||||
_ = conn.WriteMessage(websocket.TextMessage, []byte("{\"error\": \"Server not allowed\"}"))
|
||||
return
|
||||
}
|
||||
|
@ -54,34 +77,37 @@ func (h *websocketHandler) socketHandler(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
defer client.Disconnect()
|
||||
|
||||
err = client.HandshakeLoop(password)
|
||||
err = client.HandshakeLoop("4.0.0", password)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to handshake with server")
|
||||
_ = conn.WriteMessage(websocket.TextMessage, []byte("{\"error\": \"Failed to connect\"}"))
|
||||
return
|
||||
}
|
||||
|
||||
go h.receiver(conn, client)
|
||||
|
||||
for {
|
||||
messageType, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("failed to receive websocket message")
|
||||
break
|
||||
return
|
||||
}
|
||||
|
||||
if messageType == websocket.CloseMessage {
|
||||
log.Debug().Msg("websocket closed")
|
||||
break
|
||||
} else if messageType == websocket.TextMessage {
|
||||
err = conn.WriteMessage(messageType, message)
|
||||
var echoMessage echo.RawMessage
|
||||
err = json.Unmarshal(message, &echoMessage)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("failed to send websocket message")
|
||||
log.Warn().Err(err).Msg("failed to unmarshal message")
|
||||
break
|
||||
}
|
||||
client.Send(echoMessage.MessageType, echoMessage.Data, echoMessage.SubType, []string{})
|
||||
} else {
|
||||
log.Warn().Int("type", messageType).Bytes("message", message).Msg("message type not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Str("address", conn.RemoteAddr().String()).Msg("websocket connection closed")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -15,14 +15,18 @@
|
|||
"@mantine/hooks": "^5.0.2",
|
||||
"@mantine/modals": "^5.0.2",
|
||||
"@mantine/notifications": "^5.0.2",
|
||||
"@reduxjs/toolkit": "^1.8.3",
|
||||
"dayjs": "^1.11.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-feather": "^2.0.10"
|
||||
"react-feather": "^2.0.10",
|
||||
"react-redux": "^8.0.2",
|
||||
"ws": "^8.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@vitejs/plugin-react": "^2.0.0",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^3.0.0"
|
||||
|
|
|
@ -3,11 +3,15 @@ import ReactDOM from 'react-dom/client'
|
|||
import { MantineProvider } from '@mantine/core';
|
||||
import App from './App'
|
||||
import './index.css';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<MantineProvider withGlobalStyles withNormalizeCSS>
|
||||
<App />
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
</MantineProvider>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
|
24
frontend/src/middleware/chat.tsx
Normal file
24
frontend/src/middleware/chat.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { Middleware } from "@reduxjs/toolkit";
|
||||
import WebSocket from 'ws';
|
||||
import { chatActions } from "../slices/chat";
|
||||
|
||||
const chatMiddleware: Middleware = (store) => (next) => (action) => {
|
||||
if (!chatActions.startConnecting.match(action)) {
|
||||
return next(action);
|
||||
}
|
||||
|
||||
const socket = new WebSocket("ws://127.0.0.1:4000?server=195.201.123.169:16000&username=jake");
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('Connected to WebSocket!');
|
||||
store.dispatch(chatActions.connectionEstablished());
|
||||
});
|
||||
|
||||
socket.on('message', (message: any) => {
|
||||
store.dispatch(chatActions.recieveMessage({ message }))
|
||||
});
|
||||
|
||||
next(action);
|
||||
};
|
||||
|
||||
export default chatMiddleware;
|
36
frontend/src/slices/chat.tsx
Normal file
36
frontend/src/slices/chat.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
export interface ChatState {
|
||||
messages: any[];
|
||||
isEstablishingConnection: boolean;
|
||||
isConnected: boolean;
|
||||
}
|
||||
|
||||
const initialState: ChatState = {
|
||||
messages: [],
|
||||
isEstablishingConnection: false,
|
||||
isConnected: false
|
||||
};
|
||||
|
||||
const chatSlice = createSlice({
|
||||
name: "chat",
|
||||
initialState,
|
||||
reducers: {
|
||||
startConnecting: (state) => {
|
||||
state.isEstablishingConnection = true;
|
||||
},
|
||||
connectionEstablished: (state) => {
|
||||
state.isConnected = true;
|
||||
state.isEstablishingConnection = true;
|
||||
},
|
||||
recieveMessage: (state, action: PayloadAction<{
|
||||
message: any
|
||||
}>) => {
|
||||
state.messages.push(action.payload.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const chatActions = chatSlice.actions;
|
||||
|
||||
export default chatSlice;
|
5
frontend/src/store.ts
Normal file
5
frontend/src/store.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { configureStore } from '@reduxjs/toolkit';
|
||||
|
||||
export default configureStore({
|
||||
reducer: {}
|
||||
});
|
|
@ -206,7 +206,7 @@
|
|||
"@babel/plugin-syntax-jsx" "^7.18.6"
|
||||
"@babel/types" "^7.18.10"
|
||||
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.18.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
|
||||
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
|
||||
|
@ -545,6 +545,29 @@
|
|||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@reduxjs/toolkit@^1.8.3":
|
||||
version "1.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.8.3.tgz#9c6a9c497bde43a67618d37a4175a00ae12efeb2"
|
||||
integrity sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==
|
||||
dependencies:
|
||||
immer "^9.0.7"
|
||||
redux "^4.1.2"
|
||||
redux-thunk "^2.4.1"
|
||||
reselect "^4.1.5"
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "18.6.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39"
|
||||
integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg==
|
||||
|
||||
"@types/parse-json@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
|
@ -576,6 +599,18 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
||||
|
||||
"@types/use-sync-external-store@^0.0.3":
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
|
||||
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
|
||||
|
||||
"@types/ws@^8.5.3":
|
||||
version "8.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"
|
||||
integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@vitejs/plugin-react@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-2.0.0.tgz#12decd097773a00620e44b780b1d2c00df101449"
|
||||
|
@ -897,13 +932,18 @@ has@^1.0.3:
|
|||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hoist-non-react-statics@^3.3.1:
|
||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
dependencies:
|
||||
react-is "^16.7.0"
|
||||
|
||||
immer@^9.0.7:
|
||||
version "9.0.15"
|
||||
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc"
|
||||
integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==
|
||||
|
||||
import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -1053,6 +1093,23 @@ react-is@^16.13.1, react-is@^16.7.0:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-is@^18.0.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react-redux@^8.0.2:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.2.tgz#bc2a304bb21e79c6808e3e47c50fe1caf62f7aad"
|
||||
integrity sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.1"
|
||||
"@types/hoist-non-react-statics" "^3.3.1"
|
||||
"@types/use-sync-external-store" "^0.0.3"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
react-is "^18.0.0"
|
||||
use-sync-external-store "^1.0.0"
|
||||
|
||||
react-refresh@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
|
||||
|
@ -1084,11 +1141,28 @@ react@^18.2.0:
|
|||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
redux-thunk@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714"
|
||||
integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==
|
||||
|
||||
redux@^4.1.2:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
|
||||
integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.9.2"
|
||||
|
||||
regenerator-runtime@^0.13.4:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||
|
||||
reselect@^4.1.5:
|
||||
version "4.1.6"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.6.tgz#19ca2d3d0b35373a74dc1c98692cdaffb6602656"
|
||||
integrity sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
|
@ -1199,6 +1273,11 @@ use-latest@^1.2.1:
|
|||
dependencies:
|
||||
use-isomorphic-layout-effect "^1.1.1"
|
||||
|
||||
use-sync-external-store@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||
|
||||
vite@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.4.tgz#c61688d6b97573e96cf5ac25f2d68597b5ce68e8"
|
||||
|
@ -1211,6 +1290,11 @@ vite@^3.0.0:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
ws@^8.8.1:
|
||||
version "8.8.1"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0"
|
||||
integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==
|
||||
|
||||
yaml@^1.10.0:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
|
|
Loading…
Reference in a new issue