internal Transport(Reactor.IDuplexable<Reactor.Buffer> duplexable) { this.duplexable = duplexable; this.duplexable.OnData += (buffer) => { //------------------------------------------------- // WEB SOCKET FRAME PARSER //------------------------------------------------- var data = buffer.ToArray(); //------------------------------------------------- // if we have any leftovers...join to data.. //------------------------------------------------- if(this.unprocessed != null) { data = ByteData.Join(this.unprocessed, data); this.unprocessed = null; } //------------------------------------------------- // read in first frame... //------------------------------------------------- try { var frame = Frame.Parse(data, true); this.AcceptFrame(frame); data = ByteData.Unshift(data, (int)frame.FrameLength); } catch { // todo: catch multiple failed exceptions... or fix Frame.Parse this.unprocessed = data; return; } //----------------------------------------------- // read in additional frames... //----------------------------------------------- while (data.Length > 0) { try { var frame = Frame.Parse(data, true); this.AcceptFrame(frame); data = ByteData.Unshift(data, (int)frame.FrameLength); } catch { // todo: catch multiple failed exceptions... or fix Frame.Parse this.unprocessed = data; return; } } }; this.duplexable.OnEnd += () => { if(this.OnClose != null) { this.OnClose(); } }; var readable = duplexable as IReadable<Reactor.Buffer>; readable.OnError += (exception) => { if(this.OnError != null) { this.OnError(exception); } }; var writeable = duplexable as IWriteable<Reactor.Buffer>; writeable.OnError += (exception) => { if (this.OnError != null) { this.OnError(exception); } }; if (this.OnOpen != null) { this.OnOpen(); } }