Skip to content

Instantly share code, notes, and snippets.

@eletroswing
Created February 17, 2024 00:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eletroswing/eca9027704eddc814b3760c9f6c4dda6 to your computer and use it in GitHub Desktop.
Save eletroswing/eca9027704eddc814b3760c9f6c4dda6 to your computer and use it in GitHub Desktop.
tcp abstration on nodejs
# By Fountai
const { TCP, constants } = process.binding("tcp_wrap");
const { EventEmitter } = require("events");
const { Socket: NTSocket } = require("net");
class Server extends EventEmitter {
constructor() {
super();
this._handle = null;
this._decoder = new TextDecoder();
}
listen(port, address, backlog) {
const handle = new TCP(constants.SERVER);
handle.bind(address || "0.0.0.0", port);
const err = handle.listen(backlog || 511); // Backlog size
if (err) {
handle.close();
throw new Error(`Error listening: ${err}`);
}
this._handle = handle;
this._handle.onconnection = this.onconnection.bind(this);
}
onconnection(err, clientHandle) {
if (err) {
console.error("Error accepting connection:", err);
return;
}
const socket = new NTSocket({ handle: clientHandle });
socket.on("error", () => {
socket.end()
})
socket._handle.onerror = (err) => {
socket.end()
};
socket._handle.onread = (...args) => {
try {
const data = this._decoder.decode(args[0])
this.emit("connection", socket, data);
} catch (error) {
socket.end();
}
}
socket._handle.readStart();
}
close() {
if (this._handle) {
this._handle.close();
this._handle = null;
}
}
}
module.exports = Server;
const server = new Server();
server.on("connection", async (socket) => {
const content = `Hello World!`;
const type = `Content-Type: text/plain\r\nContent-Length: ${content.length + 1}`
const response = `HTTP/1.1 200 OK\r\n${type}\r\n\r\n${content}`;
socket.write(response);
});
server.listen(3000);
console.log("Server listening on port 3000");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment