Websocket dilemma between javascript and jetty embedded websocket server
<p>I have a javascript API that it's included in some websites. For some reasons there <strong>is a need for communicate that browser side with a desktop application written in Java</strong>. As you can see, all is local to the host.</p>

<p>My first solution was to use <strong>plugins/extensions for each known browser</strong>, but the lack of good support and the bunch of dependencies stop me to opt for that option. Then my second approach was to <strong>use websockets in both sides</strong>, with the server in the Java app, and the client being the browser, everything will going to be perfect, but then a big problem come to the surface: <strong>HTTPS websites can't establish connection with a insecure websocket server</strong>, not matter of Java, and not matter of if the server is on the localhost.</p>

<p>The <strong>java_websocket</strong> API that I've been using was not good enough to resolve this problem, and in google <strong>Jetty</strong> is a good name that sound for my purposes. I get involve with Jetty in few hours, and after some examples I got two classes, a server endpoint (<em>EchoSocket</em>) and the server (<em>EventServer</em>):</p>

<p>EventServer.java</p>

<pre><code>import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;

public class EventServer {

  public static void main(String[] args) {

      try {
        Server server = new Server();
        int httpsPort = 8771;

        SslContextFactory scf = new SslContextFactory("mykeystore.jks");
        scf.setKeyStorePassword("blaStore");
        scf.setKeyManagerPassword("blablaKey");

        SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(scf, "http/1.1");

        HttpConfiguration https = new HttpConfiguration();
        https.setSecurePort(httpsPort);
        https.setSecureScheme("https");
        https.addCustomizer(new SecureRequestCustomizer());

        ServerConnector sslConnector = new ServerConnector(server,
                sslConnectionFactory,
                new HttpConnectionFactory(https)
        );
        sslConnector.setPort(httpsPort);
        server.addConnector(sslConnector);

        HandlerList baseHandler = new HandlerList();
        server.setHandler(baseHandler);

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); //ServletContextHandler.SESSIONS
        context.setContextPath("/");
        baseHandler.addHandler(context);

        ServerContainer jsrContainer = WebSocketServerContainerInitializer.configureContext(context);
        jsrContainer.addEndpoint(EchoSocket.class);
        baseHandler.addHandler(new DefaultHandler());

        server.start();
        server.dump(System.err);
        server.join();

      } catch (Throwable ex) {
         ex.printStackTrace(System.err);
     }
  }
}
</code></pre>

<p>EchoSocket.java</p>

<pre><code>import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value="/echo")
public class EchoSocket
{
    @OnMessage
    public void onMessage(javax.websocket.Session session, String message){
        session.getAsyncRemote().sendText("welcomeeee");
    }

    @OnError
    public void onError(Throwable cause)
    {
        cause.printStackTrace(System.err);
    }

}
</code></pre>

<p>Using a <a href="https://www.websocket.org/echo.html" rel="nofollow">Websocket online test</a> I can communicate from <strong>Mozilla Firefox</strong> and <strong>Opera</strong>, but the connection it's disconnected after some minutes, and in some times there is an undefined error that close the connection. </p>

<p>In case of <strong>Microsoft Edge</strong> and <strong>IE</strong> nothing works, when I wrote the URI as <strong>wss://localhost:8771/echo</strong> the error is:</p>

<pre><code>SCRIPT12017: WebSocket Error: SECURITY_ERR, Cross zone connection not allowed
</code></pre>

<p>And when I try with <strong>wss://127.0.0.1:8771/echo</strong> the error is:</p>

<pre><code>SCRIPT12038: WebSocket Error: Network Error 12038, The host name in the certificate is invalid or does not match
</code></pre>

<p>In <strong>Google Chrome</strong> neither way of URI seems work, there is not connection, the error is:</p>

<pre><code>WebSocket connection to 'wss://127.0.0.1:8771/echo' failed: Error in connection establishment: net::ERR_NETWORK_CHANGED
</code></pre>

<p>and in the other case:</p>

<pre><code>WebSocket connection to 'wss://localhost:8771/echo' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
</code></pre>

<p>So, I need some help, but may be you can answer me some of the next questions:</p>

<ul>
<li>Is correct my example of Jetty?, if not, How can I correct it?</li>
<li>Should I try another libraries, or older versions of Jetty to make this work in most of the browsers?</li>
<li>Should I see other implementations of a websocket server in another languages like C#?</li>
<li>What hostname or SubjectAltName do I have to set in my SSL certificate to allow connections from IE and Edge? Maybe "localhost", or "127.0.0.1" .</li>
</ul>

<p>Please, thanks in advance, and sorry by my english.</p>