In order to add a chatting function to my website, I set up a Websocket server using node.js on a Windows 2016 server. I was able to establish a successful connection between my client and server and the application is working pretty smoothly.
However, every once in a while, the connection will appear to freeze and the client will send a message to the socket but the socket seems to be frozen until I refresh it by clicking on the command prompt on my server computer.
At first, I thought it was a connection issue but all the appropriate ports appear to be open and I am convinced that it is a server issue.
I am a beginning coder so I'm sorry if I am not using the proper terminology but help would be much appreciated. If anything is unclear I will add more info.
Thanks!
Related
I have not been able to get an answer to this anywhere online. I want to remove possible jitter from my nodejs server. I am using socket.io to create connections to node.
If a user goes to a specific part of my website, a connection is started. However, if the user refreshes the site too quickly and often, the connection is created very frequently, and issues arise with my server.
While I realized it's possible this could be solved a couple different ways, I am hoping a server solution is out there. Meaning, whenever a user connects, make sure the user is connected for at least 5 seconds. Then move on. Otherwise, disconnect the user. Thanks for any insight!
First off a little background. With a default configuration, when a socket.io connection starts, it first does 2-5 http connections and then once it has established the "logical" connection, it tries to establish a connection using the webSocket transport. If that is successful, then it keeps that webSocket connection as a long lasting connection and sends socket.io packets over it.
If the client refreshes in the middle of the transition to a webSocket connection, it creates a period of unknown state on the server where the server isn't sure if the user is just still in the middle of the transition to a lasting webSocket connection, if the user is gone entirely already, if the user is having some sort of connection issues or if the user is doing some refresh thing. You can easily end up with a situation where the server thinks there are multiple connections all from the same user in the process of being confirmed. It can be a bit messy if your server is sensitive to that kind of thing.
The quickest thing you can do is to force the connection process to go immediately to the webSocket transport. You can do that in the client by adding an options to your connection code:
let socket = io(yourURL, {transports: ["websocket"]});
You can also configure the server to only accept webSocket connections if you're try to protect against any other types of connections besides just from your own web pages.
This will then go through the usual webSocket connection which starts with a single http request that is then "upgraded" to the webSocket protocol. Once connection, one socket. The server will know right away, either the user is or isn't connected. And, once they've switched over to the webSocket protocol, the server will known immediately if the user hits refresh because the browser will close the webSocket immediately.
The "start with http first" feature in socket.io is largely present because in the early days of webSockets, there were some browsers that didn't yet support them and some network infrastructure (like corporate proxies) that didn't always support webSocket connections. The browser issue is completely gone now. All browsers in use support webSocket connections. I don't personally have any data on the corporate proxies issues, but I don't ever hear about any issues with people using webSockets these days so I don't think that's much of an issue any more either.
So, the above change will get you a quick, confirmed connection and get rid of the confusion around whether a user is or isn't connected early in the connection process.
Now, if you still have users who are messing things up by rapid refresh, you probably need to just implement some protection on your server for that. If you cookie each user that arrives on your server, you could create some middleware that would keep track of how many page requests in some recent time interval have come from the browser with this cookie and just return them an error page that explains they can't make requests that quickly. I would probably implement this at the web page level, not the webSocket level as that will give users better feedback to stop hitting refresh. If it's really a refresh you're trying to protect against and not general navigation on your site, then you can keep a record of a combination cookie and URL and if you see even two of those within a few seconds, then return the error page instead of the expected content. If you redirect to an error page, it forces a more conscious action to go back to the right page again before they can get to the content.
I have built a websocket in C++ (using boost::beast).
It is going to serve a website (client) with a JSON string if requested.
When designing my setup I made a disastrous mistake: I forgot that the client web browser (that is running on a separate device from the server) will not know the IP address of the server. It will know the port that the server is listening on.
I should specify: Both (server and client) are running in a local network.
So I have two clumsy ideas to resolve this. I would be very happy to hear your input – I am sure there will be a more elegant way to fix my problem.
Send some kind of broadcast message “Very specific string” into the network. My server will know that it is been looked for and will respond with its IP, so that the connection can be established.
This post seems to indicate that this approach will not be possible.
Have the user input the (known) IP address of the device that is running the server. I would really like to avoid this last resort solution.
Unfortunately, I cannot run node.js on the device that is hosting the websocket server.
I might not be understanding the problem. Why aren't you capable of knowing the IP of the server? Is it due because it changes? Is it because it's a server you don't know?
Maybe the solution is not about finding the IP rather than knowing beforehand the server IP address.
I could recommend checking out this post to find out the IP address in your local network. If you at least know the servername of the server that could be helpful.
#E.Soria
Thank you for your answer! I was not precise enough.
The problem was, that the server is running on a device that is going to be part of our customer’s network. The customer will define the IP address for the device, which means that I need some way of getting the address of the server.
But I might have found another solution (as you might already be able to tell I am very new to networking, so this just may be wrong): I will host the website on the same device that is hosting the server and supplying the data. Then I can just establish a websocket connection through javascript like this: let socket = new WebSocket(ws://127.0.0.1:8080); and have the website read data from the server. This seems to be very straightforward and I am a little embarrassed that I did not think of this before.
I just had not really understood how the internet works :) As long as the user who wants to see the website knows where it is hosted, he/she can just connect to the website and will see anything that I put on there.
So I have server receiving wss connections in Java hosted on google kubernetes engine.
My website connects to the websocket connection in javascript using the default WebSocket library that comes with javascript.
The client connects to the server and works fine sometimes, but sometimes it fails to connect at all, doesn't get to the on open event or anything. To see if its server-side or client-side issue I made a small java app that connects to the websocket and had it run overnight doing 30 connections at once and it didn't have any problems so I think its something client side, or related to sessions keeping something cached.
Sometimes its very "sticky" once you don't connect once, even if you try to reconnect a million times it won't work, but if you use a different browser, or reset your wifi it will start working again? Also soon as the server restarts it usually works okay, but after a little while (hours or next day) it won't work.
One of the strangest behaviors is that if I inspect the request in firefox's network tab and do "edit and send" on the headers it will ALWAYS work even if the page "stuck" not working no matter how much I refresh. Here is a pic of what I mean:
this always works
The java websocket library I'm using is this one: https://github.com/TooTallNate/Java-WebSocket
I'm just using built in javascript connection library:
var wsocket = new WebSocket(address);
All I want is a consistent connection. I even tried to right code to retry the connection if it doesn't happen after a certain time, but because of the "sticky" behavior that doesn't help much.
Here is a screenshot of wireshark info, I don't really know what any of it means but maybe it can help you guys: wireshark
I feel like it has something to do with the browser/server keeping a session history or something?
On the server I get the following error at least some of the time when this occurs:
The connection was closed because the other endpoint did not respond with a pong in time.
I am having trouble with certificate when using websocket (WSS://).
What is working
For now, I've been using websocket with WEB_SOCKET_FORCE_FLASH = true and I had no issues with connecting to my websocket server.
What is not working
I am trying to turn that option off, to stop using flash plugin for connecting. Problem occurs when i try to connect my websocket client to server. WebSocket opening handshake was canceled message appears.
I can disable this message, by going to https://127.0.0.1:9999. My browser will show that "This Connection is Untrusted", and if I add an exception here, my websocket connection will start working without any problem from now on. But i CAN'T make every end user to do that, right?
Google groups with this idea
What I need?
Is there any way, to buy, or create some self-signed certificate, which I can use? The problem is also that, it doesn't have to be localhost/127.0.0.1 but also any other IP in local network. (like 192.168.0.100 etc). End user can change that IP whenever he likes to. He just needs to point on the PC where my desktop app/websocket server is running.
What have I tried?
I sure tried to find my answer in google, browsing tons of forums, sites, and even few questions and all answers here on stack overflow.
I also tried not using certificate at all, but my page is on https:// so connection using ws:// is impossible.
Code
I know, code is usually obligatory, but I actually got my websocket client/server working, but the issue is certificate, so i hope you can forgive me lack of code.
missing info?
Do i need to provide any more information? I am willing to make multiple edits if needed.
While the current certificate system is kind of broken it is fortunately not broken enough to allow what you want. What you expect to get based on your description is a certificate for an IP addresses (bad idea anyway) which you don't even own fully (you cannot claim to be the owner of 127.0.0.1 or similar addresses) which then will be accepted by every browser without the need to add a manual exception by the user.
So I've got a working client and server, GREAT! Problem I'm running into is the following.
When the server is offline, I want the javascript/web client to open and display its interface and simply check every so often if the server is up yet, and once its up, connect.
Problem is the client throws an error that the hub is undefined and so the webpage won't open. How can I get around this to achieve the results I'm looking for.
I've searched high and low and can't seem to find an example of this.
Any help/leads are appreciated.