Can I connect to socket.io server using generic method? - javascript

I have a node.js server and I attached socket.io listener to it. The code is like this.
const server = new Hapi.Server();
server.connection({
"port": config.port
});
let io = socketio(server.listener);
io.on("connection", function(socket) {
console.log("A user connected");
socket.on("disconnect", function(){
console.log("A user disconnected");
});
// receive message from client
socket.on("client-server", function(msg) {
console.log(msg);
});
});
// somewhere to emit message
io.emit("server-client", "server to client message");
Normally I use the standard way to connect to the websocket server. An example is like this:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('server-client', function(data) {document.write(data)});
socket.emit('client-server', 'test message');
</script>
<body>Hello world</body>
</html>
It works without issue. Now, my colleague wants to connect to the websocket server from his FME server. Based on his research, the only way he can use to connect to a websocket server is using a url like this:
ws://localhost:3000/websocket
My question is: is there a way to connect to socket.io server listener using this type of string?
If not, is there a way to create a websocket server with ws://host:port url and also attach it to my node.js server?
Or, is there a way to connect to socket.io listener in FME server?

To tell Socket.IO to use WebSocket only, add this on the server:
io.set('transports', ['websocket']);
And on the client add this:
var socket = io({transports: ['websocket']});
Now you can only connect to the WebSocket server using ws protocol.

Related

Does socket IO need to serve HTML to work?

So, I am quite puzzled. I have a socket IO server that runs OK, and the HTML web client does connect to it. But, I can't emit anything. I'm using xampp to serve webpages, but does socket IO need to serve content for it to receive and send data? It's weird that I connect OK,but that's it, no emit function works.
Here's my code..
var io = require('socket.io')();
io.on('connection', function(client){ console.log("Connected OK."); io.emit('message',"data"); });
io.on('message', function(client){ console.log(client); });
io.listen(8080);
HTML
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = io.connect('http://localhost:8080');
// Add a connect listener
socket.on('connect', function() {
alert('Client has connected to the server!');
});
socket.on('message', function(event) {
console.log('Received message from client!', event);
});
</script>
The code above prints "Connected OK" to the NPM console, and it alerts "Client has connected to the server!", but that's it. So my question is, does the NPM server need to serve the HTML to work, or am I doing things wrong?. I use xampp because of PHP and MySQL.
UPDATE:## The server sends to client just fine, and the client tries to send data back, and the server receives the packet. But then it reports: " engine:polling transport discarded - closing right away +0ms". Is this normal?

socket.io not emitting event from server to client on connection

I have a very basic setup with socket.io but am having trouble getting my server to send back a message once the connection has been established.
When a connection is established to my server, I want the server to send back a message to the client. I've tried to accomplish this with the following code:
Server
// Modules
var fs = require('fs');
var https = require('https');
// Certificate
var options = {
pfx: fs.readFileSync('<my cert>')
};
// Create Server
httpsServer = https.createServer(options);
// Create websocket
var io = require('socket.io')(httpsServer);
// Listen on a port
httpsServer.listen(4000,function() {
console.log('listening on *:4000');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.emit('test','you connected');
});
Client
var socket = io('https://<my server>:4000');
When I execute this code, the websocket gets established and my server console shows the message "a user connected". However, the message ['test','you connected'] does not get emitted through the socket.
The only way I've been able to get this to work is to use setTimeout() to wait 500ms before emitting the event, in which case it does work.
Why is that? How can I configure my server to automatically respond with a message as soon as the user connects?
You need to listen to the emitted event, using socket.on(event, callback);
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var socket = io('https://localhost:4000');
//test is the emitted event.
socket.on("test", function(data){
console.log(data); //"you connected"
});
</script>

Why node.js requires an upgrade while trying to run an application on the localhost?

