Skip to content

Instantly share code, notes, and snippets.

@Lawlez
Created December 4, 2019 12:30
Show Gist options
  • Save Lawlez/e46d5d4447a016d14df88099a5c585c0 to your computer and use it in GitHub Desktop.
Save Lawlez/e46d5d4447a016d14df88099a5c585c0 to your computer and use it in GitHub Desktop.
React websockets base
import React, {useState, useEffect} from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import Login from './login'
import {w3cwebsocket as W3CWebSocket} from 'websocket'
const client = new W3CWebSocket('ws://localhost:8080')
const Application = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false)
const [userName, setUserName] = useState('username')
const [userActivity, setUserActivity] = useState([])
const [docContent, setDocContent] = useState('')
let dataFromServer
let tempName //temporary uname until sever verifies
client.onopen = () => {
console.log('WebSocket Client Connected to server')
}
client.onclose = () => {
console.log('WebSocket server closing or offline...')
}
client.onmessage = (message) => {
dataFromServer = JSON.parse(message.data)
console.log('im RECIEVING parsed: ', dataFromServer)
if (dataFromServer.type === 'userevent') {
/* ON USEREVENT*/
let index = dataFromServer.data.userActivity.length - 1
console.log(dataFromServer.data.userActivity[index])
let newestActivity = [
...userActivity,
dataFromServer.data.userActivity[index]
]
setUserActivity(newestActivity)
if (tempName === dataFromServer.data.username) {
setUserName(dataFromServer.data.username)
setIsLoggedIn(true)
} else {
setIsLoggedIn(isLoggedIn)
}
}
if (dataFromServer.type === 'contentchange') {
let index = dataFromServer.data.content_length
setDocContent(dataFromServer.data.content[index])
}
}
//todo doc auslagern
const Document = (props) => {
return (
<div className="documentWrapper">
<textarea value={props.docContent}
onChange={(e) => props.handleUserInput(e.target.value)}
className="document" />
</div>
)
}
//todo login auslagern
const Login = (props) => {
return (
<div className="loginWrapper">
<div className="loginInner">
<input
type="text"
value={props.uName}
onChange={(e) => props.handleUserInput(e.target.value)}
/>
<button onClick={props.onSubmit}> Submit </button>
</div>
</div>
)
}
const handleUserNameInput = (e) => {
setUserName(e)
}
const onSubmit = (e) => {
let data = userName
tempName = userName
client.send(
JSON.stringify({
username: data,
type: 'userevent'
})
)
}
const handleUserInput = (e) => {
setDocContent(e)
let data = e
client.send(
JSON.stringify({
username: userName,
type: 'contentchange',
content: data
})
)
}
return (
<div>
<div className="userActivity">
activity: {userActivity[userActivity.length - 1]}{' '}
</div>
{isLoggedIn ? (
<div className="wrapper">
<Document
docContent={docContent}
handleUserInput={(e) => handleUserInput(e)}
/>
</div>
) : (
<Login
onSubmit={() => onSubmit()}
uName={userName}
handleUserInput={(e) => handleUserNameInput(e)}
/>
)}
</div>
)
}
//Render
ReactDOM.render(<Application />, document.getElementById('root'))
const WebSocketSrv = () => {
const webSocketServerPort = 8080
const webSocketServer = require('websocket').server
const http = require('http')
// starting the http server and the websocket server.
const server = http.createServer()
server.listen(webSocketServerPort)
const wsServer = new webSocketServer({httpServer: server})
const clients = {}
const users = {}
let userActivity = []
const editorContent = []
const reqTypes = {
USER_EVENT: 'userevent',
CONTENT_CHANGE: 'contentchange'
}
// generates unique userid for everyuser.
const getUniqueID = () => {
const s4 = () =>
Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1)
return s4() + s4() + '-' + s4()
}
const sendMessage = (json) => {
// We are sending the current data to all connected clients
// TODO for array not obj
Object.keys(clients).map((client) => {
clients[client].sendUTF(json)
})
}
wsServer.on('request', function(request) {
var userID = getUniqueID()
console.log(
new Date() +
' Recieved a new connection from origin ' +
request.origin +
'.'
)
const connection = request.accept(null, request.origin)
clients[userID] = connection
console.log('connected: ' + userID + ' in ' + clients)
connection.on('message', function(message) {
console.log('new Request: ', message)
const dataFromClient = JSON.parse(message.utf8Data)
const json = {type: dataFromClient.type} //prepare answer with same type as request
if (dataFromClient.type === reqTypes.USER_EVENT) { //TODO : chekc if usernam eexists
users[userID] = dataFromClient.username
userActivity.push(
`${dataFromClient.username} joined to edit the document with UID ${userID}`
)
json.data = {'username': users[userID],'user-id': userID, userActivity} //add user +activity to the data of our response
}
if (dataFromClient.type === reqTypes.CONTENT_CHANGE) {
editorContent.push(dataFromClient.content)
json.data = {'username': users[userID],'content': editorContent, content_length: editorContent.length -1}
}
console.log('Message i sent to client: ', json)
sendMessage(JSON.stringify(json))
})
connection.on('close', function(connection) {
console.log(new Date() + ' Peer ' + userID + ' disconnected.')
const json = {type: reqTypes.USER_EVENT}
userActivity.push(`${users[userID].username} left the document`)
json.data = {users, userActivity}
delete clients[userID]
delete users[userID]
sendMessage(JSON.stringify(json))
})
})
}
WebSocketSrv()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment