Compare commits

..

18 Commits
alpha ... main

Author SHA1 Message Date
alex e822a8b953 added selection for message receiver 2023-03-10 22:28:22 +01:00
alex 6acc12f03e fcm 2023-03-06 20:48:15 +01:00
alex 7101c71889 multiple clients 2023-02-27 22:51:12 +01:00
alex e384f7c02c not longer needed 2023-02-08 23:14:09 +01:00
alex 79ef8afd89 added ability to switch faster between sessions using query parameters and added option to switch between localhost and server 2023-02-08 23:10:39 +01:00
alex a40d6a769b added test for wssessions 2023-02-06 00:20:36 +01:00
alex b6be47f812 updated folder structure 2023-02-04 00:28:28 +01:00
alex 1c3266e949 updated folder structure 2023-02-04 00:00:22 +01:00
alex 6d2b99d360 updated folder structure 2023-02-03 23:59:48 +01:00
alex 0bf6a65d71 added test for rsa 2023-02-03 23:35:10 +01:00
alex cb75d9630f defining address and enabling sse and wss 2023-01-08 20:47:22 +01:00
alex cffd651965 updated readme 2022-12-24 23:37:44 +01:00
alex a8c346808b fcm client 2022-12-24 23:36:43 +01:00
alex 3066f2d84e added auth query param 2022-12-23 12:41:04 +01:00
alex 4b000b30be sse implementation 2022-12-21 19:15:51 +01:00
alex db6e3c4993 reduced timer time 2022-12-18 15:18:57 +01:00
alex 350f56539b website title 2022-12-18 15:18:37 +01:00
alex 64ec827369 switch socket with click on button 2022-12-12 22:43:27 +01:00
28 changed files with 31238 additions and 61 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

23
fcm-client/.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

11
fcm-client/README.md Normal file
View File

@ -0,0 +1,11 @@
# Used docs
https://firebase.google.com/docs/cloud-messaging/js/client?hl=en&authuser=0
https://firebase.google.com/docs/cloud-messaging/js/receive?hl=en&authuser=0
https://github.com/firebase/firebase-js-sdk/issues/5403
# Problem in Brave Browser when registering the FCM > Enable "Use Google services for push messaging"
brave://settings/privacy

30509
fcm-client/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
fcm-client/package.json Normal file
View File