When I try to run my node.js application on a localhost server, it does not run and demands a required upgrade. I have tried to run the code but I get the following error:
server code
var WebSocketServer = require('ws').Server,
ws = new WebSocketServer({port: 80}),
CLIENTS=[];
**new connection etablished**
ws.on('connection', function(conn) {
CLIENTS.push(conn);
conn.on('message', function(message) {
console.log('received: %s', message);
sendAll(message);
});
console.log("new connection");
conn.send("NOUVEAU CLIENT CONNECTE");
**if you close connection**
conn.on('close', function() {
console.log("connection closed");
CLIENTS.splice(CLIENTS.indexOf(conn), 1);
});
});
**send messeages vers all clients**
function sendAll (message) {
for (var i=0; i<CLIENTS.length; i++) {
var j=i+1;
CLIENTS[i].send("Message pour le client "+j+": "+message);
}
}
client code
<p>
Result :<output name="" type="text" id="result" value"readonly"></output>
</p>
<input type="text" onchange="ws.send(this.value);">
</body>
<script>
var ws =new WebSocket('ws://localhost:80');
ws.onmessage=function(event){
document.getElementById("result").value=event.data;
}
</script>
Upgrade Required is a reference to the header that is sent when establishing a WebSocket connection between a client (i.e. the browser) and the server.
Like #Prinzhorn stated in his comment, you need a client application that connects to your WebSockets server, which could be a static html page. I recommend you reading this introduction to websockets to understand better how WebSockets work.
Do not open a client HTML file as a localhost URL but open the file directly.
After running your web-socket server,
localhost:[port]/client.html -> you will get the message "upgrade required".
file:///[folder]/client.html -> you can see your HTML file.
because you don't have any web-server with a web-socket or you did not configure your web server for your web-socket. So, you should use your file system.
The easiest way is to use right click on the client file and open it with your favorite browser.
You need to combine your WebSocket based server and static html generator Express.
For example
var express = require('express')
var expressWs = require('express-ws')
var app = express()
expressWs(app)
app.ws('/echo', (ws, req) => {
ws.on('connection', function (connection) {
//...
})
ws.on('close', function () {
//...
})
})
app.use(express.static('public'))
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
In client code
var ws = new WebSocket('ws://localhost:3000/echo');
ws.onmessage=function(event){
document.getElementById("result").value=event.data;
}
The issue is that your web socket server is running on port 80, so when you open the html template using your browser, you are actually opening the web socket server. This is because web pages opening in the browser default to using port 80.
To fix this set your web socket server's port to something else like 3000.
ws = new WebSocketServer({port: 3000})
Then when you open the page in the browser it will open the actual html page instead of the web socket server.

Socketio send message to specific client in namespace

server side:
io.of('/lobby').on('connection', function(client) {
setInterval(function(){
io.to(client.id).emit('message','test');
},2000);
});
client side:
var ioLobby = io.connect('127.0.0.1:9001/lobby');
ioLobby.on('message',function(data){
console.log(data);
});
I'm trying to send a message to a specific client in socket.io version 1.2.1. I've verified that the socket joins the default room on the server side, but its not being triggered on the client side. Any ideas?
The line io.to(client.id) will only work if that user has first joined a room with that same name. You need something like
io.on('connection', function(socket){
socket.join('some room');
});
and then you can call io.to
io.to('some room').emit('some event'):
I compromised and ended up using
socket.emit()
The only downside in comparison is requiring a ref to the socket you're emitting to.

socket.io - 'connect' event does not fire on the client

