Ejemplo n.º 1
0
    /// <summary>
    /// Processes a request to determine if it is a WebSocket request, and if so,
    /// sets the <see cref="IHttpWebSocketFeature"/> on the <see cref="HttpContext.Features"/>.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> representing the request.</param>
    /// <returns>The <see cref="Task"/> that represents the completion of the middleware pipeline.</returns>
    public Task Invoke(HttpContext context)
    {
        // Detect if an opaque upgrade is available. If so, add a websocket upgrade.
        var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>();
        var connectFeature = context.Features.Get <IHttpExtendedConnectFeature>();

        if ((upgradeFeature != null || connectFeature != null) && context.Features.Get <IHttpWebSocketFeature>() == null)
        {
            var webSocketFeature = new WebSocketHandshake(context, upgradeFeature, connectFeature, _options, _logger);
            context.Features.Set <IHttpWebSocketFeature>(webSocketFeature);
            if (!_anyOriginAllowed)
            {
                // Check for Origin header
                var originHeader = context.Request.Headers.Origin;

                if (!StringValues.IsNullOrEmpty(originHeader) && webSocketFeature.IsWebSocketRequest)
                {
                    // Check allowed origins to see if request is allowed
                    if (!_allowedOrigins.Contains(originHeader.ToString(), StringComparer.Ordinal))
                    {
                        _logger.LogDebug("Request origin {Origin} is not in the list of allowed origins.", originHeader.ToString());
                        context.Response.StatusCode = StatusCodes.Status403Forbidden;
                        return(Task.CompletedTask);
                    }
                }
            }
        }

        return(_next(context));
    }
Ejemplo n.º 2
0
        public void Open(string aURI, string aSubProtocol, int aTimeout, int aVersion)
        {
            try
            {
                if (mLog.IsDebugEnabled)
                {
                    mLog.Debug(WebSocketMessage.ESTABLiSHING_CONNECTION + WebSocketMessage.SEPARATOR
                               + WebSocketMessage.URL + aURI + WebSocketMessage.SEPARATOR + WebSocketMessage.SUBPROTOCOL
                               + aSubProtocol + WebSocketMessage.SEPARATOR + WebSocketMessage.TIMEOUT
                               + aTimeout + WebSocketMessage.SEPARATOR + WebSocketMessage.VERSION + aVersion);
                }

                mStatus = WebSocketStatus.OPENING;

                mVersion = aVersion;
                mURI     = new Uri(aURI);

                WebSocketHandshake lHandshake = new WebSocketHandshake(mURI, aSubProtocol, mVersion, mCookieManage);

                if (mSocket != null && mSocket.Connected)
                {
                    mSocket.Close();
                }
                CreateSocket();

                byte[] sendBuffer = lHandshake.GenerateC2SRequest();
                mNetStream.Write(sendBuffer, 0, sendBuffer.Length);
                mNetStream.Flush();

                mStatus = WebSocketStatus.CONNECTING;

                mHeaders.ReadRequestFromBuffer(sendBuffer);
                if (mLog.IsDebugEnabled)
                {
                    mLog.Debug(WebSocketMessage.SENDING_HANDSHAKE + mHeaders.ToStringRequest());
                }

                WebSocketTimeout.CallWithTimeout(mHeaders.ReadResponseFromStream, aTimeout, mNetStream);

                mCookieManage.AddCookies(mHeaders.GetCookies, mURI);

                if (mLog.IsDebugEnabled)
                {
                    mLog.Debug(WebSocketMessage.RECEIVING_HANDSHAKE + mHeaders.ToStringResponse());
                }

                lHandshake.VerifyS2CResponse(mHeaders);

                string lProtocol = GetResponseHeaderField(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL);

                if (lProtocol != null)
                {
                    mNegotiatedSubProtocol = new WebSocketSubProtocol(lProtocol, mEncoding);
                }
                else
                {
                    mNegotiatedSubProtocol = new WebSocketSubProtocol(WebSocketConstants.WS_SUBPROT_DEFAULT,
                                                                      WebSocketConstants.WS_ENCODING_DEFAULT);
                }

                Thread lReciver = new Thread(new ThreadStart(Receiver));
                lReciver.Start();

                if (mLog.IsInfoEnabled)
                {
                    mLog.Info(WebSocketMessage.CONNECTION_HAS_BEEN_ESTABLISHED);
                }

                mStatus    = WebSocketStatus.OPENED;
                mIsRunning = true;
                OnOpenConnection(mHeaders);
            }
            catch (TimeoutException lTe)
            {
                if (mLog.IsErrorEnabled)
                {
                    mLog.Error(WebSocketMessage.EXCEEDED_FOR_CONNECTION + WebSocketMessage.SEPARATOR
                               + WebSocketMessage.DETAILS + lTe.Message);
                }
                mCLose = WebSocketCloseReason.TIMEOUT;
                OnCloseConnection(mCLose);
                OnError(new WebSocketError(WebSocketMessage.TIMEOUT + WebSocketMessage.EXCEEDED_FOR_CONNECTION, mCLose));
                CheckReconnect();
            }
            catch (Exception lEx)
            {
                if (mLog.IsErrorEnabled)
                {
                    mLog.Error(WebSocketMessage.NOT_ESTABLISH_CONNECTION + WebSocketMessage.SEPARATOR
                               + WebSocketMessage.DETAILS + lEx.Message);
                }
                mCLose = WebSocketCloseReason.BROKEN;
                OnCloseConnection(mCLose);
                OnError(new WebSocketError(WebSocketMessage.NOT_ESTABLISH_CONNECTION, mCLose));
                CheckReconnect();
            }
        }