@ -0,0 +1,39 @@
{
"name": "fcm-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"firebase": "^9.15.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,21 @@
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');
firebase.initializeApp({
apiKey: "AIzaSyDLqlf96eXGdRjHWJiwNp00o6_Rp8cf1l0",
authDomain: "clickandjoin-69e74.firebaseapp.com",
databaseURL: 'https://clickandjoin-69e74.firebaseio.com',
projectId: "clickandjoin-69e74",
storageBucket: "clickandjoin-69e74.appspot.com",
messagingSenderId: "75683497512",
appId: "1:75683497512:web:57b0e0446813fe51e7971d"
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
messaging.onMessage((payload) => {
console.log('Message received. ', payload);
// ...
});

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

38
fcm-client/src/App.css Normal file
View File

@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

30
fcm-client/src/App.js Normal file
View File

@ -0,0 +1,30 @@
import logo from './logo.svg';
import './App.css';
import {fetchToken, onMessageListener} from './firebase'
function App() {
fetchToken();
onMessageListener().then(payload => {
console.log(payload);
}).catch(err => console.log('failed: ', err));
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
</a>
</header>
</div>
);
}
export default App;

View File

@ -0,0 +1,8 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@ -0,0 +1,60 @@
import {initializeApp} from 'firebase/app'
import {getMessaging,getToken,onMessage} from 'firebase/messaging'
const firebaseConfig = {
apiKey: "AIzaSyDLqlf96eXGdRjHWJiwNp00o6_Rp8cf1l0",
authDomain: "clickandjoin-69e74.firebaseapp.com",
projectId: "clickandjoin-69e74",
storageBucket: "clickandjoin-69e74.appspot.com",
messagingSenderId: "75683497512",
appId: "1:75683497512:web:57b0e0446813fe51e7971d"
};
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
onMessage(messaging, (payload) => {
console.log('Message received. ', payload);
// ...
});
export const fetchToken = () => {
return getToken(messaging, {vapidKey: 'BL2-7Yy5V2zFfncPROkOaRIoZ1vM_upD4slahvEv8t6HnwtkOSPQdTtfzmrzLKHcMsBp14h_BVRog100FWORwLM'}).then((currentToken) => {
if (currentToken) {
console.log('current token for client: ', currentToken);
test(currentToken)
// this token must be sent to the backend
// Track the token -> client mapping, by sending to backend server
// show on the UI that permission is secured
} else {
console.log('No registration token available. Request permission to generate one.');
// shows on the UI that permission is required
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// catch error while creating client token
});
}
export const onMessageListener = () =>
new Promise((resolve) => {
onMessage(messaging, (payload) => {
resolve(payload);
});
});
function test(t) {
console.log("test")
fetch("https://alpha-api.clickandjoin.umbach.dev/v1/a/" + t, {
method: "GET",
headers: {
"X-AUTHORizatioN": "testa"
}
})
.then((response) => response.json())
.then((data) => console.log(data))
}

13
fcm-client/src/index.css Normal file
View File

@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

17
fcm-client/src/index.js Normal file
View File

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// <React.StrictMode>
<App />
// </React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

1
fcm-client/src/logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background-color: black;
color: white;
}
</style>
</head>
<body>
<label>Select image to upload</label>
<input type="file" name="myFile" id="fileinput">
<br><br>
<span id="res-url">Upload file to see url</span>
<button id="btn-open">Open in new tab</button>
<script>
//const url = "http://localhost:8081/v1/user/avatar"
const url = "https://alpha-storage.clickandjoin.umbach.dev/v1/user/avatar"
const input = document.getElementById("fileinput")
const upload = (file) => {
const data = new FormData()
data.append("file", file)
fetch(url,{
method: "POST",
headers: {
"X-Authorization": "SpebbxEG-gOTn-C7z6-SvO3-UCtv9ZRleg3r"
},
body: data
})
.then(res => res.text())
.then(succ => {
console.log(succ)
let json = JSON.parse(succ)
document.getElementById("res-url").innerHTML = json["AvatarUrl"]
window.open(document.getElementById("res-url").innerHTML, "_blank")
})
.catch(err => console.log(err))
}
const onSelectFile = () => upload(input.files[0])
input.addEventListener("change", onSelectFile, false)
document.getElementById("btn-open").onclick = () => {
window.open(document.getElementById("res-url").innerHTML, "_blank")
}
</script>
</body>
</html>

59
rsa/rsa-test.js Normal file
View File

@ -0,0 +1,59 @@
const crypto = require('crypto')
// https://stackoverflow.com/questions/11449577/why-is-base64-encode-adding-a-slash-in-the-result
// plus and slash must be replaced with another character to ensure URL correctness. Will be replaced again on the api server to the old characters
function base64url_encode(s) {
return s.replaceAll("+", "-").replaceAll("/", "_")
}
function encryptMessage(checkMessage) {
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa',
{
modulusLength: 2048,
publicKeyEncoding: {type: 'pkcs1',format: 'pem'},
privateKeyEncoding: {type: 'pkcs1', format: 'pem'}
});
console.log(publicKey)
const b64PublicKey = Buffer.from(publicKey).toString('base64')
console.log("-------------------------")
console.log("PUBLIC KEY:", b64PublicKey)
console.log("-------------------------")
// encrypt message
const encryptedCheckMessage = crypto.privateEncrypt(privateKey, checkMessage)
const encryptedBase64CheckMessage = encryptedCheckMessage.toString('base64')
const b64CheckMessage = base64url_encode(encryptedBase64CheckMessage)
console.log("ENCRYPTED B64 CHECK MESSAGE:", b64CheckMessage)
console.log("-------------------------")
// testing decryption
const decrB64 = Buffer.from(encryptedBase64CheckMessage, 'base64')
const decr = crypto.publicDecrypt(publicKey, decrB64)
console.log("DECRYPTED MESSAGE:", decr.toString())
// sending request
fetch("http://localhost:8080/v1/user/pkeys",
{ method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-Authorization": "mw7RtGyI-1CZ3-ukNC-YTFp-UCZLvzw5gUQb"
},
body: JSON.stringify(
{
"PKey": b64PublicKey,
"CM": b64CheckMessage
}
)
})
.then((res) => res.json())
.then((data) => console.log(data))
}
encryptMessage("test")

