I'm using Node.js, Socket.io and Websocket.
Every time I emit something, it writes it in my console.log. I emit a lot of stuff so my console.log becomes totally unusable for debugging purposes.
Is there any way to prevent Websocket from writing all emit events on my console?
An example of what is written:
debug - websocket writing 5:::{"stuff...."}
debug - websocket writing 5:::{"more stuff...."}
debug - websocket writing 5:::{"even more stuff...."}
You need set log level option to 0 like this:
var io = require('socket.io').listen(port, host);
io.set('log level', 0);
Related
Focusing on the client side API only (because each server side language will have its own API), the following snippet opens a connection, creates event listeners for connect, disconnect, and message events, sends a message back to the server, and closes the connection using WebSocket.
// Create a socket instance
var socket = new WebSocket('ws://localhost:3000');
// Open the socket
socket.onopen = function(event) {
// Send an initial message
socket.send('I am the client and I\'m listening!');
// Listen for messages
socket.onmessage = function(event) {
console.log('Client received a message',event);
};
// Listen for socket closes
socket.onclose = function(event) {
console.log('Client notified socket has closed',event);
};
// To close the socket....
socket.close()
};
But I am getting an error on executing above snippet:
ReferenceError: WebSocket is not defined
I have gone through various links like https://davidwalsh.name/websocket, on how to implement WebSockets. But none of them are importing any npm package.
Question: So, how to implement WebSockets (client side AngularJS)? What am I missing here?
Try
const WebSocket = require('ws');
var socket = new WebSocket('ws://localhost:3000');
Then
npm i ws
and retry. It's work with my case
I'm leaving this here for people having trouble with the #stomp/stompjs package in a node app.
Add this line:
Object.assign(global, { WebSocket: require('ws') });
also, don't forget to npm install ws
The code you're referencing in your question is client-side code. WebSocket is available directly in browsers.
For your Node.js server-side code, look at the ws NPM package.
So, how to implement WebSockets (client side) on NodeJS?
You don't. Node.js is server-side, not client-side.
When you are trying to run JavaScript, usually, you run it either in Browser or in NodeJS.
Browser and NodeJS are different JavaScript runtime.
WebSocket itself is a application layer protocol, you need to use API to employ it.
Currently(05-Dec-2019),
most browsers support WebSocket API for developer to use WebSocket.
NodeJS does not provide any OOTB API for developer to use WebSocket, you need 3rd lib to use WebSocket (e.g. https://github.com/websockets/ws).
The example you followed is using WebSocket API in browser.
Hope it helps.
I'm making a remote debugging tool for Unity(C#), and I've set up a C# WebSocket server in the game that emits Log messages.
The remote debugging client is in JavaScript, on a page served by an http server also created by the game.
I seem to be running into issues sending messages on some browsers, and I'm not sure why. I am running the websocket server on localhost and running the client locally, and I know that kind of stuff is not really liked by chrome/firefox. But the weird thing is that I'm not getting any hard errors or exceptions. Failures seem to fail silently.
I'm pretty certain that the issue is JS/Browser related as the C# websocket server works and receives connections in all cases.
Anyway, here's the socket part of the JS code:
var socket = null;
var host = "ws://"+window.location.hostname;
var port = 55000;
var url = host+":"+port+"/msg";
function CheckSocketStatus()
{
if(socket!=null){
console.log(socket.readyState);
}
}
function CreateSocket()
{
socket = new WebSocket(url);
socket.onopen = function()
{
// // Web Socket is connected, send data using send()
console.log("Socket Open!");
socket.send("Here's a client message for ya!");
};
socket.onmessage = function (evt)
{
var message = evt.data;
console.log("MSG: " + message);
var obj = JSON.parse(message);
console.log(obj)
console.log(obj.type)
if(obj.type == "log"){
console.log("Recieved Log");
handleLogMessage(obj);
}
};
socket.onerror = function()
{
console.log("Error!");
}
socket.onclose = function(event)
{
// websocket is closed.
console.log(event.code);
console.log("Connection is closed...");
socket = null;
};
}
In all cases, when I call CreateSocket() a socket gets created and successfully connects to the server. I also have that CheckSocketStatus() function which returns "1" after the socket opens (Which should mean open/ready to send/receive). After that, here are the results:
Chrome:
Chrome will immediately close after connecting. The only thing I do in the onopen() function is a console.log() and a send(). If I remove the send() then the socket will stay open. I do not receive any messages from the server.
Firefox:
Firefox will keep the socket open indefinitely even if I call the send() function in onopen(). However, the server does not receive any messages from the client and vice versa. I feel like I managed to it to send client->server earlier but I could not reproduce that while testing for this question.
Microsoft Edge:
Weirdly enough, Edge works just fine. I can receive and send messages. Works exactly as intended.
Node Webkit (nw.js):
I'm also trying to write this as a nw.js app. Predictably, as it's running on chromium (or something googly), it produces the same results as Chrome.
So I'm not really sure what's going on. I'm not really a web programmer so intricate http stuff is not really my forte. I'm really hoping it's just a Local file issue with chrome/firefox and that it'll work fine on those platforms if I'm connecting to an external host. I'll try to test this tomorrow at work with some non-localhost server, and I'll update with my findings.
I guess the answer I'm looking for is what these symptoms point to and how I can get chrome/firefox/webkit to work properly.
Also what does Edge do here that the others do not?
Thanks in advance! If you need any more info from me please just ask! I didn't want to overload this question just in case there's a simple answer.
Update:
So I just tried connecting from my laptop to my desktop and the same issues still persist. So to my surprise it's not a local issue. I'm a bit stumped. I might have to look at the server code as well. I've also been told to try to use a wrapper, like socket.io, that might solve some platform dependent issues.I've worked with Socket.io/Unity before but I don't think I was having these issues (I wasn't running a server on the C# side that time, there don't seem to be any good socket.io server implementations on C#, and I'm not sure if socket.io interfaces with normal websockets). So that might point to a problem with my implementation on the C# side.
So I figured it out, thanks to gman. I looked at some of his code and noticed that he used a setting in his WebSocketBehavior class called "Ignore Extensions".
The websocket-sharp documentation has this to say:
"If it's set to true, the service will not return the Sec-WebSocket-Extensions header in its handshake response."
"I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error."
So I guess that that header did not jive well with Chrome/Firefox. I'm still doing some testing but this solved the behavior I was seeing with those browsers.
So if you get similar errors, do that!
So, I have a Express NodeJS server that is making a connection with another app via an upagraded WebSocket uri for a data feed. If this app goes down, then obviously the WebSocket connection gets closed. I need to reconnect with this uri once the app comes back online.
My first approach was to use a while loop in the socket.onclose function to keep attempting to make the re-connection once the app comes back online, but this didn't seem to work as planned. My code looks like this:
socket.onclose = function(){
while(socket.readyState != 1){
try{
socket = new WebSocket("URI");
console.log("connection status: " + socket.readyState);
}
catch(err) {
//send message to console
}
}
};
This approach keeps giving me a socket.readyState of 0, even after the app the URI is accessing is back online.
Another approach I took was to use the JavaScript setTimout function to attempt to make the connection by using an exponential backoff algorithm. Using this approach, my code in the socket.onclose function looks like this:
socket.onclose = function(){
var time = generateInterval(reconnAttempts); //generateInterval generates the random time based on the exponential backoff algorithm
setTimeout(function(){
reconnAttempts++; //another attempt so increment reconnAttempts
socket = new WebSocket("URI");
}, time);
};
The problem with this attempt is that if the app is still offline when the socket connection is attempted, I get the following error, for obvious reasons, and the node script terminates:
events.js:85
throw er; // Unhandled 'error' event
Error: connect ECONNREFUSED
at exports._errnoException (util.js:746:11)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1010:19)
I also began using the forever node module to ensure that my node script is always running and to make sure it gets restarted after an unexpected exit. Even though I'm using forever, after a few restarts, forever just stops the script anyway.
I am basically just looking for a way to make my NodeJS server more robust and automatically re-connect with another server that may have gone down for some reason, instead of having to manually restart the node script.
Am I completely off base with my attempts? I am a noob when it comes to NodeJS so it may even be something stupid that I'm overlooking, but I have been researching this for a day or so now and all of my attempts don't seem to work as planned.
Any suggestions would be greatly appreciated! Thanks!
Few suggestions
1) Start using domain which prevents your app from an unexpected termination. Ie your app will run under the domain(run method of domain). You can implement some alert mechanism such as email or sms to which will notify when any error occurs.
2) Start using socket.io for websocket communication, it automatically handles the reconnection. Socket.io uses keep-alive heartbeat and continuously polls from the server.
3) Start using pm2 instead of forever. Pm2 allows clustering for your app which improves the performance.
I think this may improve your app's performance, stability and robustness.
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.
I am working on a Node JS + socket.io application.
The entire application works fine, but after about 5 mins the server stops to receive the events that the client triggers. :(
When the events are not triggered, I can see that the server is successfully receiving the heart beat.
debug - got heartbeat packet
debug - cleared heartbeat timeout for client 4cKMC4Iqje-7dDfibJZm
debug - set heartbeat interval for client 4cKMC4Iqje-7dDfibJZm
debug - emitting heartbeat for client 4cKMC4Iqje-7dDfibJZm
debug - websocket writing 2::
debug - set heartbeat timeout for client 4cKMC4Iqje-7dDfibJZm
I am also sure that the client is emitting the messages because, I can see the data being sent in the chrome Developer tools.
Following is the sample data that is being sent
5:::{"name":"ev_SendChatMessage","args":[{"chatMsg":"dgdfsgfs","aID":"10010001835364"}]}
Also, I have checked the results of TCP Dump at the server machine, it is successfully receiving the data packets.
Node version is v0.10.21
socket.io version is 0.9.16
Client Code
var socket;
$(function()
{
// Connect to the Live Proctoring Server.
socket = io.connect('http://autoproc.am.in:8899');
});
function SendChatMsg()
{
// This get called on click of a button
socket.emit( "ev_SendChatMessage", { chatMsg : "textToSend", aID : "123" } );
}
Server Code
var options = {};
var io = require( 'socket.io' ).listen( 8899, options );
// Called when a connection is made with a new Client
function OnConnection ( socket )
{
console.log( "Connection has been made with " + socket.id );
socket.on('ev_SendChatMessage', SendChatMessageFromModerator );
socket.on('disconnect', OnDisconnect );
}
// This stops getting called after some time. In the beginning it is getting called successfully.
function SendChatMessageFromModerator( data )
{
console.log( data );
}
Edit: To be more precise this thing happens only after around receiving 7-8 messages and emitting 7-8 messages.
Edit: I tried to change the transport mechanism from Web Socket to "xhr-polling". Even then I am facing same problem, instead that I can see something worth in the debug.
debug - xhr-polling received data packet 5:::{"name":"ev_SendChatMessage","args":[{"chatMsg":"sfsdfdsfs","aID":"10010001167896"}]}
debug - clearing poll timeout
debug - xhr-polling writing 8::
debug - set close timeout for client JfaWyiP3YqTRmqyzz4z6
debug - xhr-polling closed due to exceeded duration
debug - setting request GET /socket.io/1/xhr-polling/JfaWyiP3YqTRmqyzz4z6?t=1389965419417
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client JfaWyiP3YqTRmqyzz4z6
This clearly shows that data has reached the Node JS application.
I found the solution to my problem..
Problem was that I was creating a database connection pool, but I was not releasing the connections using dbConn.release();
Once the connections in the pool were exhausted the application kept on waiting for the database connection to be fetched from the pool.
In short, Devil was in the details. The details I had not mention in my question. hahaha..!!