Trouble sending TCP message with Socket.io - javascript

So I'm attempting to send a TCP message to a device plugged into my computer, with an IP address of xxx.xxx.1.32 over port 9999 with Socket.io. The client successfully connects to the TCP server running on the device, but I can't seem to send any actual message to it. Here is the output I'm getting from the device:
And my client-side code:
<script src = "https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script>
var socket = io('http://xxx.xxx.1.32:9999');
socket.on('connect', function() {
socket.send('GPIO,00,0');
socket.emit('GPIO,00,0');
socket.on('message', function (msg) {
alert(msg);
});
});
</script>
It periodically receives the same messages detailed in the first picture (which makes sense since the Connection: field is set to keep alive), but it never seems to send the messages, even after first making the connection. Any ideas as to what is going wrong?

Socket.IO doesn't do plain TCP sockets as that is not possible to do in the browser. Instead it uses WebSockets which require a handshake built on top of HTTP (or alternatively some other HTTP-based fallbacks). If you want to talk to your custom device with Socket.IO you'll have to implement their entire protocol by hand.
If you can't or don't want to run node.js on your device, it might be best to forget Socket.IO and just use plain WebSockets. Or even implement a proxy server on a full-fledged computer that can proxy things over plain TCP.

Related

Where does all data send with nodejs method socket.write?

Good day! Where does all data send when nodejs method socket.write is called? I understand that socket runs of the server side for each client. But where exactly does data go? to client? On official nodejs documentanion there is no info about destination. Thank you for response.
You cannot successfully write to a socket unless you (or some part of your nodejs software) first connects it to some other socket somewhere.
A socket server listens for connection requests, and then accepts them as they arrive. (When you use node express to make a web server, express handles this for you.) A client connects to a socket server. Once the pair of sockets are connected, data you write into one of the sockets causes a data event on the other one.
The two sockets may be on different machines in different locations. That's the miracle of global networking.
So where does data you write go? To the other socket in the pair.
If you are using datagrams (not connections) it's slightly different. The data you write contains the destination address. But you probably are not using databgrams. If you are, you are probably using a protocol stack like RTSP or UDP instead of TCP.

Connect two socket.io clients together (Establish a socket to socket, cross browser connection)