View File

@ -1,58 +0,0 @@
window.onload = () => {
const msg = document.getElementById("msg")
const receiver = document.getElementById("receiver")
document.getElementById("btn-send").onclick = function() {
const chatMsg = {cmd: 2, rec: receiver.value, body: {msg: {"id": "1293", "body": msg.value}}}
ws.send(JSON.stringify(chatMsg))
console.log("Send:", chatMsg, msg.value)
}
document.getElementById("btn-clear").onclick = () => {
msg.value = ""
}
document.getElementById("copy-userid").onclick = () => {
navigator.clipboard.writeText(document.getElementById("userid").innerHTML)
console.log("copied to clipboard")
}
document.getElementById("btn-clear-rec").onclick = () => {
document.getElementById("receiver").value = ""
}
connectWS()
}
let ws = null
function connectWS() {
ws = new WebSocket("ws://localhost:3000/")
ws.onopen = () => {
console.info("ws open", document.getElementById("userid"))
}
ws.onmessage = (msg) => {
console.log("rec msg:", msg.data)
let data = JSON.parse(msg.data)
if (data["Cmd"] == 99999) {
document.getElementById("userid").innerHTML = data["Body"]
}
}
ws.onclose = (e) => {
console.log("ws closed", e.reason)
document.getElementById("userid").innerHTML = ""
setTimeout(() => connectWS(), 1000)
}
ws.onerror = (err) => {
console.warn("err:", err)
}
}

View File

@ -4,19 +4,29 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<title>CnJ</title>
<script src="script.js"></script>
</head>
<body>
<p>WS: <span id="ws"></span> <button id="change-ws">Change WS</button></p>
<p>UserID: <span id="userid"></span> <button id="copy-userid">Copy</button></p>
<br>
<label>Receiver:</label>
<label for="message-receiver">Message receiver:</label>
<select name="message-receiver" id="message-receiver">
<option value="user">User</option>
<option value="room">Room</option>
</select>
<br><br>
<label for="cmd">Cmd:</label>
<input type="number" id="cmd" name="cmd" min="0" max="10000" >
<br><br>
<label for="receiver">Receiver:</label>
<input id="receiver" type="text">
<button id="btn-clear-rec">Clear</button>
<br>
<br>
<label>Chat msg:</label>
<label for="msg">Chat msg:</label>
<input id="msg" type="text">
<button id="btn-send">Send</button>
<button id="btn-clear">Clear</button>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multiple</title>
<script src="script.js"></script>
</head>
<body>
<ul id="ws-list"></ul>
<style>
body {
background-color: black;
color: white;
}
</style>
</body>
</html>

84
ws-sse/multiple/script.js Normal file
View File

@ -0,0 +1,84 @@
/* DEFINITIONS */
const localhost = true
const sseEnabled = false
const wssEnabled = true
let wsPort = 3000
let wsPort2 = 3001
let wsAddressLocal = "ws://localhost:"
const wsAddressServer = "wss://alpha-ws.clickandjoin.umbach.dev"
/* DEFINITIONS END */
let wsList;
window.onload = () => {
wsList = document.getElementById("ws-list")
if (localhost) {
wsAddress = wsAddressLocal
} else {
wsAddress = wsAddressServer
}
wsClient(wsPort)
wsClient(wsPort2)
wsClient(wsPort)
wsClient(wsPort2)
wsClient(wsPort)
wsClient(wsPort2)
}
let count = 0
function wsClient(wsPort) {
let li = document.createElement("li")
li.id = "client-" + count
li.innerHTML = "Client: " + count + " "
let sp = document.createElement("span")
sp.id = "client-userid-" + count
li.appendChild(sp)
wsList.appendChild(li)
if (localhost) {
wsAddress = wsAddressLocal + wsPort
}
let c = count
ws = new WebSocket(wsAddress + "/?auth=WAZgOGzc-g5VC-zbav-KxCT-bCNlFfQk6ptl")
ws.onopen = () => {
console.info("ws open " + c)
}
ws.onmessage = (msg) => {
console.log("rec msg:", msg.data)
let data = JSON.parse(msg.data)
// Only used here to test whether messages can be sent between the servers
if (data["Cmd"] == 99999) {
document.getElementById("client-userid-"+c).innerHTML = data["Body"]
}
}
ws.onclose = (e) => {
console.log("closed", e.reason.code)
if (e.reason.code === 1005) return
console.log("ws closed", e)
document.getElementById("client-userid-"+c).innerHTML = ""
//setTimeout(() => wsClient(), 100)
}
ws.onerror = (err) => {
console.warn("err:", err)
}
count++
}

