151

I have a vb.net application that opens a socket and listens on it.

I need to communicate via this socket to that application using a javascript running on a browser. That is i need to send some data on this socket so that the app which is listening on this socket can take that data, do some stuff using some remote calls and get some more data and put it back on the socket that my javascript needs to read and print it in the browser.

Ive tried, socket.io, websockify but none have proved to be useful.

Hence the question, is what i am trying even possible? Is there a way that a javascript running in a browser can connect to a tcp socket and send some data and listen on it for some more data response on the socket and print it to the browser.

If this is possible can some one point me in the right direction as to which would help me establish the goal.

Darren
  • 68,902
  • 24
  • 138
  • 144
swordfish
  • 4,899
  • 5
  • 33
  • 61
  • 5
    No, you are limited to WebSockets – Bergi Sep 13 '12 at 13:55
  • 2
    @Bergi - HTTP is a protocol over tcp, so why can an HTTP connection be made but not TCP? – AlikElzin-kilaka Jun 26 '14 at 12:38
  • 1
    @kilaka: Because the (standard) APIs available in a browser environment [are limited to those](http://stackoverflow.com/q/10902256/1048572). – Bergi Jun 26 '14 at 12:44
  • Possible duplicate: http://stackoverflow.com/questions/9154035/javascript-tcp-socket-connection/9154046?noredirect=1#comment37905107_9154046 – AlikElzin-kilaka Jul 01 '14 at 10:06
  • 7
    I see a new standard creeping up Javascript's spine: http://www.w3.org/TR/raw-sockets/. – AlikElzin-kilaka Jul 01 '14 at 10:06
  • Chrome extensions can use Salt IO (https://developer.chrome.com/native-client/devguide/coding/nacl_io), but that is being deprecated and not supported in other browsers. – david25272 Sep 05 '17 at 01:32
  • I am curious why websocket talking to the other TCP listeners wasn't workable. It is sort of ugly but better than trying to string it up with regular HTTP. – Samantha Atkins Dec 12 '22 at 00:40

6 Answers6

71

As for your problem, currently you will have to depend on XHR or websockets for this.

Currently no popular browser has implemented any such raw sockets api for javascript that lets you create and access raw sockets, but a draft for the implementation of raw sockets api in JavaScript is under-way. Have a look at these links:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket

Chrome now has support for raw TCP and UDP sockets in its ‘experimental’ APIs. These features are only available for chrome apps and, although documented, are hidden for the moment. Having said that, some developers are already creating interesting projects using it, such as this IRC client.

To access this API, you’ll need to enable the experimental flag in your extension’s manifest. Using sockets is pretty straightforward, for example:

chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
  chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
        chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");         
    });
});
Sam Denty
  • 3,693
  • 3
  • 30
  • 43
Robin Rizvi
  • 5,113
  • 4
  • 27
  • 35
  • What browsers support raw sockets? – AlikElzin-kilaka Jun 27 '14 at 06:19
  • 2
    Any performance increases compared to Websockets and Rawsockets? – NiCk Newman Nov 19 '15 at 12:49
  • 6
    Isn't allowing javascript in Browser to connect to a tcp port, a security hole? Imagine javascript in your firefox/chrome connecting to anything you run locally (say MySQL DB) and publish data to an evil site? – Arun Avanathan Sep 05 '16 at 17:16
  • 1
    @ArunAvanathan whatever you do with ajax you can do with sockets and vise-versa ...no security issue as I think. – Firas Abd Alrahman Aug 20 '17 at 22:49
  • 2
    @FirasAbdAlrahman I think there are various [security policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) governing browser behavior for HTTP/S. So browser socket connection over TCP is not same as HTTP/S. – Arun Avanathan Aug 24 '17 at 03:42
  • 1
    Also, CORS usually prevents Ajax from accessing (for example) content on an intranet. Not sure how this would work with an SQL server. – david25272 Sep 05 '17 at 01:26
  • if this site must declare what sites are in whitelist in HTTP header and all scripts downloaded via HTTPS, it is not a problem. it must use whitelist in HTTP headers during loaded a JavaScript. – Daniel Yang Jan 12 '22 at 13:16
  • Did this ever make its way into any browsers in a production state or did it get abandoned? The Mozilla link no longer works. – Emperor Eto Mar 30 '22 at 17:11
  • So much of modern GUI going to web tech has unintended consequences of limiting the ports you can use to talk to the rest of your application? Nasty. – Samantha Atkins Dec 12 '22 at 00:37
  • It seems like the Direct Sockets API is the next attempt to add TCP/UDP support (April 2023): https://wicg.github.io/direct-sockets/ There is even a demo app: https://github.com/GoogleChromeLabs/telnet-client However, Mozilla doesn't want to implement this API because of security considerations: https://github.com/mozilla/standards-positions/issues/431 – linuskmr Jul 21 '23 at 18:38
32

This will be possible via the navigator interface as shown below:

navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
  () => {
    // Permission was granted
    // Create a new TCP client socket and connect to remote host
    var mySocket = new TCPSocket("127.0.0.1", 6789);

    // Send data to server
    mySocket.writeable.write("Hello World").then(
        () => {

            // Data sent sucessfully, wait for response
            console.log("Data has been sent to server");
            mySocket.readable.getReader().read().then(
                ({ value, done }) => {
                    if (!done) {
                        // Response received, log it:
                        console.log("Data received from server:" + value);
                    }

                    // Close the TCP connection
                    mySocket.close();
                }
            );
        },
        e => console.error("Sending error: ", e)
    );
  }
);

More details are outlined in the w3.org tcp-udp-sockets documentation.