Ejemplo n.º 3
0
        private bool ProcessPacket(UserTokenEventArgs userToken)
        {
            if (userToken.ClientType != ClientType.WebSocket)//第一次进来握手操作
            {
                byte[]             info      = userToken.bufferManager.GetCopyBuffer();
                WebSocketHandshake handshake = new WebSocketHandshake(info);
                if (handshake.IsWebSocket)
                {
                    userToken.Socket.Send(Encoding.UTF8.GetBytes(handshake.Response));
                    userToken.bufferManager.Reset();
                    userToken.ClientType = ClientType.WebSocket;
                    handshake            = null;
                    return(true);
                }
            }

            if (userToken.ClientType == ClientType.WebSocket)
            {
                int bodyLen         = 0;
                int informationType = -1;
                #region 处理WebSocket
                while (userToken.ResvBufferManager.Length > 6)
                {
                    if (userToken.ResvBufferManager.Length % this.receiveBufferSize == 0) //客户端一次发送的数据大于服务端缓冲区
                    {
                        return(true);
                    }
                    if (userToken.ResvBufferManager.Length >= 1024 * 120)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("单个包发送不能大于120K"));
                        return(false);
                    }
                    int clearCount = 0;

                    DataFrame dr = new DataFrame(userToken.ResvBufferManager.Buffer, ref clearCount);
                    if (dr.Header.OpCode == OpCode.Close)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("用户主动断开"));
                        return(false);
                    }
                    if (dr.Header.OpCode == OpCode.Binary)
                    {
                        #region 正常解析为二进制

                        byte[] hasAnalyzeData = dr.BinaryContent;
                        bodyLen = BitConverter.ToInt32(hasAnalyzeData, 0);              //包长
                        if (userToken.ResvBufferManager.Length >= bodyLen + clearCount) //包足够的情况
                        {
                            informationType = BitConverter.ToInt16(hasAnalyzeData, 4);  //消息类型
                            if (informationType > Int16.MaxValue || informationType < 0 || bodyLen > this.maxPacketLength | userToken.ResvBufferManager.Length > this.maxPacketLength)
                            {
                                this.RaiseErrorEvent(userToken, new Exception("解析消息类型错误|包长度超过最大长度"));
                                return(false);
                            }
                            if (informationType == 998)
                            {
                                int userIdLen = hasAnalyzeData[6];
                                if (userIdLen > this.maxUserIdlength)
                                {
                                    this.RaiseErrorEvent(userToken, new Exception("UserId长度过长"));
                                    return(false);
                                }
                                string userId    = Encoding.UTF8.GetString(BytesHelper.CopyArrayData(hasAnalyzeData, 7, this.maxUserIdlength)).Replace("\0", "");
                                string failCause = string.Empty;
                                if (this.customizeHander != null && !customizeHander.CheckLoginUser("ABC", userId, "", out failCause))
                                {
                                    this.RaiseErrorEvent(userToken, new Exception(failCause));
                                    return(false);
                                }
                                this.UserDic.Add(userId, userToken);//添加登录用户才可以发送
                                userToken.ConnectedId = userId;
                                userToken.SendBufferManager.WriteInt16((short)informationType);
                                userToken.SendBufferManager.WriteString0(failCause);
                                this.Send(userId, userToken.SendBufferManager.GetCopyBuffer());
                                Console.WriteLine(string.Format("用户{0}登录成功---" + DateTime.Now, userId));
                                userToken.ResvBufferManager.Reset();
                                userToken.SendBufferManager.Reset();
                            }
                            else
                            {
                                if (string.IsNullOrEmpty(userToken.ConnectedId))
                                {
                                    this.RaiseErrorEvent(userToken, new Exception(string.Format("用户{0}未登录;InfomationType:{1}", userToken.UserSocket.RemoteEndPoint, informationType)));
                                    return(false);
                                }
                                if (hasAnalyzeData.Length < bodyLen)
                                {
                                    Console.WriteLine("***********************" + bodyLen);
                                    userToken.ResvBufferManager.Clear(clearCount);
                                    //return true;
                                }

                                byte[] content = BytesHelper.CopyArrayData(hasAnalyzeData, 6, hasAnalyzeData.Length - 6);
                                if (this.customizeHander != null)
                                {
                                    customizeHander.HandleInformation(userToken, userToken.ConnectedId, informationType, content);
                                }

                                // Console.WriteLine(" FBL:" + userToken.bufferManager.Length + " BOdyLen:" + bodyLen + " HL:" + hasAnalyzeData.Length + " clearCount:" + clearCount);
                                userToken.ResvBufferManager.Clear(bodyLen + clearCount);
                            }
                        }
                        else
                        {
                            return(true);
                        }

                        #endregion
                    }
                    else
                    {
                        Console.WriteLine("OP:" + dr.Header.OpCode + "____出现此错误可能包长度不对");
                        userToken.ResvBufferManager.Reset(true);
                        return(true);
                    }
                }
                #endregion
            }
            if (userToken.ClientType == ClientType.DotNET)//继续处理其他平台
            {
            }
            return(true);
        }
