Example #1
0
        void SendData(CodedOutputStream writer, SendQueueEntry data)
        {
            // Write to a temp buffer so we can inspect what we send
            var stream      = new MemoryStream();
            var temp_writer = CodedOutputStream.CreateInstance(stream);

            temp_writer.WriteRawByte(data.ServiceId);
            temp_writer.WriteUInt32NoTag(data.MethodId);
            temp_writer.WriteFixedUInt16(data.RequestId);
            if (data.ListenerId.HasValue)
            {
                temp_writer.WriteUInt32NoTag(data.ListenerId.Value);
            }

            temp_writer.WriteMessageNoTag(data.Message);
            temp_writer.Flush();

            var buffer = stream.ToArray();

            //Debug.WriteLine("Sending data: ");
            //Debug.WriteLine(buffer.ToHexString());

            writer.WriteRawBytes(buffer);
            writer.Flush();
        }
Example #2
0
        void WriteLoop()
        {
            var writer = CodedOutputStream.CreateInstance(socket.GetStream());

            while (socket.Connected)
            {
                try {
                    SendQueueEntry send_data = null;
                    lock (sendQueue) {
                        // Wait for messages in the send queue
                        while (sendQueue.Count == 0)
                        {
                            Monitor.Wait(sendQueue);
                        }

                        send_data = sendQueue.Dequeue();
                    }

                    SendData(writer, send_data);
                } catch (Exception e) {
                    Disconnect(e.Message);
                }
            }
        }
        private void SenderThread()
        {
            // mark this thread as a background thread
            Thread.CurrentThread.IsBackground = true;
            Thread.CurrentThread.Name         = "Dataset sender thread";

            // keep track of client to remove
            List <IPEndPoint> removeList = new List <IPEndPoint>();

            // enter the send queue lock
            Monitor.Enter(sendQueue);
            while (true)
            {
                if (sendQueue.Count == 0)
                {
                    Monitor.Wait(sendQueue);
                }

                // assume that now there is an entry in the queue
                if (sendQueue.Count > 0)
                {
                    // dequeue the entry
                    SendQueueEntry entry = sendQueue.Dequeue();

                    // fill up the buffer until we're at our target size
                    while (sendQueue.Count > 0)
                    {
                        SendQueueEntry nextEntry = sendQueue.Peek();
                        if (entry.length + nextEntry.length <= target_packet_size)
                        {
                            // add in this entry
                            // actually dequeue the entry
                            sendQueue.Dequeue();
                            // copy the next entry into our working buffer
                            Buffer.BlockCopy(nextEntry.buffer, 0, entry.buffer, entry.length, nextEntry.length);
                            // update the entry length
                            entry.length += nextEntry.length;

                            // free the next entry buffer
                            FreeBuffer(nextEntry.buffer);
                        }
                        else
                        {
                            // leave the loop, adding the next packet would go over the target size
                            break;
                        }
                    }

                    // increment the packet count and byte count
                    packetCount++;

                    // release the lock
                    Monitor.Exit(sendQueue);
                    try {
                        // acquire a reader lock
                        using (ReaderLock rl = new ReaderLock(listenerRWLock)) {
                            // clear the remove list
                            removeList.Clear();

                            // iterate through the listeners and send to each of them
                            foreach (IPEndPoint listener in listenerEndPoints)
                            {
                                try {
                                    sender.SendTo(entry.buffer, entry.length, SocketFlags.None, listener);
                                    byteCount += entry.length;
                                }
                                catch (Exception) {
                                    // for any client error, add to the remove list
                                    removeList.Add(listener);
                                }
                            }

                            // if there are listeners to remove, acquire a writer lock and remove them
                            // only wait for 20 milliseconds to get the writer lock to avoid blocking
                            using (WriterLock wl = rl.UpgradeToWriter(20)) {
                                foreach (IPEndPoint ep in removeList)
                                {
                                    listenerEndPoints.Remove(ep);
                                }
                            }

                            doSendDataValues = listenerEndPoints.Count > 0;
                        }
                    }
                    catch (Exception) {
                        // ignore any exceptions
                    }
                    finally {
                        // re-enter the send queue lock
                        Monitor.Enter(sendQueue);
                    }

                    // free the buffer entry
                    FreeBuffer(entry.buffer);
                }
            }
        }