I am trying to get started with node.js and socket.io.
I have a very (very) simple client-server test application and i can't get it to work.
The system is set up on a windows machine with an apache server.
The apache is running on port 81 and the the socket.io is set up to listen to port 8001
Server - server.js
var io = require('socket.io').listen(8001);
io.sockets.on('connection', function (socket) {
console.log('\ngot a new connection from: ' + socket.id + '\n');
});
Client - index.html
<!DOCTYPE html>
<html>
<head>
<title>node-tests</title>
<script type="text/javascript" src="http://localhost:8001/socket.io/socket.io.js"> </script>
<script type="text/javascript">
var socket = io.connect('http://localhost', { port: 8001 });
socket.on('connect', function () {
alert('connect');
});
socket.on('error', function (data) {
console.log(data || 'error');
});
socket.on('connect_failed', function (data) {
console.log(data || 'connect_failed');
});
</script>
</head>
<body>
</body>
</html>
After starting my server using node server.js the standard (expected) output is written to the server console:
info: socket.io started
When I open index.html in the browser (chrome in my case - didn't test on other browsers) the following log is written to the server console:
info: socket.io started
debug: served static content /socket.io.js
debug: client authorized
info: handshake authorized 9952353481638352052
debug: setting request GET /socket.io/1/websocket/9952353481638352052
debug: set heartbeat interval for client 9952353481638352052
debug: client authorized for
got a new connection from: 9952353481638352052
debug: setting request GET /socket.io/1/xhr-polling/9952353481638352052?t=1333635235315
debug: setting poll timeout
debug: discarding transport
debug: cleared heartbeat interval for client 9952353481638352052
debug: setting request GET /socket.io/1/jsonp-polling/9952353481638352052?t=1333635238316&i=0
debug: setting poll timeout
debug: discarding transport
debug: clearing poll timeout
debug: clearing poll timeout
debug: jsonppolling writing io.j[0]("8::");
debug: set close timeout for client 9952353481638352052
debug: jsonppolling closed due to exceeded duration
debug: setting request GET /socket.io/1/jsonp-polling/9952353481638352052?t=1333635258339&i=0
...
...
...
In the browsers console I get:
connect_failed
So it seems like the client is reaching the server and trying to connect, and the server is authorizing the handshake but the connect event is never fired in the client, instead the connect method reaches its connect timeout and max reconnection attempts and gives up returning connect_failed.
Any help\insight on this would be helpful.
Thank you
Make sure that both client and server have same major version of socket.io. For example, combination of socket.io#2.3.0 on server and socket.io-client#3.x.x at client leads to this case and the 'connect' event is not dispatched.
//Client side
<script src="http://yourdomain.com:8001/socket.io/socket.io.js"></script>
var socket = io.connect('http://yourdomain.com:8001');
//Server side
var io = require('socket.io').listen(8001);
io.sockets.on('connection',function(socket) {
`console.log('a user connected');`
});
Client side:
The client side code requests the client version of socket IO from the same file that gives you server side socketIO. Var socket will now have all the methods that are available with socketIO, such as socket.emit or socket.on
Server Side:
same as client side, making the socketIO methods available for use under var io.
Change in the frontend (client):
var socket = io.connect(http://myapp.herokuapp.com);
to
var socket = io.connect();
After many hours of dealing with various clients (Chrome, Firefox browsers and Phonegap app) that did not register connection to the server properly (i.e. the server registered the websocket connection successfully in its logs, but the frontend did not register the connection event), I tried #Timothy's solution from the comments and now everything works again on heroku and on localhost.
With socketio 2.3.0 you have to use socket.on('connect')
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io({
transports: ['polling']
});
console.log("created",socket);
socket.on('connect', function(data){ // <-- this works
console.log("socket ON connect",data);
});
socket.on('connection', function(data){ // <-- this fails
console.log("socket ON connection",data);
});
</script>
Use autoConnect: false option while creating: io(... { autoConnect: false }), subscribe on your events and invoke io.connect().
Try the following:
Change
var socket = io.connect('http://localhost', { port: 8001 });
to
var socket = io.connect('http://localhost:8001');
Try using this:
Server.js
var http = require("http").createServer(), io = require("socket.io").listen(http);
http.listen(8001);
io.sockets.on("connection", function(socket){
console.log("Connected!");
socket.emit("foo", "Now, we are connected");
});
index.html
<script src="http://localhost:8001/socket.io/socket.io.js"></script>
<script>
var i = io.connect("http://localhost:5001");
i.on("foo", function(bar){
console.log(bar);
})
</script>

Categories