Some users can't connect to websocket - javascript

I am using socket.io.Some users sending message to me 'I can't send a message why ?'.I researched this problem,guess firewall or antivirus blocking websocket.If browser doesn't support the websocket,socket.io automatically switching to xhr polling,there is no problem.But If browser supports the websocket and antivirus or firewall is blocking the websocket,socket.io is not switching to xhr,and users can't send messages.How can I resolve this problem ?
Here is a websocket test report a user
http://websocketstest.com/result/244711
Websocket support is ok,data receive is no.

You can set Socket.IO to use only XHR polling in the configuration:
io.configure(function () {
io.set("transports", ["xhr-polling"]);
});
See Configuring Socket.IO in the official documentation.

I have found that a lot of users end up not being able to connect successfully with socket.io. Rather than trying to continually diagnose it, I have started to build my apps to have easy fallbacks to ajax. I can in fact, change my environment variable of useSocketIO to false, and the whole site, chatting, tipping, image sharing will fallback to ajax. This does not solve the underlying issue, but has saved me a lot of headaches in lost data not being transmitted.
pseudo code on the client
# check that I have a socket object
if socket != null
# if not connected, try to reconnect
if !socket.connected and !socket.connecting
attemptResetOfSocketIO()
# if now connected, send socket message
if socket.connected or socket.connecting
sendSocketMessage()
else
# not connected, send via ajax
sendAjaxMessage()
else
# no socket object, send via ajax
sendAjaxMessage()

Related

Javascript WebSocket - Need more delay

I need to delay when the handshake starts when using the WebSocket API on the browser.
The server is a Nucleo board (L476RG) with a wifi shield IDW01M1.
The client is Firefox v50.1
1. Testing the server
I made Python scripts to establish a WebSocket connection. I noticed that I needed to first "Connect" to the server. Then initiate the exchange after a delay of 600ms
I cannot run my server faster than this. Remember this is a hobby level MCU
2. Testing the client
I made a local server using Python. My Javascript client connects to it with no issues.
#!c:/Python27/python.exe -u
import socket
import time
TCP_IP = '172.24.220.1'
TCP_PORT = 3000
BUFFER_SIZE = 1024
#
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect first
connected = False
while not connected:
try:
s.connect((TCP_IP, TCP_PORT))
connected = True
except Exception as e:
pass
#------------------------------------
time.sleep(0.6)
#------------------------------------
# Send first bytes
s.send("Good-hi")
# Ping pong
data = s.recv(BUFFER_SIZE)
Same issue happens with Python also when using the WebSocket library
#!c:/Python27/python.exe -u
import time
import websocket
from websocket import create_connection
remote = "ws://172.24.220.1:3000"
websocket.enableTrace(True)
ws = websocket.WebSocket()
ws.connect(remote) #<------Need to add delay inside this method
print "WebSocket established"
ws.close()
This page explains what happens inside the WebSocket method.
With Python I can open a socket without any handshake (RAW Socket), then start my handshake by sending manually the headers.
However this is impossible to do in a browser because I can't open RAW sockets.
At least, this is my understanding so far.
Summary, is there a way to first establish a connection between client and server, then start the handshake at will ?
If you use the WebSockets api in javascript.
There is a onopen event that gets fired when the connection is ready.
you could put a setTimeout inside this to delay sending first data.
I don't think you can delay the handshake itself.
Maybe try putting new Websocket inside setTimeout to make sure all files have been served before trying to start connection.
more info here:
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications

netty-socketio: client did not complete upgrade - closing transport

I have a socket server running with netty-socketio and a web app that connects to it using socket.io-client JS library.
The problem is that I'm losing a few connections (not all, let's say 20%).
For the lost connections: right after the connection is made by the client, the server logs client did not complete upgrade - closing transport and disconnects the client.
This happens on my production server (using nginx as proxy) and also on my local environment (connecting directly to the netty-socketio server). It's pretty much random and I cant identify a pattern on it. For example, if I continuously keep refreshing the client app on the browser (with a 5 seconds interval), at some point this error will happen, and for the subsequent tries it will work normal again (until it happens another time).
This is the error on the netty-socketio lib: https://github.com/mrniko/netty-socketio/blob/master/src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java#L196
but I could not figure out why it happens randomly (some times at the first try)
Any thoughts on this are really appreciated.
Thanks
After some research and tests I found out that when using netty-socketio as server, you need to specify the transport method on the client side.
var socket = io('server-address', { transports: [ 'polling' ] });
// or
var socket = io('server-address', { transports: [ 'websocket' ] });
If you don't specify it, the connection will be established using polling as transport method and netty will automatically try to upgrade it to websocket. This is what was causing connection failures.
After specifying the transport method I had 0% connection failures so far.

Correct way to handle Websocket