I'd like to know if there's any way to establish a P2P connection between two browsers using socket.io-client (but I'm willing to use anything else that may do the trick).
Both browsers are currently connected to a node.js app serving HTTP requests with Express, which stores both clients's IP addresses (and ports when running locally). What I'd like to do is add a third connection that links both clients (let's call them A and B) directly, so that messages/data will go straight from one client to another, without transiting through the node.js server.
Is that feasible? If so, how?
So far, I've tried connecting the two clients (let's call them A and B) with the following code:
Client A:
A_to_server_socket = io();
A_to_server_socket.on('p2p', function(address_B){
A_to_B_socket = io(address_B); // Instantiates a new socket
A_to_B_socket.on('connect', function() {
console.log('Connected!');
});
});
I'm not sure about the code for client B. However I've tried:
repeat the above code for B, using B's own address (to override the default of connecting to the server)
repeat the above code for B, this time using A's address
having B_to_server_socket listen for a new connect event
However regardless of B's code, when running A's code I'm confronted with a "Cross-Origin Request blocked" error on Firefox, or "Failed to load resource: net::ERR_CONNECTION_REFUSED" followed by "net::ERR_CONNECTION_REFUSED" on Chrome.
Any hints towards a solution, or insights for better understanding the problem and how sockets work would be most welcome.
I'll try to summarize my comments into an answer.
In TCP, a connection is made when one endpoint A connects to another endpoint B. To connect to endpoint B, that host must be "listening" for incoming connections originating from other hosts. In a typical web request, the browser establishes a TCP connection to the web server and this works because the web server is listening for incoming requests on a specific port and when one of those requests comes in, it accepts the incoming request to establish an active TCP connection. So, you must have one side initiating the request and another side listening for the request.
For various security reasons, browsers themselves don't "listen" for incoming connections so you can't connect directly to them. They only allow you to connect outbound to some other listening agent on the internet. So, if a browser never listens for an incoming webSocket connection, then you can't establish a true peer-to-peer (e.g. browser-to-browser) webSocket connection.
Furthermore, TCP is designed so that you can't have two browsers both connect to a common server and then somehow have that server connect up their pipelines such that the two browser are now just wired directly to each other. TCP just doesn't work that way. It is possible to have an agent in the middle forwarding packets from one client to another via a separate connection to each (that's how Chat applications generally work), but the agent in the middle can't simply plug the two TCP connections together such that the packets go directly from one client to the other (and no longer go through the server) as a fireman would connect two firehoses. TCP just doens't work that way. It might be possible to have some complicated scheme that involved rewriting packet headers to a packet sent from endPoint A was forwarded to endPoint B and looked like it came from the server instead, but that still involves the server as the middleman or proxy.
The usual way to solve this problem is to just let each browser connect to a common server and have the server act as the middleman or traffic cop, forwarding packets from one browser to another.
Existing P2P applications (outside of browsers) work by having each client actually listen for incoming connections (act like a server) so that another client can connect directly to them. P2P itself is more complicated than this because one needs to have a means of discovering an IP address to connect to (since clients typically aren't in DNS) and often there are firewalls in the way that need some cooperation between the two ends in order to make the firewall allow the incoming connection. But, alas, this capability of listening for an incoming connection is not something a browser from plain javascript will allow you to do.
There is no something like "connection between two browsers using socket.io-client."
But there is "Both browsers are connected to a node.js app serving HTTP requests with Express, which keeps track of both clients's IP addresses (and ports when running locally)."
If you want to have P2P connection between two browser, following may be a way to do so.
when you get client A connection, join to a room "P2P"
when you get client B connection, join to a room "P2P"
to exchange between client A and client B, use
socket.broadcast.to('P2P').emit("message", "Good Morning");
Hope this may help.

how to not expose server info when loading and connecting to socket

I have drupal site that communicates with Node.js server via sockets, so i have the following to load and send connection request in the header:
<script src="http://xx.xx.xx.xx:3000/socket.io/socket.io.js"></script>
...
socket = io.connect('http://xx.xx.xx.xx:3000');
This works well, however. I prefer my server ip and the port number is not exposed to the rest of the world. What is the approach to do so? Thank You
The short answer is :
You can not do this.
The longer explaination :
Your socket.io connection is like any other connection made to your server(s). It will be always visible in the developer tools of any other browser. You might want to use a proxy service for that, but in the end your socket.io server will always be exposed.
Nobody will ever read your JS code if he wants to get your socket.io IP-address, there are many other easier ways to do that.
Although you can always use the autoconnect feature of socket.io and just put
socket = io.connect();

Javascript port access

Can javascript access the system ports ?
If yes, is it possible to write a server (TCP/UDP in C) to which data can be send from javascript ?
Let's assume that you're not asking for Node.js.
You can write WebSocket server in C and connect your JavaScript to it. There are already plenty of implementations so you don't have to write it yourself.
When you start your server and bind it to specific host name and port you can connect from your JavaScript by:
var ws = new WebSocket('ws://hostname:port');
ws.onopen = function () {
console.log('Connected');
};
ws.onmessage = function () {
console.log('New message...');
};
ws.send('Some message...');
For example, here is one http://code.google.com/p/cwebsocket/.
As far as I know WebSocket is over TCP.
One more option is to create HTTP server use AJAX with or without long polling.
What do you mean by "system ports"? Serial ports? AGP ports? Rewrites of an application in a different programming language? There is no such term as "system ports" in general usage. You seem to be referring to sockets.
In which case....
Sort of. You can get a connection to any TCP port using javascript - but you will only be able to communicate over that port using HTTP. It is possible to tunnel communications via websockets - however this requires a proxy at the server end to connect to a conventional server. TCP is a stream protocol but websockets are message oriented.
If you're implementing your own server from scratch, then it's a lot easier to build on top of something which already understands about websockets (such as node.js).
You can't use UDP (other than DNS lookups as a by-product of establishing TCP connections).

Can you connect client to client via web sockets without touching the server?

I don't quite know how to search this in google:
"client to client websocket connections"
"browser to browser websockets"
"websockets without a server"
Haha, is there a way for someone on a webpage in the browser to communicate directly to another person on a web page in the browser, without touching the server?
I am very familiar with socket.io, but that requires all clients emit messages to the server, which can broadcast them to the other connected clients. I am not familiar with the details of web sockets though, so maybe there's a way to communicate without sending messages through the server.
Is this possible? I just want to know the scope of web socket functionality, the limits you can take them too, etc.
Not Web Sockets, but four years later and now we've got browser-to-browser communication!
http://www.webrtc.org/
There are JS libraries built around it to make it easier (e.g. https://simplewebrtc.com/). However, it does still require a server to orchestrate connections.
I know this question is ancient, but it showed up in Google when I searched so it likely will for others!
This is not possible, you have to have the server in the middle.
For an application to accept connections, it has to have a server port open and listening for incoming requests. You cannot have a server socket exposed from a browser. I dont know if you can expose a server socket from within an applet. But even if you could, you would need to know the IP address of the other client for establishing a peer to peer connection.
Well, technically when you broadcast, the client emits to the server, the server broadcasts to everyone. I don't think with the current architecture of the web peer to peer connections like this is possible.
But it is possible that a client send a message to server specifying another client ID, and the server sending it to the other clients using sessions.
The moment you have a client listening for websockets (which you have to do in other to communicate), it becomes a server.

Categories