Note that there are some explanatory texts on larger screens.

plurals
  1. POEstablishing WebSocket connection with Java server and Javascript client
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload