public void Close() { lock (stateLock) { if (state != State.Started) { return; } state = State.Closing; DemonitorTask(receiver); receiver.Stop(); DemonitorTask(receiver); sender.Stop(); socket.Send(BinaryMessage.Make(MSG_CLOSE).Complete()); // HACK: otherwise close message may not be sent Thread.Sleep(TimeSpan.FromMilliseconds(5)); socket.Close(); state = State.Closed; } Dispatcher.Dispatch(new ExitMessage()); }
public void Send(BinaryMessage message) { var buffer = new byte[message.Length + 1]; buffer[0] = message.Type; Array.Copy(message.GetData(), 0, buffer, 1, message.Length); socket.Send(buffer); }
public PendingMessage(ushort seq, BinaryMessage message) { Type = message.Type; Content = message.GetData(); Seq = seq; Last = DateTime.Now; RetryCount = 0; }
protected void AckGobData(long gobId, int frame) { var message = BinaryMessage.Make(MSG_OBJACK) .UInt32((uint)gobId) .Int32(frame) .Complete(); // FIXME: make it smarter socket.Send(message); }
public void SendSeqMessage(BinaryMessage message) { lock (pending) { pending.Add(new PendingMessage(pendingSeq, message)); pendingSeq++; } lock (thisLock) Monitor.PulseAll(thisLock); }
public void ReadWriteTest() { var input = BinaryMessage.Make(1) .String("Test") .UInt16(64) .String("Test2") .Complete(); var output = new BinaryMessage(1, input.GetData()); Assert.AreEqual(output.Type, input.Type); using (var reader = output.GetReader()) { Assert.AreEqual("Test", reader.ReadCString()); Assert.AreEqual(64, reader.ReadUInt16()); Assert.AreEqual("Test2", reader.ReadCString()); } }
private void ReceiveMessage(BinaryMessage msg) { var reader = msg.GetReader(); switch (msg.Type) { case MSG_REL: var seq = reader.ReadUInt16(); while (reader.HasRemaining) { var type = reader.ReadByte(); int len; if ((type & 0x80) != 0) // is not last? { type &= 0x7f; len = reader.ReadUInt16(); } else { len = (int)reader.Remaining; } ReceiveSeqMessage(seq, new BinaryMessage(type, reader.ReadBytes(len))); seq++; } break; case MSG_ACK: sender.ReceiveAck(reader.ReadUInt16()); break; case MSG_MAPDATA: HandleMapData(msg.GetReader()); break; case MSG_OBJDATA: HandleGobData(msg.GetReader()); break; case MSG_CLOSE: Close(); return; } }
private void ReceiveSeqMessage(ushort seq, BinaryMessage msg) { if (seq == rseq) { HandleSeqMessage(msg); while (true) { rseq++; if (!waiting.Remove(rseq, out msg)) { break; } HandleSeqMessage(msg); } sender.SendAck((ushort)(rseq - 1)); } else if (seq > rseq) { waiting[seq] = msg; } }
public bool Receive(out BinaryMessage message) { if (!socket.Poll(receiveTimeout * 1000, SelectMode.SelectRead)) { message = null; return(false); } int size = socket.Receive(receiveBuffer); if (size == 0) { throw new Exception("Couldn't receive data from socket"); } var type = receiveBuffer[0]; var buffer = new byte[size - 1]; Array.Copy(receiveBuffer, 1, buffer, 0, size - 1); message = new BinaryMessage(type, buffer); return(true); }
protected void SendSeqMessage(BinaryMessage message) { sender.SendSeqMessage(message); }
protected void Send(BinaryMessage message) { socket.Send(message); }
protected abstract void HandleSeqMessage(BinaryMessage message);
protected override void OnStart() { var last = DateTime.Now; while (!IsCancelled) { var to = TimeSpan.FromMilliseconds(5000); var now = DateTime.Now; var beat = true; lock (pending) { if (pending.Count > 0) { to = TimeSpan.FromMilliseconds(60); } } lock (thisLock) { if (ackTime.HasValue) { to = ackTime.Value - now + TimeSpan.FromMilliseconds(AckThreshold); } if (to.TotalMilliseconds > 0) { Monitor.Wait(thisLock, to); } } lock (pending) { foreach (var msg in pending) { int txtime; if (msg.RetryCount == 0) { txtime = 0; } else if (msg.RetryCount == 1) { txtime = 80; } else if (msg.RetryCount < 4) { txtime = 200; } else if (msg.RetryCount < 10) { txtime = 620; } else { txtime = 2000; } if ((now - msg.Last).TotalMilliseconds > txtime) { msg.Last = now; msg.RetryCount++; var rmsg = BinaryMessage.Make(ProtocolHandlerBase.MSG_REL) .UInt16(msg.Seq) .Byte(msg.Type) .Bytes(msg.Content) .Complete(); socket.Send(rmsg); beat = false; } } } lock (thisLock) { if (ackTime.HasValue && ((now - ackTime.Value).TotalMilliseconds >= AckThreshold)) { socket.Send(BinaryMessage.Make(ProtocolHandlerBase.MSG_ACK).UInt16(ackSeq).Complete()); ackTime = null; beat = false; } } if (beat) { if ((now - last).TotalMilliseconds > KeepAliveTimeout) { socket.Send(BinaryMessage.Make(ProtocolHandlerBase.MSG_BEAT).Complete()); last = now; } } } }