Esempio n. 1
0
        internal static Task WriteAsync <T>(WebSocketConnection connection,
                                            WebSocketsFrame.OpCodes opCode,
                                            WebSocketsFrame.FrameFlags flags, ref T message)
            where T : struct, IMessageWriter
        {
            int payloadLength = message.GetPayloadLength();
            var buffer        = connection.Connection.Output.Alloc(MaxHeaderLength + payloadLength);
            int mask          = connection.ConnectionType == ConnectionType.Client ? CreateMask() : 0;

            WriteFrameHeader(ref buffer, WebSocketsFrame.FrameFlags.IsFinal, opCode, payloadLength, mask);
            if (payloadLength != 0)
            {
                if (mask == 0)
                {
                    message.WritePayload(buffer);
                }
                else
                {
                    var payloadStart = buffer.AsReadableBuffer().End;
                    message.WritePayload(buffer);
                    var payload = buffer.AsReadableBuffer().Slice(payloadStart); // note that this is a different AsReadableBuffer; call twice is good
                    WebSocketsFrame.ApplyMask(ref payload, mask);
                }
            }
            return(buffer.FlushAsync().AsTask());
        }
Esempio n. 2
0
        internal static void WriteFrameHeader(ref WritableBuffer output, WebSocketsFrame.FrameFlags flags, WebSocketsFrame.OpCodes opCode, int payloadLength, int mask)
        {
            output.Ensure(MaxHeaderLength);

            int index = 0;
            var span  = output.Buffer.Span;

            span[index++] = (byte)(((int)flags & 240) | ((int)opCode & 15));
            if (payloadLength > ushort.MaxValue)
            { // write as a 64-bit length
                span[index++] = (byte)((mask != 0 ? 128 : 0) | 127);
                span.Slice(index).Write((uint)0);
                span.Slice(index + 4).Write(ToNetworkByteOrder((uint)payloadLength));
                index += 8;
            }
            else if (payloadLength > 125)
            { // write as a 16-bit length
                span[index++] = (byte)((mask != 0 ? 128 : 0) | 126);
                span.Slice(index).Write(ToNetworkByteOrder((ushort)payloadLength));
                index += 2;
            }
            else
            { // write in the header
                span[index++] = (byte)((mask != 0 ? 128 : 0) | payloadLength);
            }
            if (mask != 0)
            {
                span.Slice(index).Write(mask);
                index += 4;
            }
            output.Advance(index);
        }
Esempio n. 3
0
 internal Task SendAsync(WebSocketsFrame.OpCodes opCode, ref Message message, WebSocketsFrame.FrameFlags flags = WebSocketsFrame.FrameFlags.IsFinal)
 {
     if (connection.Output.Writing.IsCompleted)
     {
         throw new InvalidOperationException("Connection has been closed");
     }
     return(SendAsyncImpl(opCode, message, flags));
 }
Esempio n. 4
0
        public Task SendAsync(byte[] message, WebSocketsFrame.FrameFlags flags = WebSocketsFrame.FrameFlags.IsFinal)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            var msg = MessageWriter.Create(message);

            return(SendAsync(WebSocketsFrame.OpCodes.Binary, ref msg, flags));
        }
        internal static unsafe void WriteFrameHeader(ref WritableBuffer output, WebSocketsFrame.FrameFlags flags, WebSocketsFrame.OpCodes opCode, int payloadLength, int mask)
        {
            byte *buffer = (byte *)output.Memory.BufferPtr;

            int bytesWritten;

            *buffer++ = (byte)(((int)flags & 240) | ((int)opCode & 15));
            if (payloadLength > ushort.MaxValue)
            { // write as a 64-bit length
                *buffer++ = (byte)((mask != 0 ? 128 : 0) | 127);
                *buffer++ = 0;
                *buffer++ = 0;
                *buffer++ = 0;
                *buffer++ = 0;
                *buffer++ = (byte)(payloadLength >> 24);
                *buffer++ = (byte)(payloadLength >> 16);
                *buffer++ = (byte)(payloadLength >> 8);
                *buffer++ = (byte)(payloadLength);
                bytesWritten = 10;
            }
            else if (payloadLength > 125)
            { // write as a 16-bit length
                *buffer++ = (byte)((mask != 0 ? 128 : 0) | 126);
                *buffer++ = (byte)(payloadLength >> 8);
                *buffer++ = (byte)(payloadLength);
                bytesWritten = 4;
            }
            else
            { // write in the header
                *buffer++ = (byte)((mask != 0 ? 128 : 0) | payloadLength);
                bytesWritten = 2;
            }
            if (mask != 0)
            {
                *buffer++ = (byte)(mask >> 24);
                *buffer++ = (byte)(mask >> 16);
                *buffer++ = (byte)(mask >> 8);
                *buffer++ = (byte)(mask);
                bytesWritten += 4;
            }
            output.CommitBytes(bytesWritten);
        }
Esempio n. 6
0
        private async Task SendAsyncImpl <T>(WebSocketsFrame.OpCodes opCode, T message, WebSocketsFrame.FrameFlags flags) where T : struct, IMessageWriter
        {
            //TODO: come up with a better way of getting ordered access to the socket
            var  writeLock = GetWriteSemaphore();
            bool haveLock  = writeLock.Wait(0);

            if (!haveLock)
            {   // try to acquire asynchronously instead, then
                await writeLock.WaitAsync();
            }
            try
            {
                WebSocketServer.WriteStatus(ConnectionType, $"Writing {opCode} message ({message.GetPayloadLength()} bytes)...");
                await WebSocketProtocol.WriteAsync(this, opCode, flags, ref message);

                if (opCode == WebSocketsFrame.OpCodes.Close)
                {
                    connection.Output.Complete();
                }
            }
            finally
            {
                writeLock.Release();
            }
        }
Esempio n. 7
0
 internal Task SendAsync <T>(WebSocketsFrame.OpCodes opCode, ref T message, WebSocketsFrame.FrameFlags flags = WebSocketsFrame.FrameFlags.IsFinal) where T : struct, IMessageWriter
 {
     return(SendAsyncImpl(opCode, message, flags));
 }