17 lines
6.8 KiB
JavaScript
17 lines
6.8 KiB
JavaScript
|
/*
|
||
|
* Websock: high-performance binary WebSockets
|
||
|
* Copyright (C) 2012 Joel Martin
|
||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||
|
*
|
||
|
* Websock is similar to the standard WebSocket object but Websock
|
||
|
* enables communication with raw TCP sockets (i.e. the binary stream)
|
||
|
* via websockify. This is accomplished by base64 encoding the data
|
||
|
* stream between Websock and websockify.
|
||
|
*
|
||
|
* Websock has built-in receive queue buffering; the message event
|
||
|
* does not contain actual data but is simply a notification that
|
||
|
* there is new data available. Several rQ* methods are available to
|
||
|
* read binary data off of the receive queue.
|
||
|
*/
|
||
|
|
||
|
function Websock(){"use strict";this._websocket=null,this._rQi=0,this._rQlen=0,this._rQbufferSize=4194304,this._rQmax=this._rQbufferSize/8,this._rQ=null,this._sQbufferSize=10240,this._sQlen=0,this._sQ=null,this._mode="binary",this.maxBufferedAmount=200,this._eventHandlers={message:function(){},open:function(){},close:function(){},error:function(){}}}window.WebSocket&&!window.WEB_SOCKET_FORCE_FLASH?Websock_native=!0:window.MozWebSocket&&!window.WEB_SOCKET_FORCE_FLASH?(Websock_native=!0,window.WebSocket=window.MozWebSocket):Websock_native=!1,function(){"use strict";var e=function(){try{var e=new Uint8Array([1,2,3]);return String.fromCharCode.apply(null,e),function(e){return String.fromCharCode.apply(null,e)}}catch(e){return function(e){return String.fromCharCode.apply(null,Array.prototype.slice.call(e))}}}();Websock.prototype={get_sQ:function(){return this._sQ},get_rQ:function(){return this._rQ},get_rQi:function(){return this._rQi},set_rQi:function(e){this._rQi=e},rQlen:function(){return this._rQlen-this._rQi},rQpeek8:function(){return this._rQ[this._rQi]},rQshift8:function(){return this._rQ[this._rQi++]},rQskip8:function(){this._rQi++},rQskipBytes:function(e){this._rQi+=e},rQshift16:function(){return(this._rQ[this._rQi++]<<8)+this._rQ[this._rQi++]},rQshift32:function(){return(this._rQ[this._rQi++]<<24)+(this._rQ[this._rQi++]<<16)+(this._rQ[this._rQi++]<<8)+this._rQ[this._rQi++]},rQshiftStr:function(t){void 0===t&&(t=this.rQlen());var i=new Uint8Array(this._rQ.buffer,this._rQi,t);return this._rQi+=t,e(i)},rQshiftBytes:function(e){return void 0===e&&(e=this.rQlen()),this._rQi+=e,new Uint8Array(this._rQ.buffer,this._rQi-e,e)},rQshiftTo:function(e,t){void 0===t&&(t=this.rQlen()),e.set(new Uint8Array(this._rQ.buffer,this._rQi,t)),this._rQi+=t},rQwhole:function(){return new Uint8Array(this._rQ.buffer,0,this._rQlen)},rQslice:function(e,t){return t?new Uint8Array(this._rQ.buffer,this._rQi+e,t-e):new Uint8Array(this._rQ.buffer,this._rQi+e,this._rQlen-this._rQi-e)},rQwait:function(e,t,i){if(this._rQlen-this._rQi<t){if(i){if(this._rQi<i)throw new Error("rQwait cannot backup "+i+" bytes");this._rQi-=i}return!0}return!1},flush:function(){return 0!==this._websocket.bufferedAmount&&Util.Debug("bufferedAmount: "+this._websocket.bufferedAmount),this._websocket.bufferedAmount<this.maxBufferedAmount?(this._sQlen>0&&this._websocket.readyState===WebSocket.OPEN&&(this._websocket.send(this._encode_message()),this._sQlen=0),!0):(Util.Info("Delaying send, bufferedAmount: "+this._websocket.bufferedAmount),!1)},send:function(e){return this._sQ.set(e,this._sQlen),this._sQlen+=e.length,this.flush()},send_string:function(e){this.send(e.split("").map(function(e){return e.charCodeAt(0)}))},off:function(e){this._eventHandlers[e]=function(){}},on:function(e,t){this._eventHandlers[e]=t},_allocate_buffers:function(){this._rQ=new Uint8Array(this._rQbufferSize),this._sQ=new Uint8Array(this._sQbufferSize)},init:function(e,t){this._allocate_buffers(),this._rQi=0,this._websocket=null;var i=!1;"Uint8Array"in window&&"set"in Uint8Array.prototype&&(i=!0);var r=!1;try{i&&("binaryType"in WebSocket.prototype||new WebSocket(t+"://.").binaryType)&&(Util.Info("Detected binaryType support in WebSockets"),r=!0)}catch(e){}if(void 0===e&&(e="binary"),Array.isArray(e)&&e.indexOf("binary")>-1&&(e="binary"),!r)throw new Error("noVNC no longer supports base64 WebSockets. Please use a browser which supports binary WebSockets.");if("binary"!=e)throw new Error("noVNC no longer supports base64 WebSockets. Please use the binary subprotocol instead.");return e},open:function(e,t){var i=e.match(/^([a-z]+):\/\//)[1];t=this.init(t,i),this._websocket=new WebSocket(e,t),t.indexOf("binary")>=0&&(this._websocket.binaryType="arraybuffer"),this._websocket.onmessage=this._recv_message.bind(this),this._websocket.onopen=function(){if(Util.Debug(">> WebSock.onopen"),this._websocket.protocol?(this._mode=this._websocket.protocol,Util.Info("Server choose sub-protocol: "+this._websocket.protocol)):(this._mode="binary",Util.Error("Server select no sub-protocol!: "+this._websocket.protocol)),"binary"
|