This blog post shows a proof of concept implementation which can be extended to emulate a WebSocket client in JavaScript in browsers where WebSocket support is not available, but there is a working Java plugin installed.
The motivation behind this blog post is to design drop-in replacements for WebSocket for older browsers (e.g. Internet Explorer 9 and earlier, Opera 9 and earlier, Safari 4 and earlier, Firefox 3.7 and earlier), where WebSocket client support is not available, but some browser plugin (like Java, Flash or Silverlight) could be used to emulate it. This blog post is a proof-of-concept demonstrating how the Java plugin can be used for such an emulation.
The trick is to use the java
symbol exported to JavaScript. Here is the relevant HTML page with JavaScript code, which implements a simple, proof-of-concept HTTP client in JavaScript using Java:
<html><head> <title>Java WebSocket proof-of-concept test</title> <script type="text/javascript"> function output(str) { var output = document.getElementById("output") var text = document.createTextNode(str) var br = document.createElement('br') output.insertBefore(br, null) output.insertBefore(text, null) } function init() { output("find java") java.lang var hostItems = window.location.host.split(':') var hostName = hostItems[0] var port = 80 if (hostItems.length > 1) { port = parseInt(hostItems[1], 10) if (port == 443 && window.location.protocol == 'https:') port = 80 } output("connecting to host " + hostName + ", port " + port) var socket = new java.net.Socket(hostName, port) output("connected") var osw = new java.io.OutputStreamWriter(socket.getOutputStream(), "UTF-8") var isr = new java.io.InputStreamReader(socket.getInputStream(), "UTF-8") var bis = new java.io.BufferedReader(isr) output("sending request (GET /answer.html)") osw.write("GET /answer.html HTTP/1.0\r\n\r\n") osw.flush() output("reading response") // SUXX: This blocks the whole browser (Firefox) until the response is // ready. var line while (true) { line = bis.readLine() if (line == null) break if (line == '' || line == '\r') break output("got header line: " + line) } output("done with header") if (line != null) { while (true) { line = bis.readLine() if (line == null) break output("got body line: " + line) } } output("done with body") output("closing") isr.close() osw.close() socket.close() output("done") } </script> </head><body onload="init()"> <div id="output" style="border:1px solid black;padding: 2px">Welcome!</div> </body></html>
The code above could be easily upgraded to use the WebSocket protocol.
Please note that the implementation above has a show-stopper bug: it locks the whole browser UI (all functionality in all tabs, in Firefox 3.6) until the server returns the HTTP response. It might be possible to solve it by using java.nio.SocketChannel
, but we haven't investigated that yet.
Please note that it is possible to do WebSocket emulation with Flash instead of Java, see web-socket-js for the client-side code (JavaScript and Flash) and web-socket-ruby for the server-side code.
Please note that we haven't investigated if it is possible to do WebSocket emulation with Silverlight instead of Java.