public void TestReadTimeout() { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect("localhost", port); NetHelper helper = new NetHelper(); helper.Set(socket, 100); NetHeader header = new NetHeader(); byte[] bytes; bool ok = helper.ReadTimeout(200, ref header, out bytes); Assert.AreEqual(ok, false); helper.Close(); }
public void TestWriteRead() { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect("localhost", port); NetHelper helper = new NetHelper(); helper.Set(socket, 100); helper.WriteWithHeader(1, NetHelper.ToUTF8("status")); NetHeader header = new NetHeader(); byte[] bytes; helper.Read(ref header, out bytes); string beginExpected = "\n{\"status\":\"ok\""; string beginRead = NetHelper.FromUTF8(bytes).Substring(0, beginExpected.Length); Assert.AreEqual(beginExpected, beginRead); helper.Close(); }
public void Read(ref NetHeader header, out byte[] bytes) { int read = socket.Receive(headerBytes, 0, NetHeader.HEADER_SIZE, SocketFlags.None); if (read < NetHeader.HEADER_SIZE) { throw new Exception("Failed to read header."); } header.ReadFrom(headerBytes); bytes = new byte[header.MessageSize]; // read the rest of the message read = 0; while (header.MessageSize > read) { read += socket.Receive(bytes, read, (int)header.MessageSize - read, SocketFlags.None); } }
public bool ReadTimeout(int timeout, ref NetHeader header, out byte[] bytes) { bytes = null; try { socket.ReceiveTimeout = timeout; Read(ref header, out bytes); return true; } catch (SocketException e) { if (e.SocketErrorCode == SocketError.TimedOut) { return false; } else { throw e; } } }
public void WriteWithHeader(UInt32 requestId, byte[] bytes) { NetHeader header = new NetHeader((UInt32)bytes.Length, requestId); Write(header.GetBytes()); Write(bytes); }
private bool readTimeout(int timeout, ref NetHeader header, out byte[] bytes) { bytes = null; try { if (!rw.Valid()) throw new InvalidOperationException("Not connected"); return rw.ReadTimeout(timeout, ref header, out bytes); } catch (Exception e) { hardDisconnect(); throw e; } }
private void read(ref NetHeader header, out byte[] bytes) { const int MAX_READ_TIMEOUT_MILLISECONDS = 1000 * 60 * 3; bool timedout = readTimeout(MAX_READ_TIMEOUT_MILLISECONDS, ref header, out bytes); if (!timedout) { throw new TimeoutException(); } }
/// <summary> /// WaitForPubSub waits until the pubsubsql server publishes a message for /// the subscribed Client or until the timeout interval elapses. /// Returns false when timeout interval elapses. /// </summary> public bool WaitForPubSub(int timeout) { // timed out if (timeout <= 0) { return false; } // process backlog first reset(); if (backlog.Count > 0) { byte[] bytes = backlog.Dequeue(); unmarshalJSON(bytes); return true; } for (;;) { byte[] bytes = null; NetHeader header = new NetHeader(); // return on error if (!readTimeout(timeout, ref header, out bytes)) return false; // we got what we were looking for if (header.RequestId == 0) { unmarshalJSON(bytes); return true; } // this is not pubsub message; are we reading abandoned result set // ignore and continue reading do we want to adjust time out value here? // TODO? } }
/// <summary> /// NextRow is used to move to the next row in the result set returned by the pubsubsql server. /// When called for the first time, NextRow moves to the first row in the result set. /// Returns false when all rows are read. /// </summary> public bool NextRow() { for (;;) { // no resulst set if (response.Rows == 0) return false; if (response.Fromrow == 0 || response.Torow == 0) return false; // the current record is valid record++; if (record <= (response.Torow - response.Fromrow)) return true; // we reached the end of the result set if (response.Rows == response.Torow) { record--; return false; } // if we are here there is another batch reset(); NetHeader header = new NetHeader(); byte[] bytes = null; read(ref header, out bytes); if (header.RequestId > 0 && header.RequestId != this.requestId) { protocolError(); return false; } unmarshalJSON(bytes); } }
/// <summary> /// Execute executes a command against the pubsubsql server. /// The pubsubsql server returns to the Client a response in JSON format. /// </summary> public void Execute(string command) { reset(); write(command); NetHeader header = new NetHeader(); for (;;) { byte[] bytes = null; reset(); read(ref header, out bytes); if (header.RequestId == requestId) { // response we are waiting for unmarshalJSON(bytes); return; } else if (header.RequestId == 0) { // pubsub action, save it and skip it for now // will be proccesed next time WaitPubSub is called backlog.Enqueue(bytes); } else if (header.RequestId < this.requestId) { // we did not read full result set from previous command ignore it or flag and error? // for now lets ignore it, continue reading until we hit our request id reset(); } else { // this should never happen throw new Exception("Protocol error invalid requestId"); } } }