title: Establishing WebSocket connection with Java server and Javascript client
body: <p>I'm trying to implement WebSockets with a Javascript-based client and a Java-based server. I think I've done all the correct steps, but for an unknown reason, I can't establish the connection with both.</p>
  
  <p>When the server socket receives a connection, it handles to form a websocket-accept response, and it sends back to the client, but the connection in the client socket instantly close, weird that there's no handshake problem.</p>
  
  <p>Does anyone have an idea what might be the problem?</p>
  
  <p>Here's my server code implemented in java:</p>
  
  <pre><code>package server;
  
  import java.io.IOException;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.ArrayList;
  import java.util.List;
  
  import server.message.Message;
  import server.message.SpeakMessage;
  
  
  public class Server implements ConnectionListener {
      private static final int PORT = 1509;
      private MessageDispatcher dispatcher = new MessageDispatcher();
      private List&lt;ConnectionManager&gt; clients = new ArrayList&lt;&gt;();
  
      public void listen() {
          try (ServerSocket server = new ServerSocket(PORT)) {
              System.out.printf("Listening on port %d...%n", PORT);
              while (true) {
                  System.out.println("Waiting for connection...");
                  Socket client = server.accept();
                  System.out.println("Incoming connection - Attempting to establish connection...");
                  ConnectionManager manager = new ConnectionManager(client, dispatcher, this);
                  manager.start();
              }
          } catch (IOException e) {
              System.out.println("Unable to start server");
              e.printStackTrace();
          }
          System.exit(0);
      }
  
      public void execute() {
          try {
              while (true) {
                  if (dispatcher.isEmpty()) {
                      Thread.sleep(100);
                      continue;
                  }
                  Message msg = dispatcher.read();
                  if (msg instanceof SpeakMessage)
                      broadcast(MessageEncoder.spoke(((SpeakMessage) msg).getText()));
              }
          } catch (Exception e) {
              e.printStackTrace();
              System.exit(1);
          }
      }
  
      public static void main(String[] args) {
          final Server server = new Server();
          new Thread(new Runnable() {
              @Override
              public void run() {
                  server.listen();
              }
          }).start();
          server.execute();
      }
  
      public synchronized void broadcast(byte[] message) {
          for (ConnectionManager client : clients) {
              client.send(message);
          }
      }
  
      @Override
      public synchronized void clientConnected(ConnectionManager who) {
          clients.add(who);
          System.out.println("Connected client " + clients.size());
      }
  
      @Override
      public synchronized void clientDisconnected(ConnectionManager who) {
          clients.remove(who);
      }
  }
  </code></pre>
  
  <p>Heres subclass ConnectionManager of server:</p>
  
  <pre><code>package server;
  
  import java.io.DataInputStream;
  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.lang.reflect.InvocationTargetException;
  import java.net.Socket;
  import java.security.MessageDigest;
  import java.util.Properties;
  
  import server.message.HandshakeMessage;
  import server.message.Message;
  
  
  public class ConnectionManager {
      private static final int CLIENT_VERSION = 1;
      private Socket socket;
      private MessageDecoder decoder = new MessageDecoder();
      private MessageDispatcher dispatcher;
      private ConnectionListener listener;
  
      public ConnectionManager(Socket connection, MessageDispatcher dispatcher, ConnectionListener listener) {
          socket = connection;
          this.dispatcher = dispatcher;
          this.listener = listener;
      }
  
      public void start() {
          Thread t = new Thread(new ChannelReader());
          t.setName("Client thread");
          t.setDaemon(true);
          t.start();
      }
  
      public void send(byte[] data) {
          if (socket == null)
              return;
  
          try {
              DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
              dos.write(data);
              dos.flush();
          } catch (IOException e) {
              disconnect("Client closed the connection");
          }
      }
  
      private class ChannelReader implements Runnable {
          private boolean accepted = false;
          private String ret = null;
  
          @Override
          public void run() {
              try {
                  DataInputStream in = new DataInputStream(socket.getInputStream());
                  while (socket != null &amp;&amp; socket.isConnected()) {
                      int len = in.readShort();
                      if (len &lt; 0) {
                          disconnect("Invalid message length.");
                      }
  
                      String s;
                      readLine(in);
                      Properties props = new Properties();
                      while((s=readLine(in)) != null &amp;&amp; !s.equals("")) {
                          String[] q = s.split(": ");
                          props.put(q[0], q[1]);
                      }
  
                      if(props.get("Upgrade").equals("websocket") &amp;&amp; props.get("Sec-WebSocket-Version").equals("13")) { // check if is websocket 8
                          String key = (String) props.get("Sec-WebSocket-Key");
                          String r = key + "" + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // magic key
                          MessageDigest md = MessageDigest.getInstance("SHA-1");
                          md.reset();
                          md.update(r.getBytes());
                          byte[] sha1hash = md.digest();
  
  
                          String returnBase = base64(sha1hash);
  
  
                          ret = "HTTP/1.1 101 Switching Protocols\r\n";
                              ret+="Upgrade: websocket\r\n";
                              ret+="Connection: Upgrade\r\n";
                              ret+="Sec-WebSocket-Accept: "+returnBase;
  
                      } else {
                          disconnect("Client got wrong version of websocket");
                      }
  
                      Message msg = decoder.decode((String) props.get("Sec-WebSocket-Protocol"));
  
                      if (!accepted) {
                          doHandshake(msg);
                      } else if (dispatcher != null) {
                          dispatcher.dispatch(msg);
                      }
                  }
              } catch (Exception e) {
                  disconnect(e.getMessage());
                  e.printStackTrace();
              }
          }
  
          private void doHandshake(Message msg) {
              if (!(msg instanceof HandshakeMessage)) {
                  disconnect("Missing handshake message");
                  return;
              }
              HandshakeMessage handshake = (HandshakeMessage) msg;
              if (handshake.getVersion() != CLIENT_VERSION) {
                  disconnect("Client failed in handshake.");
                  return;
              }
              send(ret.getBytes());
              accepted = true;
              listener.clientConnected(ConnectionManager.this);
          }   
  
          private String base64(byte[] input) throws ClassNotFoundException, 
          SecurityException, NoSuchMethodException, IllegalArgumentException, 
          IllegalAccessException, InvocationTargetException, InstantiationException {
              Class&lt;?&gt; c = Class.forName("sun.misc.BASE64Encoder");
              java.lang.reflect.Method m = c.getMethod("encode", new Class&lt;?&gt;[]{byte[].class});
              String s = (String) m.invoke(c.newInstance(), input);
              return s;
          }
  
          private String readLine(InputStream in) {
              try{
                  String line = "";
                  int pread;
                  int read = 0;
                  while(true) {
                      pread = read;
                      read = in.read();
                      if(read!=13&amp;&amp;read!=10)
                          line += (char) read;
                      if(pread==13&amp;&amp;read==10) break;
                  }
                  return line;
              }catch(IOException ex){
  
              }
              return null;
          }
  
      }
  
      public synchronized void disconnect(String message) {
          System.err.println(message);
          if (socket != null) {
              try {
                  socket.close();
              } catch (IOException e) {
  
              }
          }
          socket = null;
          listener.clientDisconnected(ConnectionManager.this);
      }
  }
  </code></pre>
  
  <p>And the MessageDispatcher:</p>
  
  <pre><code>package server;
  
  import java.util.Queue;
  import java.util.concurrent.LinkedBlockingDeque;
  
  import server.message.Message;
  
  
  public class MessageDispatcher {
      Queue&lt;Message&gt; messageQueue = new LinkedBlockingDeque&lt;&gt;();
  
      public void dispatch(Message message) {
          messageQueue.offer(message);
      }
  
      public Message read() {
          return messageQueue.poll();
      }
  
      public boolean isEmpty() {
          return messageQueue.isEmpty();
      }
  }
  </code></pre>
  
  <p>And heres my client code implemented in javascript:</p>
  
  <pre><code>var canvas, // Canvas DOM element
      ctx,    // Canvas rendering context
      socket; // Socket connection
  
  function init() {
      // Initialise the canvas
      canvas = document.getElementById("gameCanvas");
      ctx = canvas.getContext("2d");
      // Maximise the canvas
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
  
      // Initialise socket connection
      if (window.WebSocket) { 
          socket = new WebSocket("ws://localhost:1509/", ["1", "YURI"]);
          socket.onopen = onSocketConnected();
          socket.onclose = onSocketDisconnect();
          socket.onmessage = onSocketMessage();
          socket.onerror = onSocketError();
      } else {
          alert("The browser does not support websocket.");
      }
  
  };
  
  // Socket message
  function onSocketMessage(message) {
      console.log('Message: ' + message.data);
  };
  
  // Socket error
  function onSocketError(error) {
      console.log('Error: ' + error.data);
  };
  
  // Socket connected
  function onSocketConnected() {
      console.log("Connected to socket server");
  };
  
  // Socket disconnected
  function onSocketDisconnect() {
      console.log("Disconnected from socket server");
  };
  </code></pre>