Example #1
0
        /// <summary>
        /// Writes the message to a memory mapped file, where the memory mapped file name is WebsocketPipe.Address + id.
        /// mmf format: [wasread? 1 byte][datasize(int)][length(int)][msg][length(int)][msg]...
        /// If wasread=0, then writes the new message to the end of the message list and advances the number of messages +1.
        /// If wasread=1, clears the mmf and then writes the new message.
        /// </summary>
        /// <param name="wp">The calling WebsocketPipe</param>
        /// <param name="msg">The message to write.</param>
        /// <param name="to">The stream to write the mmf filename to.</param>
        /// <param name="id">The id of the targer we are writing to, since there may be many we open a mmf for each</param>
        public virtual void WriteMessage(WebsocketPipeMessageInfo msg, Stream to)
        {
            if (msg.Data.Length < this.UseInternalPacketDataSendingIfMsgByteSizeIsLessThen)
            {
                // write that this is an internal message.
                to.WriteByte(1);
                WebsocketAsInternalDataSocket.WriteMessage(msg, to);
                return;
            }

            // write that this is a mmf msg.
            to.WriteByte(0);

            // make the id and write it to the stream.
            string id = MakeValidMmfID(msg.DataSocketId);

            byte[] mmfnamebuffer = ASCIIEncoding.ASCII.GetBytes(id);
            to.Write(mmfnamebuffer, 0, mmfnamebuffer.Length);

            Mutex mu = new Mutex(false, id + "_mutex");

            if (!mu.WaitOne(MemoryMappedFileAccessTimeout))
            {
                throw new Exception("Memory mapped file access timedout.");
            }

            // The data size for a single message.
            int totalDataSize = msg.Data.Length + sizeof(int) + 1;

            // Creating/Opening the stream.
            MemoryMappedViewStream strm = GetDataWritingMemoryMappedViewStream(id, ref totalDataSize);

            // we are at the position of the write, and are ready for the message write.
            msg.WriteToStream(strm);

            strm.Flush();
            strm.Close();
            strm.Dispose();
            strm = null;

            // release the mutex.
            mu.ReleaseMutex();
        }
Example #2
0
        /// <summary>
        /// Reads the pending messages in the memory mapped file, where the memory mapped file name is in the stream from.
        /// mmf format: [wasread? 1 byte][datasize(int)][length(int)][msg][length(int)][msg]...
        /// If wasread=1, then ignores the read since the mmf was not written to, or was already read.
        /// If wasread=0, reads all pending messages and sets wasread to 1.
        /// </summary>
        /// <param name="wp"></param>
        /// <param name="from"></param>
        /// <returns></returns>
        public virtual IEnumerable <WebsocketPipeMessageInfo> ReadMessages(Stream from)
        {
            // reading the memory mapped file name or the msg bytes.
            if (from.ReadByte() == 1)
            {
                // internal message.
                return(WebsocketAsInternalDataSocket.ReadMessages(from));
            }

            // read the id from the from stram.
            StreamReader freader = new StreamReader(from, ASCIIEncoding.ASCII);
            string       id      = freader.ReadToEnd();

            // calling the mutex to verify reading.
            Mutex mu = new Mutex(false, id + "_mutex");

            if (!mu.WaitOne(MemoryMappedFileAccessTimeout))
            {
                throw new Exception("Wait timeout while attempting to read messages from mmf file with id: " + id);
            }

            MemoryMappedFile mmf    = MemoryMappedFile.OpenExisting(id);
            Stream           strm   = mmf.CreateViewStream(0, 0, MemoryMappedFileAccess.ReadWrite);
            BinaryReader     reader = new BinaryReader(strm);

            strm.Seek(0, SeekOrigin.Begin);

            BinaryReader msgreader       = null;
            int          totalDataLength = 0;

            if (strm.Length > MMFHeaderSize && reader.ReadByte() == 0)
            {
                // there is something we need to read.
                // reading all the contents.
                totalDataLength = reader.ReadInt32();

                if (totalDataLength > 0)
                {
                    msgreader = new BinaryReader(new MemoryStream(reader.ReadBytes(totalDataLength)));
                }

                // marking as read.
                strm.Seek(0, SeekOrigin.Begin);
                strm.WriteByte(1);
            }

            strm.Flush();
            strm.Close();
            strm.Dispose();

            // clearing the newly created mmf.
            mmf.Dispose();
            mmf = null;

            // release the mutex allowing others to write.
            mu.ReleaseMutex();
            mu.Dispose();
            mu     = null;
            reader = null;

            // return nothing...
            if (msgreader == null)
            {
                return(new WebsocketPipeMessageInfo[0]);
            }

            // reading the messages.
            strm = msgreader.BaseStream;
            msgreader.BaseStream.Seek(0, SeekOrigin.Begin);

            List <WebsocketPipeMessageInfo> msgs = new List <WebsocketPipeMessageInfo>();

            while (strm.Position < totalDataLength)
            {
                WebsocketPipeMessageInfo info = WebsocketPipeMessageInfo.FromStream(msgreader);
                if (info == null)
                {
                    break;  // something went wrong.
                }
                msgs.Add(info);
            }

            strm.Close();
            strm.Dispose();
            msgreader = null;
            strm      = null;
            return(msgs);
        }