npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

webtcp

v1.0.0

Published

WebSocket/TCP bridge that allows browsers to interact with TCP servers.

Downloads

10

Readme

WebTCP 1.0.0

Inspired by the original WebTCP: yankov/webtcp

WebTCP allows users to create a raw TCP(With optional SSL support) socket using WebSockets.

Why a new library? The old library is abandoned, has too much functionality for being a raw TCP socket, and the code was hard to understand for me.

How does it work

Client and server (bridge) communicate through a websocket connection. When the browser wants to create a TCP socket it sends a command to the bridge. The bridge creates a real TCP socket connection and maps all the events that happen on this socket to a client's socket object. For example, when data is received bridge will trigger a data event on according socket object on a browser side.

Why would anyone need that

Sometimes an API does not provide a way to communicate through HTTP or WebSockets, in which case you need to resort to raw TCP.

Can I use this in production?

NO. Not without heavy security additions.

This library allows users to leverage your server to create raw TCP sockets. They can literally do anything with that, all using your servers IP.

You would have to limit your users ability to connect to certain servers(options.mayConnect), properly encrypt the traffic both ways, etc.

This library is not battle tested and is primarily used for prototyping by me.

Installing

Assuming you have node.js, npm and git installed:

Add as a dependency for using in your project

npm install webtcp

Clone the repository for testing/contributing

Clone the repo

git clone https://github.com/PatrickSachs/webtcp

Install dependencies

cd webtcp
npm install

Run WebTCP example server

npm run example

Your WebTCP server will now be hosted on localhost:9999.

The library is not published to npm. If you want to use it as a dep in your project you'll have to manually add it to your package.json(See here for details).

How to use it

Client usage

Connect to the server using a WebSocket.

const socket = new WebSocket("localhost", 9999);

This WebSocket is now your TCP socket.

Before we can actually send data we need to connect to a TCP server:

socket.send(JSON.stringify({
  type: "connect",
  host: "localhost",
  port: 8001
}));  

Assuming everything went smooth the bridge will respond with

{
  "type": "connect"
}

Now we are ready to send data:

// Binary payload
socket.send(JSON.stringify({
  type: "data",
  payload: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
}));  
// String payload
socket.send(JSON.stringify({
  type: "data",
  payload: "Hello World"
}));  

We once we are done, let's close the socket again:

socket.send(JSON.stringify({
  type: "close"
})); 

This will also close the websocket.

Events emitted by the bridge

connect

Once we have connected to the server the connect event occurs.

{
  "type": "connect"
}

data

Sent when the socket recceived data.

{
  "type": "data",
  "payload": "<string>"
}

end

Sent when the other end closed the socket by sending a FIN packet.

{
  "type": "end"
}

close

Sent when the socket is closed. If hadError is true an eror event will be emitted aswell.

{
  "type": "close",
  "hadError": "<boolean>"
}

error

Sent when an error occurred. This typically closes the socket.

{
  "type": "error",
  "error": "<string>"
}

timeout

Sent when the socket timed out due to inactivity.

{
  "type": "timeout"
}

Events handled by the bridge

connect

Used to connect to a TCP server.

{
  "type": "connect",
  "host": "<string>",
  "port": "<number>",
  "encoding": "<string>",
  "timeout": "<number>",
  "noDelay": "<boolean>",
  "keepAlive": "<boolean>",
  "initialDelay": "<number>",
  "ssl": "<boolean>"
}

close

Closes the TCP Socket & WebSocket.

{
  "type": "close"
}

data

Sends data. The payload can either be a string on an array of bytes(=numbers).

{
  "type": "data",
  "payload": "<string | number[]>"
}

Manually creating a server

This is pretty much a copy of the example included under /examples/server.js, but it's always nice to see a code example.

As you can see WebTCP integrates seamlessly into express using the express-ws library. You can of course roll your own solution, which would require you to adjust the createConnection function passed in the options to use your WebSocket API.

const webtcp = require("../src");
const express = require("express");
const enableWebsockets = require("express-ws");

const PORT = 9999;

const app = express();
enableWebsockets(app);

// All options are optional. The following values are the default ones.
app.ws("/", ({
  // The options for this webtcp server instance
  debug: false,
  mayConnect: ({host, port}) => true,
  // Creates the connection/session object if you are using a non-default WebSocket implementation.
  createConnection: (ws, _req) => ({
    // Sends a JSON object over the WebSocket.
    send: data => ws.send(JSON.stringify(data)),
    // Checks if the socket is open. If this returns true, the server assumes that calling send will work.
    isOpen: () => ws.readyState === READY_STATE.OPEN,
    // Placeholder for the TCP socket. Simply set this to null unless you need to get really fancy.
    socket: null
  }),
  // The default options for the TCP socket
  defaultTcpOptions: {
    host: "localhost",
    port: 9998,
    ssl: false,
    encoding: "utf8",
    timeout: 0,
    noDelay: false,
    keepAlive: false,
    initialDelay: 0
  }
});
app.listen(PORT, () => console.log(`[webtcp] Running on port ${PORT}!`));

Contributing

Always welcome! Feel free to open issues and PRs as you wish, then we can talk about possible additions/fixes/changes.