Ejemplo n.º 4
0
        private bool ProcessPacket(UserTokenEventArgs userToken)
        {
            if (userToken.ClientType != ClientType.WebSocket)//第一次进来握手操作
            {
                byte[]             recvMsg   = userToken.ResvBufferManager.GetCopyBuffer();
                WebSocketHandshake handshake = new WebSocketHandshake(recvMsg);
                if (handshake.IsWebSocket)
                {
                    userToken.UserSocket.Send(Encoding.UTF8.GetBytes(handshake.Response));
                    userToken.ResvBufferManager.Reset();
                    userToken.ClientType = ClientType.WebSocket;
                }
                handshake = null;
                return(true);
            }
            if (userToken.ClientType == ClientType.WebSocket)
            {
                #region 处理WebSocket
                try
                {
                    if (userToken.ResvBufferManager.Length % this.receiveBufferSize == 0) //客户端一次发送的数据大于服务端缓冲区
                    {
                        return(true);
                    }
                    if (userToken.ResvBufferManager.Length >= 1024 * 120)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("WebSocket暂不能解析大于120K的单个包"));
                        return(false);
                    }
                    while (userToken.ResvBufferManager.Length != 0)
                    {
                        int       clearCount = 0;
                        DataFrame dr         = new DataFrame(userToken.ResvBufferManager.Buffer, ref clearCount);
                        if (dr.Header.OpCode == OpCode.Close)
                        {
                            this.RaiseErrorEvent(userToken, new Exception("33333333333用户主动断开"));
                            return(false);
                        }
                        if (dr.Header.OpCode == OpCode.Binary)
                        {
                            #region 正常解析为二进制


                            MessageHeader header = new MessageHeader();
                            header.ProccessHeader(dr.BinaryContent);
                            if (header.MessageId > UInt16.MaxValue || header.MessageId < 0 || header.PacketLength > this.maxPacketLength | userToken.ResvBufferManager.Length > this.maxPacketLength)
                            {
                                this.RaiseErrorEvent(userToken, new Exception("解析消息类型错误|包长度超过最大长度"));
                                return(false);
                            }
                            if (userToken.ResvBufferManager.Length < header.PacketLength + clearCount)//包不足够的情况
                            {
                                return(true);
                            }
                            byte[]     content    = BytesHelper.CopyArrayData(dr.BinaryContent, header.Length, dr.BinaryContent.Length - header.Length);
                            NetMessage netMessage = new NetMessage(header, content);
                            userToken.NetMessage = netMessage;
                            //userToken.ResvBufferManager.SetOffset(header.Length-1);
                            if (this.customizeHander != null)
                            {
                                customizeHander.HandleInformation(userToken);
                                //customizeHander.HandleInformation(userToken, userToken.ConnectedId, netMessage.Header.MessageId, content);
                            }
                            userToken.ResvBufferManager.Clear(header.PacketLength + clearCount);
                            #endregion
                        }
                        else
                        {
                            this.RaiseErrorEvent(userToken, new Exception("WebScoket未能正确解析包 OP代码" + dr.Header.OpCode));
                            userToken.ResvBufferManager.Reset();
                            return(true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.RaiseErrorEvent(userToken, new Exception("处理WebSocket包出现异常:" + ex.ToString()));
                    return(false);
                }
                #endregion
            }
            if (userToken.ClientType == ClientType.DotNET)//继续处理其他平台
            {
                //string userId = userToken.UserSocket.RemoteEndPoint.ToString();
            }
            return(true);
        }
Ejemplo n.º 5
0
        public void Open(string aURI, string aSubProtocol, int aTimeout, int aVersion)
        {
            try
            {
                if (mLog.IsDebugEnabled)
                    mLog.Debug(WebSocketMessage.ESTABLiSHING_CONNECTION + WebSocketMessage.SEPARATOR
                        + WebSocketMessage.URL + aURI + WebSocketMessage.SEPARATOR + WebSocketMessage.SUBPROTOCOL
                        + aSubProtocol + WebSocketMessage.SEPARATOR + WebSocketMessage.TIMEOUT
                        + aTimeout + WebSocketMessage.SEPARATOR + WebSocketMessage.VERSION + aVersion);

                mStatus = WebSocketStatus.OPENING;

                mVersion = aVersion;
                mURI = new Uri(aURI);

                WebSocketHandshake lHandshake = new WebSocketHandshake(mURI, aSubProtocol, mVersion,mCookieManage);

                if (mSocket != null && mSocket.Connected)
                    mSocket.Close();
                 CreateSocket();

                byte[] sendBuffer = lHandshake.GenerateC2SRequest();
                mNetStream.Write(sendBuffer, 0, sendBuffer.Length);
                mNetStream.Flush();

                mStatus = WebSocketStatus.CONNECTING;

                mHeaders.ReadRequestFromBuffer(sendBuffer);
                if (mLog.IsDebugEnabled)
                    mLog.Debug(WebSocketMessage.SENDING_HANDSHAKE + mHeaders.ToStringRequest());

                WebSocketTimeout.CallWithTimeout(mHeaders.ReadResponseFromStream, aTimeout, mNetStream);

                mCookieManage.AddCookies(mHeaders.GetCookies, mURI);

                if (mLog.IsDebugEnabled)
                    mLog.Debug(WebSocketMessage.RECEIVING_HANDSHAKE + mHeaders.ToStringResponse());

                lHandshake.VerifyS2CResponse(mHeaders);

                string lProtocol = GetResponseHeaderField(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL);

                if (lProtocol != null)
                    mNegotiatedSubProtocol = new WebSocketSubProtocol(lProtocol, mEncoding);
                else
                    mNegotiatedSubProtocol = new WebSocketSubProtocol(WebSocketConstants.WS_SUBPROT_DEFAULT,
                        WebSocketConstants.WS_ENCODING_DEFAULT);

                Thread lReciver = new Thread(new ThreadStart(Receiver));
                lReciver.Start();

                if (mLog.IsInfoEnabled)
                    mLog.Info(WebSocketMessage.CONNECTION_HAS_BEEN_ESTABLISHED);

                mStatus = WebSocketStatus.OPENED;
                mIsRunning = true;
                OnOpenConnection(mHeaders);
            }
            catch (TimeoutException lTe)
            {
                if (mLog.IsErrorEnabled)
                    mLog.Error(WebSocketMessage.EXCEEDED_FOR_CONNECTION + WebSocketMessage.SEPARATOR
                        + WebSocketMessage.DETAILS + lTe.Message);
                mCLose = WebSocketCloseReason.TIMEOUT;
                OnCloseConnection(mCLose);
                OnError(new WebSocketError(WebSocketMessage.TIMEOUT + WebSocketMessage.EXCEEDED_FOR_CONNECTION, mCLose));
                CheckReconnect();
            }
            catch (Exception lEx)
            {
                if (mLog.IsErrorEnabled)
                    mLog.Error(WebSocketMessage.NOT_ESTABLISH_CONNECTION + WebSocketMessage.SEPARATOR
                        + WebSocketMessage.DETAILS + lEx.Message);
                mCLose = WebSocketCloseReason.BROKEN;
                OnCloseConnection(mCLose);
                OnError(new WebSocketError(WebSocketMessage.NOT_ESTABLISH_CONNECTION, mCLose));
                CheckReconnect();
            }
        }