public UniRx.IObservable <HTTPResult> Invoke(JToken payload = null) { return(UniRx.Observable.Range(0, 1) .Select(_ => { if (is_connecting) { throw new Sas.Exception(Sas.ERRNO.REQUET_ALREADY_CONNECTING.ToErrCode()); } return _; }) .SelectMany(_ => { mShared.Add(mReq); if (payload == null) { return UniRx.Observable.Range(0, 1); } return mReq.GetRequestStreamAsObservable() .Select(stream => { mReq.ContentType = "application/json"; var packet = new PROTOCOL(); packet.ver = PROTOCOL.VERSION; packet.serial = mShared.send_cnt + 1; packet.utc = UnixDateTime.ToUnixTimeMilliseconds(System.DateTime.UtcNow); packet.command = "post"; packet.payload = payload; // new JArray(payload.ToList()); var pretty_json = Newtonsoft.Json.JsonConvert.SerializeObject(packet); var bytes = System.Text.Encoding.UTF8.GetBytes(pretty_json); stream.BeginWrite(bytes, 0, bytes.Length, (handle) => { stream.EndWrite(handle); stream.Dispose(); }, null); return _; }); }) .SelectMany(_ => { return UniRx.Observable.Create <HTTPResult> (observer => { var handle = mReq.GetResponseAsObservable() .Select(response => { using (var ostream = response.GetResponseStream()) { using (System.IO.StreamReader reader = new System.IO.StreamReader(ostream)) { ostream.Flush(); var data = reader.ReadToEnd(); var ret = new HTTPResult(); ret.req = mReq; ret.res = response; ret.param = payload; var root = JObject.Parse(data); ret.protocol = new PROTOCOL(); ret.protocol.ver = (long)root["ver"]; ret.protocol.utc = (long)root["utc"]; ret.protocol.serial = (long)root["serial"]; ret.protocol.command = (string)root["command"]; ret.protocol.payload = root["payload"]; if (ret.protocol.command == "error") { var jError = ret.protocol.GetPayload(token => { var obj = (JObject)token; var err = new Error { code = (int)obj["errno"], what = (string)obj["what"], }; return err; }); throw new Sas.Net.ExceptionRes(response, jError); } return ret; } } }) .Delay(TimeSpan.FromMilliseconds(1), UniRx.Scheduler.MainThread) .Do(protocol => mShared.Del(protocol.req, protocol.res)) .Subscribe(data => observer.OnNext(data), err => { var exception = new Net.ExceptionReq(mReq, payload, err); UniRx.Observable.Range(0, 1) .SubscribeOnMainThread() .Do(__ => { mShared.Del(mReq, null, exception); throw exception; }) .SubscribeOnMainThread() .Subscribe(__ => { }, inner => observer.OnError(inner)); }, () => observer.OnCompleted()); return UniRx.Disposable.Create(() => { handle.Dispose(); }); }); })); }