http://raw-sockets.sysapps.org/#interface-tcpsocket

https://www.w3.org/TR/tcp-udp-sockets/

Another alternative is to use Chrome Sockets

Creating connections

chrome.sockets.tcp.create({}, function(createInfo) {
  chrome.sockets.tcp.connect(createInfo.socketId,
    IP, PORT, onConnectedCallback);
});

Sending data

chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);

Receiving data

chrome.sockets.tcp.onReceive.addListener(function(info) {
  if (info.socketId != socketId)
    return;
  // info.data is an arrayBuffer.
});

You can use also attempt to use HTML5 Web Sockets (Although this is not direct TCP communication):

var connection = new WebSocket('ws://IPAddress:Port');

connection.onopen = function () {
  connection.send('Ping'); // Send the message 'Ping' to the server
};

http://www.html5rocks.com/en/tutorials/websockets/basics/

Your server must also be listening with a WebSocket server such as pywebsocket, alternatively you can write your own as outlined at Mozilla

Darren
  • 68,902
  • 24
  • 138
  • 144
  • 29
    To elaborate a bit more on this answer: the server must also be listening with a WebSocket server. WebSockets cannot connect directly to a raw TCP socket. websockify is a tool that acts as WebSocket-to-TCP proxy: it sits on your server and listens for WebSocket connections, and then forwards the WebSocket communication to and from a specified TCP socket. – apsillers Sep 13 '12 at 14:02
  • 69
    This does **not answer the question** - websocket is a protocol over TCP (like HTTP for example) and not direct TCP communication. – AlikElzin-kilaka Jun 29 '14 at 14:00
  • 1
    but how to put the message in the browser window? :( – shzyincu Aug 18 '16 at 07:08
  • @shzyincu you need DOM manipulation for that and the answer is a bit more involved that a simple comment. you should ask a new question about it – Ciprian Tomoiagă Sep 07 '16 at 12:43
  • @DarrenDavies has youtube implemented websocket? how do their streaming server works? Any idea what would be the case? – user786 Sep 14 '16 at 13:41
  • 4
    This answer is totally wrong and should be deleted. – Brad Jul 31 '18 at 14:26
  • 2
    @Brad this answer helped me and it must have helped some others also having 22 upvotes. – user1378687 Aug 01 '18 at 09:19
  • 5
    `navigator.tcpPermission` is an abandoned proposal. You can read it on w3 link: `This document was produced by the System Applications Working Group. Members of this Working Group have agreed not to progress the TCP UDP Sockets API specification further as a Recommendation track document, electing instead to publish it as an informative Working Group Note under a permissive license with a view to enabling it to form the basis of further work by others, e.g. in a W3C Community Group.` – macabeus Jan 19 '20 at 01:41
  • You can also read about this (discontinued) proposal here: https://www.w3.org/2012/sysapps/tcp-udp-sockets/ – macabeus Jan 19 '20 at 01:46
8

ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.

ws2s schematic diagram

enter image description here

code sample:

var socket = new WS2S("wss://ws2s.feling.io/").newSocket()

socket.onReady = () => {
  socket.connect("feling.io", 80)
  socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}

socket.onRecv = (data) => {
  console.log('onRecv', data)
}
chenyan
  • 81
  • 1
  • 3
5

See jsocket. Haven't used it myself. Been more than 3 years since last update (as of 26/6/2014).

* Uses flash :(

From the documentation:

<script type='text/javascript'>
    // Host we are connecting to
    var host = 'localhost'; 
    // Port we are connecting on
    var port = 3000;

    var socket = new jSocket();

    // When the socket is added the to document 
    socket.onReady = function(){
            socket.connect(host, port);             
    }

    // Connection attempt finished
    socket.onConnect = function(success, msg){
            if(success){
                    // Send something to the socket
                    socket.write('Hello world');            
            }else{
                    alert('Connection to the server could not be estabilished: ' + msg);            
            }       
    }
    socket.onData = function(data){
            alert('Received from socket: '+data);   
    }

    // Setup our socket in the div with the id="socket"
    socket.setup('mySocket');       
</script>
AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
1

In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):

  1. Bridge app that sits on the client's machine and can deal with both TCP/IP sockets and WebSockets. It will interact with the TCP/IP socket in question.

  2. Server-side app (such as a JSP/Servlet WAR) that can talk WebSockets. It includes at least one HTML page (including server-side processing code if need be) to be accessed by a browser.

It should work like this

  1. The Bridge will open a WS connection to the web app (because a server can't connect to a client).
  2. The Web app will ask the client to identify itself
  3. The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
    1. The browser-viewable page connects to the WS server using JS.
    2. Repeat step 3, but for the JS-based page
    3. The JS-based page sends a command to the server, including to which bridge it must go.
    4. The server forwards the command to the bridge.
    5. The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
    6. The Bridge sends a response to the server through the WS
    7. The WS forwards the response to the browser-viewable page
    8. The JS processes the response and reacts accordingly
    9. Repeat until either client disconnects/unloads

Note 1: The above steps are a vast simplification and do not include information about error handling and keepAlive requests, in the event that either client disconnects prematurely or the server needs to inform clients that it is shutting down/restarting.

Note 2: Depending on your needs, it might be possible to merge these components into one if the TCP/IP socket server in question (to which the bridge talks) is on the same machine as the server app.

Agi Hammerthief
  • 2,114
  • 1
  • 22
  • 38
0

The solution you are really looking for is web sockets. However, the chromium project has developed some new technologies that are direct TCP connections TCP chromium

Sdedelbrock
  • 5,192
  • 1
  • 18
  • 13