WebSocket,并非HTML 5獨有,WebSocket是一種協定。隻是在handshake的時候,發送的連結資訊頭和HTTP相似。HTML 5隻是實作了WebSocket的用戶端。其實,難點在于服務端,服務端相對還是比較複雜的。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnaucjM3IDZ4kDZ4IGM0ImN2UTZ0QjYiNmYlZTOzgDNmhzNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpg)
也就說,你需要解讀opcode, Payload len 這些比較敏感的位值之後,你才開始取後面的Payload Data, 比如opcode如果是1,那麼就是讀取字元串,如果是2,那麼就是讀取流。
如果自己用java做服務端,握手協定的響應,換行符不能使“\r\n”或“\n”,因為這不是标準的換行符,其實是個字元串,隻是螢幕顯示的時候是換行,可以用PrintWrite.println(),或者
String newLine = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
握手之後,根據opcode做相應的操作,JAVA的IO和NIO,在實作方面都缺憾,難以實作。使用IO的話,在獲得socket之 後,InputStream會處于阻塞,因為阻塞,是以後續做outputStream的操作時就會不友善。NIO的話,是SocketChannel寫 入讀出,基本都是ByteBuffer,用這個的話,有時opcode值為1(讀取字元串),ByteBuffer解碼得到的字元串經常性是亂碼。感覺最 好還是學Tomcat,自己重寫一下InputStream。
Tomcat在7.0.27之後就開始支援WebSocket,在它之上建立WebSocket是很簡單的,基本就是繼承 WebSocketServlet,實作createWebSocketInbound方法和重寫StreamInbound的方法。Tomcat的 example裡面有相關的例子。
Tomcat處理流程,WebSocketServlet本身就繼承了HttpServlet,重寫doGet方法,在doGet方法裡面做了 handshake的操作,之後就是一些UpgradeInbound的操作,做好接收資料流的準備(StreamInbound提供了onData方 法)。每次資料過來,都會執行onData裡面的WsFrame frame = wsIs.nextFrame(true); 對資料幀進行分析,并且提供自定義InputStream流,調用使用者重寫的onBinaryData或者onTextData方法,将輸入流裡面的資料 讀出,再response給用戶端。
WebSocketServlet(doGet) -> handshake -> createWebSocketInbound -> doUpgrade -> setUpgradeProcessor ->
onUpgradeComplete -> onData -> 資料過來 -> wsIs.nextFrame(true) -> 生成自定義InputStream -> 調用使用者重寫方法 (另外如果opcode是關閉Socket,也會有相應的操作)
http://www.open-open.com/lib/view/open1344582940452.html