Websockets: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 174: Line 174:
Javascript is dead - long live the king
Javascript is dead - long live the king
==Setting up Typescript==
==Setting up Typescript==
Found this a bit of challenge first time through but it seems to work. Here is the project setup.
Found this a bit of challenge first time through but it seems to work. Here is the project setup.<br>
[[File:TS Setup Project Structure.png| 600px]]
[[File:TS Setup Project Structure.png| 300px]]<br>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
npm i -D typescript
npm i -D typescript
</syntaxhighlight>
</syntaxhighlight>

Revision as of 21:48, 31 July 2022

Pros and Cons

Pros

  • Full Duplex (no polling)
  • Http compatiable
  • Firewall friendly

Cons

  • Proxy is tricky
  • L7 Load Balancing challenging (timeouts)
  • Stateful, difficult to horizontally scale

Simple JS example

Client

<html>
    <body>
        <script>
            const ws = new WebSocket("ws://localhost:3100")

            ws.addEventListener("open", () => {
                console.log("We are connected")
                ws.send("hello everyone")
            })

            ws.addEventListener("message", (e) => {
                console.log("We have data", e)
            })

        </script>
    </body>
</html>

Server

We need to npm install

  "dependencies": {
    "ws": "^8.8.1"
  }

And run this.

const Websocket  = require("ws")

const wss = new Websocket.Server({port: 3100})

wss.on("connection", ws => {

    console.log("New Client Connected")

    ws.on("message", (data) => {
        console.log("Client Sent", data)
        ws.send(data.toUpperCase())
    }) 

    ws.on("close", () => {
        console.log("Client Disconnected")
    })
})

Another example

This one uses websocket library - npm i websockets

const http = require("http");
const WebSocketServer = require("websocket").server

const port  = 3100
let connection = null;

//create a raw http server (this will help us create the TCP which will then pass to the websocket to do the job)
const httpserver = http.createServer((req, res) =>
    console.log("we have received a request"))

//pass the httpserver object to the WebSocketServer library to do all the job, this class will override the req/res 
const websocket = new WebSocketServer({
    "httpServer": httpserver
})

httpserver.listen(port, () => console.log(`My server is listening on port ${port}`))

//when a legit websocket request comes listen to it and get the connection .. once you get a connection thats it! 
websocket.on("request", request => {

    connection = request.accept(null, request.origin)
    connection.on("open", () => console.log("Opened!!!"))
    connection.on("close", () => console.log("CLOSED!!!"))
    connection.on("message", message => {

        console.log(`Received message ${message.utf8Data}`)
        connection.send(`got your message: ${message.utf8Data}`)
    })

    //use connection.send to send stuff to the client 
    sendevery5seconds();
})

function sendevery5seconds() {
    connection.send(`Message ${Math.random()}`);
    setTimeout(sendevery5seconds, 5000);
}

//client code 
//let ws = new WebSocket("ws://localhost:8080");
//ws.onmessage = message => console.log(`Received: ${message.data}`);
//ws.send("Hello! I'm client")

Bills Server

This is an attempt to manage connections in a server process

let failedConnections = []

class BillsServer {

    constructor() {
        this.index = 0
        this.connections = []
        this.loop()
    }

    addConnection(connection) {

        connection.on("close", () => {
            failedConnections.push(connection.id)
            console.log(`closing socket for ${connection.id}`)
        })

        connection.on("message", message => {
            console.log(`Received message ${message.utf8Data}`)
        })

        this.connections.push(connection)
    }

    loop = () => {
        setInterval(this.process, 5000);
    }

    process = () => {

        console.log("Current connections: ", this.connections.length)
        if(this.connections.length > 0) {

            this.processAll()

            if(failedConnections.length > 0) {
                console.log(`Removing ${failedConnections.length} failed connections`)
                this.connections = this.connections.filter((connection) => !failedConnections.includes(connection.id))
                console.log(`${this.connections.length} Remaining Connections`)
                failedConnections = []
            }
        }
    }

    processAll = () => {
        for(let i = 0; i < this.connections.length; i++) {
            try {
                console.log(`${i.toString()}: Processing connection`,this.connections[i].id)
                this.handleConnection(this.connections[i]) 
            }
            catch(e) {
                console.log(`${i.toString()}: Got an error handling connection`, e ? e : "Unknown error")
            }
        }
    }

    handleConnection = (connection) => {
        console.log("Sending to client", connection.id)
        connection.send(`Sending you greetings`)
    }
}

module.exports  =  BillsServer

Bills Server Typescript

Javascript is dead - long live the king

Setting up Typescript

Found this a bit of challenge first time through but it seems to work. Here is the project setup.

npm i -D typescript