Transport Settings in Socket.IO 1.4.x - node.js

I have been tinkering with deployd on Heroku using this gist as a starting point:
https://gist.github.com/facultymatt/5373247
Line 20 of that server.js tries to set transports for socket.io like so:
server.sockets.manager.settings.transports = ["xhr-polling"];
But encounters this error:
Cannot read property 'settings' of undefined.
From research so far it seems this approach is deprecated in socket.io 1.4.5. However, if that's so I am not clear on how I should address this setting.
My question is similar to this one. But differs in that I seek to change the settings once socket.io is already constructed by and attached to an instance of deployd.

Set it on creation:
var server = deployd({
socketIo: {
options: { transports : ['xhr-polling'] }
}
});
Or if you can't do that, change it runtime (this is a hack):
server.sockets.server.eio.transports = ['xhr-polling'];
(This is still supported for backwards compatibility:)
server.sockets.server.set('transports', ['xhr-polling']);

Related

Why isn't my simple socket.io event system working?

I am running into a problem while using socket.io to do some event handling. For some reason, the following code snippet does not handle the event 'update', or any event for that matter. Let me explain the situation.
I have created a file named updates.js to create a socket.io socket variable named socket_8888 that is bound to port 8888. I then use module.exports to make that socket variable available to any other file that imports updates.js using require('updates.js'). I structured my application this way because I need to emit events from several different files.
In app.js:
var updates = require('updates.js');
setTimeout(function() {
updates.regular.on("update", function () {
console.log("Updated.");
})
}, 1000);
setTimeout(
function () {
console.log(updates.regular.eventNames()); // Verifying that there is actually a listener bound to the socket -> prints ['update']
updates.regular.emit("update", 100)
}, 1500);
In updates.js:
var io = require("socket.io");
var socket_8888 = io(8888);
var updates = {
regular: socket_8888
};
module.exports = updates;
However, a few simple tests have uncovered that events are not being handled, and I really cannot figure out why. The word "Updated" should print a second and a half after I run the application using "node www", but it does not.
The reason I started doing this simple testing was because I am trying to revive an old website of mine, but after a couple years, API updates have rendered a lot of my code useless. So I am trying to rebuild. I am not trying to send events between different files on the server. I am only testing the events locally because the events were not firing to the browser client. For this reason, I decided to investigate using this simple test, and it turns out the events can not even be emitted/listened to on the actual server, let alone be handled on a client that is on a whole different network.
I have already verified that the listener is actually binding to the socket. However, I do not know how to check whether or not the socket is actually emitting the event "update".
I have written the listener to bind only after one second because attempting to bind the moment the application starts does not give Express enough time to set everything up. Otherwise, the socket would still be undefined.
I do not get any error messages. The code just does not work as I expected.
I would really appreciate it if the community can tell me why the event 'update' is not being handled.
To include update module (update.js)
Try this
It work's Perfectly
module.exports = updates
var updates = require('./updates');

Socket io in node app on google app engine