I've a client to server Websocket connection which should be there for 40 seconds or so. Ideally it should be forever open.
The client continually sends data to server and vice-versa.
Right now I'm using this sequence:
var socket;
function senddata(data)
{
if (!socket)
{
socket = new WebSocket(url);
socket.onopen = function (evt) {
socket.send(data);
socket.onmessage = function (evt) {
var obj = JSON.parse(evt.data);
port.postMessage(obj);
}
socket.oneerror = function (evt) {
socket.close();
socket = null;
}
socket.onclose = function(evt){
socket = null;
}
}
}
else
{
socket.send(data);
}
}
Clearly as per current logic, in case of error, the current request data may not be sent at all.
To be frank it sometimes gives error that websocket is still in connecting state. This connection breaks often due to networking issues. In short it does not work perfectly well.
I've read a better design : How to wait for a WebSocket's readyState to change but does not cover all cases I need to handle.
Also I've Googled about this but could not get the correct procedure for this.
So what is the right way to send regular data through Websockets which handles well these issues like connection break etc?
An event you don't seem to cover is onclose. Which should work really well, since it's called whenever the connection terminates. This is more reliable than onerror, because not all connection disruptions result in an error.
I personally use Socket.IO, it enables real-time bidirectional event-based communication between client and server.
It is event driven. Events such as
on connection :: socket.on('conection',callback);
and
on disconnect :: socket.on('disconnect',callback);
are built in with socket.io so it can help you with your connection concerns. Pretty much very easy to use, check out their site if you are interested.
I use two-layer scheme on client: abstract-wrapper + websocket-client:
The responsibilities of the websocket-client are interacting with a server, recovering the connection and providing interfaces (event-emitter and some methods) to abstract-wrapper.
The abstract-wrapper is a high-level layer, which interacts with websocket-client, subscribes to its events and aggregating data, when the connection is temporary failed. The abstract-wrapper can provide to application layer any interface such as Promise, EventEmitter and so on.
On application layer, I just work with abstract-wrapper and don't worry about connection or data losing. Undoubtedly, it's a good idea to have here information about the status of connection and data sending confirmation, because it's useful.
If it is necessary, I can provide some code for example
This apparently is a server issue not a problem in the client.
I don't know how the server looks like here. But this was a huge problem for me in the past when I was working on a websocket based project. The connection would continuously break.
So I created a websocket server in java, and that resolved my problem.
websockets depend on lots of settings, like if you're using servlets then servlet container's settings matter, if you're using some php etc, apache and php settings matter, for example if you create a websocket server in php and php has default time-out of 30 seconds, it will break after 30 seconds. If keep-alive is not set, the connection wont stay alive etc.
What you can do as quick solution is
keep sending pings to a server after a certain amount of time (like 2 or 3 seconds, so that if a websocket is disconnected it is known to the client so it could invoke onclose or ondisconnect, I hope you know that there is no way to find if a connection is broken other than failing to send something.
check server's keep-alive header
If you have access to server, then it's timeouts etc.
I think that would help

Websocket on MAMP

I am working on a personal project that has a chat message system. I want the messages to update real time for both users when a new message is sent (like facebook chat). Although I have tried multiple ways to detect changes on the database and AJAX my PHP script that SELECTs the messages I can only update the sender's message in real time. The receiver can't see the new message unless they refresh their page. So I decided to use websockets on my local environment to keep the connection open and AJAX my messages.php script when there is a change on the database. However, when I create the websocket object:
var msgsSocket = new WebSocket("ws://www.localhost:8888/messages.php");
I am getting an error:
WebSocket connection to 'ws://www.localhost:8888/messages.php' failed: Error during WebSocket handshake: Unexpected response code: 200
I also tested with the following URL strings:
www.localhost/messages.php
localhost:8888/messages.php
I am not sure what I am doing wrong. Any help is welcome.
P.S. I am using MAMP

socket.io in node.js: socket.emit doesn't complete before socket.disconnect

I'm trying to use node.js as a server with socket.io (over a https connection server object, client connecting with option secure: true) with a JavaScript front end.
On the server if a login attempt fails I am calling:
socket.emit('unauthorized');
socket.disconnect();
On the client side I have:
this.Socket = io.connect(server, { secure: true });
this.Socket.on('disconnect', this.Socket_Disconnect);
this.Socket.on('unauthorized', this.Socket_Unauthorized);
I am able to see the disconnect event firing (with arguments set as ['booted'] regardless of whether i pass any arguments to socket.disconnect(), but the unauthorized event never makes it. Am I attempting to pass this message the wrong way?
The rationale I have here is that I want to be able to send different types of disconnect events like:
logout - clients should stop trying to connect until a user logs in
server reboot - clients should reattempt connection until they get through
I need to be able to tell on the client side why a client was disconnected by the server, is there at least some way to make sure a message has sent before calling socket.disconnect()?
Edit: this appears specific to the node.js cluster code - when the application is run on a single thread it works as expected.
Solved this by setting up a Redis server and configuring socket.io to use it within node.js if anyone finds this looking for a solution to the issue.

Categories

Resources