unix sockets on nodeJs - javascript

Quick and basic nodeJs question,
I'm working with unix socket for inter-server communication between c++ application and my NodeJs server,
I've wrote my nodeJs server like so:
var net = require('net');
var unixSocketServer = net.createConnection('/tmp/unixSocket');
unixSocketServer.on('connect',function(){
console.log('unix server socket connected on /tmp/unixSocket');
...
});
However I'm getting connection refuse error.
I can understand that the c++ application haven't opened/connected to the socket yet.
My questions are
why does it matter? shouldn't the nodeJs server wait until 'connect' event emitted?
Am I using nodeJs currently? am I missing something?

Ok, so there's some misunderstanding here. Let's start from what a 'unix socket' really is. I think you're thinking it's just a file-like item that acts like a server on its own through the OS/filesystem. That's not quite correct. While it is indeed bound through the filesystem, it isn't really a traditional file. Instead, it's just like an TCP/IP socket, except instead of binding an IP and port, a filepath is bound.
The key point there is that it's just a bound socket with a different type of address (and some extra capabilities, but that's outside the scope here). So that means that something has to bind the socket! In this case, we need a server, just like we would if we were communicating over a 'normal' port. If there isn't a server bound to the path, you get an error, just like you would when connecting to a port with no listener.
To create a server on a unix domain socket in node, it's pretty simple:
'use strict';
const net = require('net');
const unixSocketServer = net.createServer();
unixSocketServer.listen('/tmp/unixSocket', () => {
console.log('now listening');
});
unixSocketServer.on('connection', (s) => {
console.log('got connection!');
s.write('hello world');
s.end();
});
Note that there is one other difference between 'normal' sockets and unix domain sockets: After a server is done with the unix domain socket, it is not automatically destroyed. You must instead unlink /tmp/unixSocket in order to reuse that 'address'/path

Related

Socket IO keeps disconnecting and reconnecting

I'm very very new to sockets and socket.io, so I apologize if this is an obvious question. I'm using the C# client for Socket.IO and have a local javascript server running. Here is my app.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket) {
console.log('A user connected');
socket.on('test', function () {
console.log('Test run'); });
socket.on('disconnect', function () {
console.log('A user disconnected'); });
});
http.listen(3000, function() {
console.log('listening on localhost:3000'); });
In my main C# class (it is a Windows Forms application) the only line of code I have relating to the sockets at all is the instance variable private Socket socket = IO.Socket("http://localhost:3000/");. Yet for some reason, the server repeatedly receives the connect and disconnect events. Here is a screenshot of my console:
screenshot
This all happens automatically, as soon as I run my C# program, without any interaction, and stops as soon as I close it. Any ideas as to why it keeps connecting/disconnecting?
EDIT: For whatever reason the problem seems to go away when I remove Newtonsoft.json from the project. However, without it I cannot use the Emit function as well as others. Is there a workaround to this?
To anyone encountering this issue, check if client & server speak the same protocol version.
On a high-level, this is likely to be caused by protocol version mismatch between server and client. I've had the same issue in JS app. Turned out I was using some older version of socket.io on the client and the latest on the server. In the repository you provided we can find:
// EngineIoClientDotNet/Src/EngineIoClientDotNet.mono/Parser/Parser.cs
public static readonly int Protocol = 3;
So this (now deprecated) client is using Engine.IO protocol v3. You didn't provide info which socket.io version you were using on the server, but it simply might've been using different revision on Engine.IO protocol.
As a side note, speaking more low-level: I guess that the client might be able to connect, but it does not respond to server's first ping command in a proper way (or the other way around). Therefore the connection is immediately dropped. Socket.IO has a history of breaking changes in how ping-pong mechanism is implemented, and this might be the underlying root cause.

How to receive data in real time from TCP socket using PHP or JS? [duplicate]

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.
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!");
});
});
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
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
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)
}
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>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
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.
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
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
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.
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

socket.io confusion with express.js

server side code:
var server = require("http").Server(express);
var io = require("socket.io")(server);
server.listen(5000);
io.on('connection', function(client) {
client.on('order', function(data) {
io.emit('place_order',data);
});
});
cilent side code
var socket = io.connect('http://localhost:5000');
socket.on('place_order', function (data) {alert('data.x')})
Somewhere in github I git clone a project and I saw something above. The 3rd line of server side code confused me. Why the author created extra port here? isn't it ok to discard the 3rd line and in the cilent side just connect to the path without port like var socket = io.connect('http://localhost:5000');? Need explanation for socket.io expert here, I'm confused.
btw this code does work..
Why the author created extra port here?
You have to start your server on some port and server.listen(nnn) is one way to do that. If you don't start your server, it isn't actually running and you can't ever connect to it.
Servers must be created and then started on a specific port.
In your particular code example, you've chosen to run your server on port 5000 instead of the more common port 80.
isn't it ok to discard the 3rd line
No. Without it your server will not be running.
If your server is started on port 80, then you don't have to list a port number in the URL since that is the default port number for an http:// connection.
After attaching your socket.io to an HTTP server, it needs to start. This how socket works. Thats what the 3rd line does. So, removing it means you are not starting the server itself, and obviously that wouldn't work.
The port is at 5000 which might look unconventional to you, but this is a standard practise to prevent errors if the PORT 80 is in use, like it often is by other web/internet based applications/servers. But, if that isn't the case feel free to change the port to 80 by replacing the 3rd line as server.listen(80);
For Ref: if you get the error: Error: listen EADDRINUSE :::80 then understand directly that the port wasn't free!!
That is not a socket.io's problem. In a Node.js application you need to specify which port do you want your Node.js runs.
Node.js is a plataform and in the first line you create a server and for that you need to put the port that your server runs.
https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_http

Jetty Web Socket Timeout

I am trying to establish a Web Socket Connection using Jetty 9.3.0 RC.
function checkDetails(port) {
var ws = new WebSocket("ws://localhost:9995/application");
ws.onopen = function(event) {
console.log("onopen called...");
}
ws.onerror = function(event){
console.log('onerror called...');
}
ws.onmessage = function(event) {
console.log("onmessage called..." + event.data);
}
ws.onclose = function(event) {
console.log("onclose called..." + port);
console.log(event);
ws.close();
}
}
The code works fine if the port 9995 used for creating the Web Socket connection is not occupied by some other process.
var ws = new WebSocket("ws://localhost:9995/application");
But in case if the port is occupied by some other process, then it keeps on trying to connect with that port until the port is released.
I need to provide a timeout so that if the port does not respond in 3 mins then the Web Socket should release (or stop listening) the port and display a console log.
Please let me know the simplest way to achieve this.
From client side you are connecting to some web socket. If port (9995 in your case) is available to connect to then it means that some program (in server mode) is listening and responding. And does something - answers with some data. So, you can connect to such program if it exists and answers or you cannot if there is no server listener for port 9995. When you say "port is occupied" by some other process that means that this process exist and answers. And this process will respond with whatever it is designed for. So, from client side, all what you do is connect to existing and running process which listens for this port in the server mode. That's it and that's all.
However, if we ignore your comment that OP is only about client side then my first suggestion would be to look on the server configuration and check that it is in multithread mode and can answer and proceed multiple requests at once. What you are describing looks like you have singe thread process which works with only one request and can answer next one when current is finished. That sounds like "process occupied". But since comment insist that we are talking only about client side then this speculation would be unnecessary.

Connecting to TCP Socket from browser using javascript

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.
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!");
});
});
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
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
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)
}
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>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
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.
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
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
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.
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

Categories