I'd like to run a p2p chat written in node js with socket io on GAE.
My app works locally fine but I get error messages when I run it on the GAE servers related to the socket io I think.
Here are the two relevant script tags of my local client.html when running locally:
<script src="/socket.io/socket.io.js"></script>
<!-- <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script> -->
<script type="text/javascript">
// our socket.io code goes here
var socketio = io.connect("127.0.0.1:1337");
socketio.on("message_to_client", function (data) {
to_history(data['message']);
});
function send_message() {
var msg = [document.getElementById("text1").value, user1, uuid];
socketio.emit("message_to_server", {
message: msg
});
}
</script>
I've seen blogs/posts saying that for deployment I need to allow a firewall rule here on SO (which is in place now). I also tried pointing my deployed app to a static external IP like (after making it static in my google cloud console):
var socketio = io.connect('https://104.197.51.XXX')
or to point it to the port 65080 specified in my firewall rule (see documentation by google here:
var socketio = io.connect('https://104.197.51.XXX:65080')
None of this works.
I have the html loaded fine and the jQuery part I have and css is also loading just fine. It's just the socket stuff that I seem to be getting wrong. What do I have to change?
If this is of use, here the app.yaml:
runtime: nodejs
vm: true
Any help is greatly appreciated. Thanks.
Sadly, App Engine just doesn't support websockets (yet). The hack-around you're using is really unreliable for a few reasons:
it makes a direct connection to the instance, which can go down or be recycled at any time
Short of magic hackery, there's really no way to get https going down this route.
In short - this is not production ready. That having been said....
https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/appengine/websockets
That link will show you a working example and instructions of how to set it up.
Instead of that - I'd suggest using pubnub:
https://www.pubnub.com/docs/nodejs-javascript/pubnub-javascript-sdk
It has a really nice API, and is going to be way more reliable than anything you can hack together with App Engine (you know, until we fix this). You can see a few examples that I've done here:
https://github.com/JustinBeckwith/cloudcats/blob/master/web/public/script.js
https://github.com/JustinBeckwith/hatspin/blob/master/public/script.js
I hope this helps!
I also made the similar chat webapp recently and deployed it on heroku (https://chatterboxxx.herokuapp.com). I also used socket.io for this. I am not sure of GAE, but I don't think you need to specify any IP address in your socket.io js code.
I think you should use
var socketio = io();
instead of
var socketio = io.connect("127.0.0.1:1337");
This works well for me.

NodeJS: thrift vs thrift-http package - which one to use?

What is the difference between these two packages to use thrift on NodeJS:
- thrift
- thrift-http
At first glance it appears thrift-http would be needed to use thrift over http but I installed the thrift package and it does have a createHttpConnection method defined in it. Here is sample code I wrote:
var thrift = require('thrift');
var myService = require('./gen-nodejs/MyService');
var transport = thrift.TBufferedTransport;
var protocol = thrift.TBinaryProtocol;
// connect to proxy on 127.0.0.1:8888
var connection = thrift.createHttpConnection('127.0.0.1', 8888, {
transport : transport,
protocol : protocol,
path: 'http://localhost:5331/myhandler',
});
connection.on('error', function(err) {
console.log(err);
});
// Create a client with the connection
var client = thrift.createHttpClient(myService, connection);
console.log('calling getTotalJobCount...');
client.getTotalJobCount(function(count)
{
console.log('total job count = ' + count);
});
But when I run it I get this:
total job count = NULL
This is not as expected as the service returns an integer which cannot appear as NULL in the client callback. I can't find the link now, but yesterday I read somewhere that thrift only supports TJSONProtocol over http. Is that correct even now? And is that the reason why I am seeing a NULL? Also where can I see the source code for thrift in nodejs? This is the first link that appears in Google when searching for "thrift nodejs" and it seems the code is completely outdated.
The thrift package is the one provided by the Apache Thrift project team.
The other one is someone elses package, not related to the "official" sources in any way. After a quick check against the relevant commits, the version of the files seems to be 0.9.3 as well, which is the most recent official release. However, I can't say whether all these files are entirely original, or if they have been modified. You will have to verify that on your own (or just trust that guy).

Websocket server running fine but cannot connect from client (what url should I use?)

OK this is very simple to anyone who's used websocket and nodejs.
I have created a websocket server named ws_server.js and put it in C:\Program Files (x86)\nodejs where I have installed the nodejs framework. I started the server and it is running and it says it's listening on port 8080. So far so good, I have the server running.
Now I simply want to connect to it from client code so that I can do all that lovely stuff about capturing events using event listeners etc. The problem is, embarassingly, I cannot figure out what URL to use to connect to my websocket server.
function init() {
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket("ws://localhost:8080/"); // WHAT URL SHOULD BE USED HERE?
websocket.onopen = function(evt) { alert("OPEN") };
websocket.onclose = function(evt) { alert("CLOSE") };
websocket.onmessage = function(evt) { alert("MESSAGE") };
websocket.onerror = function(evt) { alert("ERROR") };
}
function doSend(message) {
// this would be called by user pressing a button somewhere
websocket.send(message);
alert("SENT");
}
window.addEventListener("load", init, false);
When I use ws://localhost:8080 the only events that trigger are CLOSE and ERROR. I cannot get the client to connect. I must be missing something very simple. Do I need to set up my nodejs folder in IIS for example and then use that as the URL?
Just to reiterate, the websocket server is running fine, I just don't know what URL to use to connect to it from the client.
EDIT: The websocket server reports the following error.
Specified protocol was not requested by the client.
I think I have got it working by doing the following.
var websocket = new WebSocket("ws://localhost:8080/","echo-protocol");
The problem being that I needed to specify a protocol. At least now I get the onopen event. ...if nothing much else
I was seeing the same error, the entire web server goes down. Adding the protocol fixes it but leaves me wondering why it was implemented this way. I mean, one bad request should not bring down your server.
You definitely have to encase it a try/catch, but the example code provided here https://www.npmjs.com/package/websocket (2019-08-07) does not. This issue can be easily avoided.
I just wanted to share a crazy issue that I had. I was able to connect to a websocket of an old version of a 3rd party app in one computer, but not to a newer version of the app in another.
Moreever, even in new computer with the new version of the app, The app was able to connect to the websocket, but no matter what I did, when I tried to connect with my own code, I kept getting the error message that the websocket connection failed
Long story short, They changed an apache configuration that allowed connecting to the websocket via a proxy.
In the old version, apache config was:
ProxyPass /socket/ ws://localhost:33015/ retry=10
ProxyPass /socket ws://localhost:33015/ retry=10
In the new version, apache config was changed to:
ProxyPass /socket/ ws://localhost:33015/ retry=10
By bad luck, I was trying to connect to ws://localhost/socket and not to ws://localhost/socket/. As a result, proxy was not found, and connection returned an error.
Moral of the story: Make sure that you are trying to connect to a websocket url that exists.
For me, the solution was to change the URL from ws:// to wss://. This is because the server I was connecting to had updated its security, and now only accepted wss.

How do I log Socket.io through Winston?

I would like to use Winston as logger for Socket.io. I have seen this issue where it says:
var io = require('socket.io').listen(8080);
io.set('logger', { debug: <log function>, info: … , error: .., warn: .. })
Unfortunately, it is not described what the log function should look like.
Some playing around and a look into the Socket.io logger documentation told me that there is no fixed set of parameters: There are log messages with one, two and three parameters. Perhaps there are even more, I don't know.
I think that this is definitely not a good practice to have an undefined number of parameters, especially if this is your interface to external components.
Anyway ... does anybody have some experience with this? Can anyone point out what to watch out for?
This seems to work fine for me
var io = require('socket.io').listen(server, {
logger: {
debug: winston.debug,
info: winston.info,
error: winston.error,
warn: winston.warn
}
});
As a bonus, by setting the logger in the same call as .listen(), you catch all the log output from Socket.IO. Note that you should be able to just pass winston instead of that object, but it isn't working for me, so that's why I've posted this solution instead.
Since socket.io v1.0 logger parameter does not longer work.
They switched to debug
You may refer to this issue on how to setup Winston with socket.io
You can simply plug in the winston instance as the logger object:
var winston = require('winston');
io.set('logger', winston);

Resources