I am developing an app for some time and recently I attached to the app an SSL Certificate (it is not self-signed; it is signed by Comodo, so the problem can't occur from here). I implemented long ago a WebSocket endpoint on my Java Glassfish server and I'm using it with javascript. I have been using the WebSocket successfully via http until now, when I moved to https.
Let's have a look at the code snippets I use:
Server Endpoint:
#ServerEndpoint(value = "/ws/chat",
encoders = ChatMessageEncoder.class,
decoders = ChatMessageDecoder.class)
public class ChatEndpoint {
#OnOpen
public void open(final Session session) {
// stuff happenin'
}
#OnMessage
public void onMessage(final Session session) {
// stuff happenin' }
#OnError
public void onError(Throwable t) {
t.printStackTrace();
System.out.println("error");
}
#OnClose
public void onClose() {
}
}
Client Connection:
var wsocketPrivate;
function connectToChatserver() {
var serviceLocation = 'wss://<ip>:8080/ws/chat';
$rootScope.wsocketPrivate = new WebSocket(serviceLocation);
$rootScope.wsocketPrivate.onmessage = onMessageReceived;
};
function onMessageReceived(evt) {
console.log(evt)
};
connectToChatserver();
Not having activated ssl certificate and using var serviceLocation = 'ws://<ip>:8080/ws/chat'; (ws instead of wss) works perfectly fine. When I moved to https, it asked for wss (the browser blocked my ws handshake because it wasn't secure) and moving to wss, the following error occurs:
WebSocket connection to 'wss://<ip>:8080/ws/chat' failed: Error in connection establishment: net::ERR_TIMED_OUT
What am I doing wrong? Can you suggest some tests to find out more information?
Thank you,
Mihai
I finally found where the problem was. I was using an nginx front server as a proxy. The default configuration of that server was blocking my wss for some weird reason.
Related
About 4 hours of research...here we go.
I have a C# program that sends and listens for anything coming in a specific Socket. Using the sockets, C# can send stuff to it and can receive from it just fine. Now, going to my JavaScript file, I'm using the WebSocket interface to communicate with C#, but doesn't work (usually times out after a couple of minutes). When the Socket is online, the JavaScript code will take up to about 4 minutes then throw an error saying "WebSocket opening handshake timed out". The thing is I know that it can find because, when the port of the ip doesn't exist the JavaScript file throws an error in the next couple seconds.
Things I've done:
Turn off all firewalls, use both ws and wss at the beginning of the ip and port (ex: wss://xxx.xxx.x.xx:11111), change the port, change the ip to a valid ip still reachable, research for 4 hours.
C#:
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = IPAddress.Parse("ip");
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
Socket listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
Console.WriteLine("Waiting connection...");
Socket clientSocket = listener.Accept();
byte[] bytes = new Byte[1024];
string data = null;
while (true)
{
int numByte = clientSocket.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, numByte);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Text received -> {0} ", data);
byte[] message = Encoding.ASCII.GetBytes("Test Server");
clientSocket.Send(message);
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
JavaScript:
socket = new WebSocket("wss://ip:11111");
socket.onopen = function()
{
alert("Connected!");
}
socket.onerror = function()
{
alert("Connection Failed");
}
The ip is local
Long story short, C# can communicate with itself and JavaScript can find it but can't communicate with it.
Properly complete a handshake. (Or use a library / connection type that does.)
The WebSocket protocol (as original defined in RFC6455 - The WebSocket Protocol) does not open a plain unrestricted socket, in part for security reasons.
Since the handshake is not complete, the client WS request will timeout as the HTTP “Upgrade” response is never received. Until the handshake is complete, the WS will not be active over the underlying TCP connection.
Initiating a WebSocket connection (“the handshake”) is defined in section 4 of the RFC. It is also discussed in How JavaScript works: Deep dive into WebSockets and HTTP/2 with SSE + how to pick the right path.
The client establishes a WebSocket connection through a process known as the WebSocket handshake. This process starts with the client sending a regular HTTP request to the server. An Upgrade header is included in this request which informs the server that the client wishes to establish a WebSocket connection.
..
Now that [after] the handshake is complete the initial HTTP connection is replaced by a WebSocket connection that uses the same underlying TCP/IP connection. At this point, either party can start sending data.
I have a web-socket that is started from javascript, that is connecting to a domain (e.g my-domain):
let socket = new WebSocket("ws://www.my-domain.com/ws");
If I go in the browser and type www.my-domain.com all works fine. However, for short domain name (i.e. without www) (http://my-domain.com) the opening of the websocket fails.
I have tested on Firefox:
Firefox can’t establish a connection to the server at ws://www.my-domain.com/ws.
EDIT: The server is done in GO:
http.HandleFunc("/ws", wsHandler)
http.HandleFunc("/", rootHandler)
panic(http.ListenAndServe(":80", nil))
func (this *server) wsHandler(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Origin") != "http://"+r.Host {
http.Error(w, "Origin not allowed", 403)
return
}
...
I am trying to create a web socket in java. However I am getting error "Error during WebSocket handshake: Unexpected response code: 404
(anonymous)" when I am trying to connect to the socket using java script.
I have tried using provided scope with the javax.websocket, also tried switching to tomcat7-websocket jar as suggested in answers here WebSocket 404 error . I am still getting the same error. Thank you for the help in advance.
I also tried removing the .m2 directory, that didn't help either.
I am using this code on java end
#ServerEndpoint("/webSockTest")
public class ServerTest {
private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());
#OnOpen
public void open(Session session) {
peers.add(session);
}
#OnClose
public void close(Session session) {
peers.remove(session);
}
#OnError
public void onError(Throwable error) {
}
#OnMessage
public String handleMessage(String message, Session session) {
return "hello";
}
}
And trying to connect using:
new WebSocket("ws://localhost:8080/demo/webSockTest")
i have python server(with the help of asyncio and websockets module) and js client(with the help of websockets library) that are connected. The problem is that i need this connection to be secured (i'm working on passwords), but i had no success on establishing a connection with wss(web socket secure) - the code runs only with ws.
I even tried to establish my own encryption with RSA and AES but that also didn't work.
i'm really hopeles about it so if anyone ever did it or know a little about it, pls help me figure out what's wrong with it, or a direction to a rigth solution for secured connection that will work.
here's my server:
async def app(websocket, path):
while True :
data = await websocket.recv()
if (data== "close"):
print("connection with client closed.")
break
data = data.encode()
arr = data.split("~".encode())
for i in range(0,4):
arr[i]=arr[i].decode()
resualt=algo(arr)
await websocket.send(resualt)
start_server = websockets.serve(app, '0.0.0.0', 6169)
and my client:
var socket = new WebSocket("ws://127.0.0.1:6169/");
socket.onopen = function (evt) {
socket.send(st);
};
socket.onmessage = function (evt) {
alert("scrool extension page down to see the password");
$('#res').val(evt.data);
socket.send("close");
};
socket.onerror = function (evt) {
alert("the error is: "+evt.data);
};
in the python script we tried to use ssl:
c = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
c.load_default_certs(purpose=ssl.Purpose.CLIENT_AUTH)
start_server = websockets.serve(app, '0.0.0.0', 6169, ssl=c)
and in the js sciprt we wrote instead of the ws, wss:
"ws://127.0.0.1:6169/")
and the error we get:
WebSocket connection to 'wss://127.0.0.1:6169/' failed: Error in connection
establishment: net::ERR_CONNECTION_CLOSED
I'm having JavaScript SignalR client and .NET SignalR server application. After application redeployment by Octopus Deploy the client stops receivng any messages from the server, although the server receives messages from the client and tries to send messages back.
More detailed behavior:
Client opens connection with id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'
Connection '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c' is created on the server.
Client sends messages to the server, server sends messages to the client. Everything is ok.
Server is redeployed by Octopus Deploy.
Client sends message to the server from the same connection. Message is received by the server.
Server sends message to the client. Message is not received.
After server restart in application logs I see that messages from the client are received by the server but I don't see that connection was created.
Should I manually create SignalR connections after restart?
Can messages from the client be received without created connection?
Here is the module I use for logging:
public class LoggingPipelineModule : HubPipelineModule
{
protected override void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext)
{
Logging.Logger.Error(exceptionContext.Error.Message, exceptionContext.Error);
base.OnIncomingError(exceptionContext, invokerContext);
}
protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context)
{
Logging.Logger.Debug(string.Format(
"Invoking '{0}' on server hub '{1}' with connection id '{2}'",
context.MethodDescriptor.Name,
context.MethodDescriptor.Hub.Name,
context.Hub.Context.ConnectionId));
return base.OnBeforeIncoming(context);
}
protected override bool OnBeforeOutgoing(IHubOutgoingInvokerContext context)
{
var connection = context.Connection as Connection;
if (connection != null)
{
Logging.Logger.Debug(string.Format(
"Invoking '{0}' on client hub '{1}' with connection id '{2}'",
context.Invocation.Method,
context.Invocation.Hub,
connection.Identity));
}
else
{
Logging.Logger.Debug(string.Format(
"Invoking '{0}' on client hub '{1}'",
context.Invocation.Method,
context.Invocation.Hub));
}
return base.OnBeforeOutgoing(context);
}
protected override void OnAfterConnect(IHub hub)
{
Logging.Logger.Debug(string.Format("New connection with id {0} is established", hub.Context.ConnectionId));
base.OnAfterConnect(hub);
}
protected override void OnAfterDisconnect(IHub hub, bool stopCalled)
{
Logging.Logger.Debug(string.Format("Connection with id {0} was closed", hub.Context.ConnectionId));
base.OnAfterDisconnect(hub, stopCalled);
}
protected override void OnAfterReconnect(IHub hub)
{
Logging.Logger.Debug(string.Format("Connection with id {0} was recreated", hub.Context.ConnectionId));
base.OnAfterReconnect(hub);
}
}
Here are the application logs (there is no connection creation):
2017-03-28 08:40:58,915 [62] DEBUG Invoking 'Push' on client hub 'ServerHub' with connection id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'
2017-03-28 08:41:18,213 [88] DEBUG Invoking 'Unsubscribe' on server hub 'ServerHub' with connection id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'
2017-03-28 08:41:18,447 [64] DEBUG Invoking 'Subscribe' on server hub 'ServerHub' with connection id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'
2017-03-28 08:41:23,916 [64] DEBUG Invoking 'Unsubscribe' on server hub 'ServerHub' with connection id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'
2017-03-28 08:41:24,151 [62] DEBUG Invoking 'Subscribe' on server hub 'ServerHub' with connection id '5dd083cc-f7fe-4b7d-8cae-d0e87b35d51c'