/// <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)); }
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(); } }
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); }
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); }
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(); } }