139
ws-sse/script.js Normal file
View File

@ -0,0 +1,139 @@
/* DEFINITIONS */
const localhost = true
const sseEnabled = false
const wssEnabled = true
let wsPort = 3000
let wsAddressLocal = "ws://localhost:"
const wsAddressServer = "wss://alpha-ws.clickandjoin.umbach.dev"
const sseAddressLocal = "http://127.0.0.1:3005/"
const sseAddressServer = "https://alpha-sse.clickandjoin.umbach.dev/"
/* DEFINITIONS END */
let ws = null
let sseAddress, wsAddress = "";
window.onload = () => {
if (localhost) {
sseAddress = sseAddressLocal
wsAddress = wsAddressLocal
} else {
sseAddress = sseAddressServer
wsAddress = wsAddressServer
}
const msg = document.getElementById("msg")
const receiver = document.getElementById("receiver")
const messageReceiver = document.getElementById("message-receiver")
const cmd = document.getElementById("cmd")
cmd.value = 2
document.getElementById("btn-send").onclick = function() {
const chatMsg = {cmd: parseInt(cmd.value), body: {test: msg.value}}
messageReceiver.value == "user" ? chatMsg.rec_user = receiver.value : chatMsg.rec_room = receiver.value
console.log("messageReceiver", messageReceiver.value)
ws.send(JSON.stringify(chatMsg))
console.log("Send:", chatMsg, msg.value)
}
document.getElementById("btn-clear").onclick = () => {
msg.value = ""
}
document.getElementById("copy-userid").onclick = () => {
navigator.clipboard.writeText(document.getElementById("userid").innerHTML)
console.log("copied to clipboard")
}
document.getElementById("btn-clear-rec").onclick = () => {
receiver.value = ""
}
document.getElementById("change-ws").onclick = () => {
wsPort === 3000 ? wsPort = 3001 : wsPort = 3000
if (ws.readyState == 1) {
ws.close()
}
}
connectWS()
connectSSE()
}
function connectSSE() {
if (!sseEnabled) return
var source = new EventSource(sseAddress)
source.onmessage = (e) => {
console.log(e.data)
let obj = JSON.parse(e.data)
console.log(obj.Body)
}
}
let auths = [
"WAZgOGzc-g5VC-zbav-KxCT-bCNlFfQk6ptl",
"AdZ23xwZ-EhNl-vbbh-I3j3-BlCqsSRYjRM5",
"yq2DjCWN-wdtj-pPRx-CAfL-YbfDb113nEIX",
"cKagUAi2-y0jf-uWax-kDj5-rMOnwl41TA8l",
"hKJrICzW-fgw1-kgUw-k7hG-2de2rroaXEo3",
"z8NJ0VOw-U35X-Yl3W-tusq-MbS2coW2eQRi"]
function connectWS() {
if (!wssEnabled) return
let s = parseInt(window.location.search.split("=")[1]) // ?s=NUMBER_OF_PREFERED_WS_SESSION
let auth;
s == undefined || s > (auths.length - 1) ? auth = auths[0] : auth = auths[s]
if (localhost) {
wsAddress = wsAddressLocal + wsPort
}
ws = new WebSocket(wsAddress + "/?auth=" + auth)
ws.onopen = () => {
console.info("ws open", document.getElementById("userid"))
document.getElementById("ws").innerHTML = ws.url
}
ws.onmessage = (msg) => {
console.log("rec msg:", msg.data)
let data = JSON.parse(msg.data)
// Only used here to test whether messages can be sent between the servers
if (data["Cmd"] == 99999) {
document.getElementById("userid").innerHTML = data["Body"]
}
}
ws.onclose = (e) => {
console.log("closed", e.reason.code)
if (e.reason.code === 1005) return
console.log("ws closed", e)
document.getElementById("userid").innerHTML = ""
setTimeout(() => connectWS(), 100)
}
ws.onerror = (err) => {
console.warn("err:", err)
}
}