I may not be entering the correct search terms but I cannot seem to find good examples that allow my node application to initiate a socket.io client connection to another telnet server (non-node).
Below is my node app trying to connect to a telnet server
var ioc = require('socket.io-client'),
clientSocket = ioc.connect('192.168.1.97', {
port: 23
});
clientSocket.on('connect', function(){
console.log('connected to to telnet');
});
clientSocket.on('connect_error', function(data){
console.log('connection error to telnet');
console.log(data);
});
clientSocket.on('connect_timeout', function(data){
console.log('connection timeout to telnet');
console.log(data);
});
Here is the error I get
connection error to telnet
timeout
connection timeout to telnet
20000
I've telneted directly to the telnet server successfully from the terminal. Bad code?
You can't.
Socket.IO has nothing to do with regular TCP network sockets. Socket.IO is an RPC layer providing web-socket-like functionality over several transports (Web Sockets, long-polling AJAX, etc.). You can't just connect to any server you want, you must connect to a Socket.IO server. Even Web Sockets itself has a whole protocol built on top of HTTP that must be set up.
If you want to connect to an arbitrary server to send/receive data, that connection must be proxied server-side through your Node.js application. Socket.IO is only for communication between a Socket.IO client and a Socket.IO server.
Not Sure if this can be done, but have a look at this package
https://www.npmjs.org/package/node-telnet-client
Related
I am looking to implement real-time updates in my application that has a node.js backend. I want to use socket.io for this and I understand the library that needs to be implemented. However, I already have a node.js server running:
app.listen(process.env.PORT, () => {
console.log("Server is up and running")
})
The question is fairly simple: is it possible to use the same server with the same port to listen for socket.io connections, or should I run this entirely on a different server or just open another port for this? Because what I often see in the examples is that it listens to http. See below.
What I usually see (this example comes from this post)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function () {
console.log('listening on *:3000');
});
Now, if I would use the same server and port, how could I also listen for incoming socket.io requests or emit to its clients? Can I just keep listening with app.listen and will it also connect to socket.io?
In short yes, the socket connection starts as an http request on the same address and port.
The WebSocket protocol was designed to work well with the existing Web
infrastructure. As part of this design principle, the protocol
specification defines that the WebSocket connection starts its life as
an HTTP connection, guaranteeing full backwards compatibility with the
pre-WebSocket world. The protocol switch from HTTP to WebSocket is
referred to as a the WebSocket handshake.
At this point the HTTP connection breaks down and is replaced by the
WebSocket connection over the same underlying TCP/IP connection. The
WebSocket connection uses the same ports as HTTP (80) and HTTPS (443),
by default.
https://websocket.org/aboutwebsocket.html
I'm trying to test a simple socket.io websocket server. The tool I found for testing socket.io in the command line was iocat.
The server:
var io = require('socket.io')(12345);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('test', function(msg){
console.log('test msg: ' + msg);
io.emit('test', 'Test answer');
});
});
I started it with node socket.js command and disabled any web servers running on this machine.
This worked. The server responded ok to the connect and disconnect event but not for the 'test' message:
me#whatever:~/prj/client$ iocat --socketio ws://localhost:12345
> test
> asdfasdf
>
server response:
me#whatever:~/prj/client$ node socket.js
a user connected
user disconnected
a user connected
user disconnected
Any knows why ? I would prefer a command line tester, because I want to put my web server on https, Apache proxy and sub urls. So I want to make sure I baby-step on it and nothing else is interfering.
It appears that you have a socket.io server, but you are trying to use a webSocket command line utility to communicate with it.
A socket.io server does use a webSocket under the covers as the base level transport, but adds an additional layer on top of the webSocket and thus requires a socket.io client to complete the connection and exchange data with a socket.io server.
So:
socket.io server <==> socket.io client
webSocket server <==> webSocket client
So, you need a socket.io client to communicate with your socket.io server or you can dumb your server down to just a webSocket server using any one of several webSocket modules available for nodejs.
New part of the answer, now that the question has morphed into a question about how to use iocat properly.
A socket.io message has two parts to it, the message name and the message data. With your use of iocat, you are sending data only (with a default message name of message). It appears you need to use the -e option to set the message name to 'test' that you want to send. Or change your server to listen to the default message name of message that iocat uses. It is a bit odd that iocat doesn't let you directly specify the message name AND the message data on each transmission.
I am trying to build a command-line chat room using Node.js and Socket.io.
This is my server-side code so far, I have tried this with both http initialisations (with express, like on the official website's tutorial, and without it):
#app = require('express')()
#http = require('http').Server(app)
http = require('http').createServer()
io = require('socket.io')(http)
io.sockets.on 'connect', (socket) ->
console.log 'a user connected'
http.listen 3000, () ->
console.log 'listening on *:3000'
I start this with nodejs server.js, the "Listening on" is showing up.
If I run lsof -i tcp:3000, the server.js process shows up.
However, when I start this client-side code:
socket = require('socket.io-client')('localhost:3000', {})
socket.on 'connect', (socket) ->
console.log "Connected"
No luck... When I run nodejs client.js, neither "connect" events, from server nor client, are fired!
My questions are :
- What am I doing wrong?
- Is it necessary to start a HTTP server to use it? Sockets are on the transport layer, right? So in theory I don't need a HTTP protocol to trade messages.
If this is a server to server connection and you're only making a socket.io connection (not also setting it up for regular HTTP connections), then this code shows the simple way for just a socket.io connection:
Listening socket.io-only server
// Load the library and initialize a server on port 3000
// This will create an underlying HTTP server, start it and bind socket.io to it
const io = require('socket.io')(3000);
// listen for incoming client connections and log connect and disconnect events
io.on('connection', function (socket) {
console.log("socket.io connect: ", socket.id);
socket.on('disconnect', function() {
console.log("socket.io disconnect: ", socket.id);
});
});
Node.js socket.io client - connects to another socket.io server
// load the client-side library
const io = require('socket.io-client');
// connect to a server and port
const socket = io('http://localhost:3000');
// listen for successful connection to the server
socket.on('connect', function() {
console.log("socket.io connection: ", socket.id);
});
This code works on my computer. I can run two separate node.js apps on the same host and they can talk to one another and both see the connect and disconnect events.
Some Explaining
The socket.io protocol is initiated by making an HTTP connection to an HTTP server. So, anytime you have a socket.io connection, there is an HTTP server listening somewhere. That HTTP connection is initially sent with some special headers that indicate to the server that this is a request to "upgrade" to the webSocket protocol and some additional security info is included.
This is pretty great reference on how a webSocket connection is initially established. It will show you step by step what happens.
Once both sides agree on the "upgrade" in protocol, then the protocol is switched to webSocket (socket.io is then an additional protocol layer on top of the base webSocket protocol, but the connection is all established at the HTTP/webSocket level). Once the upgrade is agreed upon, the exact same TCP connection that was originally the incoming HTTP connection is repurposed and becomes the webSocket/socket.io connection.
With the socket.io server-side library, you can either create the HTTP server yourself and then pass that to socket.io or you can have socket.io just create one for you. If you're only using socket.io on this server and not also sharing using http server for regular http requests, then you can go either way. The minimal code example above, just lets socket.io create the http server for you transparently and then socket.io binds to it. If you are also fielding regular web requests from the http server, then you would typically create the http server first and then pass it to socket.io so socket.io could bind to the http server you already have.
Then, keep in mind that socket.io is using the webSocket transport. It's just some additional packet structure on top of the webSocket transport. It would akin to agreeing to send JSON across an HTTP connection. HTTP is the host transport and underlying data format. Both sides then agree to format some data in JSON format and send it across HTTP. The socket.io message format sits on top of webSocket in that way.
Your Questions
Is it necessary to start a HTTP server to use it?
Yes, an HTTP server must exist somewhere because all socket.io connections start with an HTTP request to an HTTP server.
Sockets are on the transport layer, right?
The initial connection protocol stack works like this:
TCP <- HTTP protocol
Then, after the protocol upgrade:
TCP <- webSocket <- socket.io
So after the protocol upgrade from HTTP to the webSocket transport, you then have socket.io packet format sitting on top of the webSocket format sitting on top of TCP.
So in theory I don't need a HTTP protocol to trade messages.
No, that is not correct. All connections are initially established with HTTP. Once the upgrade happens to the webSocket transport, HTTP is no longer used.
I am implementing web server using express module, the web server communicates with the backend server to get the data and send to UI.
Now if due to some reason the backend server does not send any data, then TCP connection does not get closed. How I can implement connection to backend server close after some timeout period?
I am not using socket.io module.
Regards,
-M-
If you are using Socket you can close the server connection using:
socket.on('timeout', function () {
socket.close();
});
You can also:
socket.setTimeout()
socket.setKeepAlive()
I have a desktop app in Adobe Air (flex).
I have used flashSocket.io library in my app to communicate with socket.io on node.js server.
It works perfectly for most of the clients.
But for some random client the flex app is not able to create a connection with the socket.io server. It constantly throws connection error and close error on flex. The clients are not behind any firewalls or proxy server.
The console has warning like
Web Socket Connection Invalid
I guess this for those clients who are not able to connect.
Since its working for majority of the users i don't know where should i look into. Also, i am unable to reproduce this on my side.
Here's the Server Code:
var io = require('socket.io').listen(app);
app.listen(8080, function() {
console.log('%s listening at %s', app.name, app.url);
});
io.configure(function() {
io.set('transports', ['flashsocket']);
io.set('flash policy port', 843);
});
Flex code:
socket = new FlashSocket("http://domain.com:8080/");
socket.addEventListener(FlashSocketEvent.CONNECT, onConnect);
socket.addEventListener(FlashSocketEvent.MESSAGE, onMessage);
socket.addEventListener(FlashSocketEvent.CLOSE, onDisconnect); //only close and connect_error event is always fired for certain clients
socket.addEventListener(FlashSocketEvent.CONNECT_ERROR, onConnectError);
Any help would be highly appreciated.
Use a different port, we're using 443.