public event EventHandler <UserTokenEventArgs> OnDataSendCompleted; // 数据发送完成 #endregion public SocketServer(int maxConnectionCount) { this.MaxConnectionCount = maxConnectionCount; this.UserDic = new ObjectManager <string, UserTokenEventArgs>(); for (int i = 0; i <= maxConnectionCount; i++) //按照连接数建立读写对象 { byte[] receiveBuffer = new byte[receiveBufferSize]; UserTokenEventArgs userToken = new UserTokenEventArgs(); userToken.RecvSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBufferSize); userToken.RecvSocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); recvStackPool.Push(userToken.RecvSocketAsyncEventArgs); SocketAsyncEventArgs sendSocketAsyncEventArgs = new SocketAsyncEventArgs(); sendSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBufferSize); sendSocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); sendStackPool.Push(sendSocketAsyncEventArgs); } maxNumberAcceptedClients = new Semaphore(maxConnectionCount, maxConnectionCount); // 初始信号量 tCheckClientHeartbeat = new Thread(CheckClientHeartbeat); //开启新线程检查心跳 tCheckClientHeartbeat.IsBackground = true; tCheckClientHeartbeat.Start(); }
private void ProcessAccept(SocketAsyncEventArgs e) { if (e.LastOperation != SocketAsyncOperation.Accept) //检查上一次操作是否是Accept,不是就返回 { return; } if (e.SocketError == SocketError.Success) { Socket sock = e.AcceptSocket; if (sock != null && sock.Connected) { SocketAsyncEventArgs recvSocketAsyncEventArgs = null; if (this.recvStackPool.TryPop(out recvSocketAsyncEventArgs)) { UserTokenEventArgs userToken = recvSocketAsyncEventArgs.UserToken as UserTokenEventArgs; userToken.ConnectTime = DateTime.Now; userToken.ActiveTime = DateTime.Now; userToken.UserSocket = sock; Interlocked.Increment(ref this.connectedSocketsCount); // 获得一个新的Guid 32位 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" userToken.ConnectedId = Guid.NewGuid().ToString("N"); try { this.UserDic.Add(userToken.ConnectedId, userToken);// 添加到集合中 EventHandler <UserTokenEventArgs> handler = OnClientConnect; if (handler != null) { handler(this, userToken);//抛出连接断开事件 } if (!userToken.UserSocket.ReceiveAsync(recvSocketAsyncEventArgs)) { ProcessReceive(recvSocketAsyncEventArgs); } } catch (Exception ex) { this.RaiseErrorEvent(userToken, ex); this.RaiseDisconnectedEvent(userToken); } } else { sock.Send(Encoding.Default.GetBytes("连接已经达到最大数!")); //已经达到最大客户连接数量,在这接受连接,发送“连接已经达到最大数”,然后断开连接 string outStr = String.Format("连接已满,拒绝 {0} 的连接。", sock.RemoteEndPoint); RaiseErrorEvent(null, new Exception(outStr)); sock.Close(); } } StartAccept(e);//投递接收请求 } }
//抛出错误事件 public void RaiseErrorEvent(UserTokenEventArgs token, Exception ex) { if (OnClientError != null) { if (null != token) { OnClientError(token, ex);//抛出客户端错误事件 } else { OnClientError(null, ex); } } }
public void RaiseDisconnectedEvent(UserTokenEventArgs userToken)//引发断开连接事件 { if (null != userToken && userToken.UserSocket != null) { try { EventHandler <UserTokenEventArgs> handler = OnClientDisconnect;//最先抛出事件 // 如果订户事件将为空(null) if (handler != null) { handler(this, userToken);//抛出连接断开事件 } if (this.customizeHander != null && !userToken.ConnectedId.IsNullEmpty()) { customizeHander.ClientClose(userToken); } userToken.Reset();//方便下一次使用 if (userToken.UserSocket.Connected) { try { userToken.UserSocket.Shutdown(SocketShutdown.Both); } catch { } } userToken.UserSocket.Close(); userToken.UserSocket = null; Interlocked.Decrement(ref connectedSocketsCount); maxNumberAcceptedClients.Release(); this.UserDic.Remove(userToken.ConnectedId); recvStackPool.Push(userToken.RecvSocketAsyncEventArgs);// 释放以使它们可以被其他客户端重新利用,总数不变 } catch (ObjectDisposedException) { // 抛出客户处理已经被关闭 } catch (Exception ex) { RaiseErrorEvent(userToken, ex); } finally { } } }
/// <summary> /// 异步接收操作完成时调用. 如果远程主机关闭连接Socket将关闭 /// </summary> private void ProcessReceive(SocketAsyncEventArgs e) { UserTokenEventArgs userToken = e.UserToken as UserTokenEventArgs; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { //Console.WriteLine("收到长度" + e.BytesTransferred + " 是否接受完毕" + userToken.UserSocket.Available); Interlocked.Add(ref receiveTotalBytes, e.BytesTransferred); // 增加接收到的字节总数 userToken.ActiveTime = DateTime.Now; //重置活动时间 userToken.ResvBufferManager.WriteBuffer(e.Buffer, e.Offset, e.BytesTransferred); try { EventHandler <UserTokenEventArgs> handler = OnClientRead;// 抛出接收到数据事件 if (handler != null) { handler(this, userToken); } if (!this.ProcessPacket(userToken))//如果处理数据返回失败,则断开连接 使用内置的处理 { RaiseDisconnectedEvent(userToken); } else { if (userToken.UserSocket != null && userToken.UserSocket.Connected) { bool willRaiseEvent = userToken.UserSocket.ReceiveAsync(e); //投递接收请求 if (!willRaiseEvent) { ProcessReceive(e); } } } } catch (Exception ex) { RaiseErrorEvent(userToken, ex); RaiseDisconnectedEvent(userToken); } } else { RaiseDisconnectedEvent(userToken); } }
public void Send(string connectionId, byte[] buffer) { UserTokenEventArgs userToken = UserDic.Get(connectionId); if (userToken == null || userToken.UserSocket == null) { return; } if (userToken.ClientType == ClientType.WebSocket) { buffer = WebSocketUtils.PackServerData(buffer);//或者使用DataFram } SocketAsyncEventArgs sendEventArgs = null; if (this.sendStackPool.TryPop(out sendEventArgs)) { try { sendEventArgs.UserToken = userToken; sendEventArgs.SetBuffer(buffer, 0, buffer.Length);//最后设置发送数据 //异步发送数据 //Array.Copy(buffer, 0, sendEventArgs.Buffer, 0, buffer.Length);//设置发送数据 bool willRaiseEvent = userToken.UserSocket.SendAsync(sendEventArgs);//采用异步发送才能处理sendStackPool if (!willRaiseEvent) { ProcessSend(sendEventArgs); } } catch (ObjectDisposedException)//调用此处的异步发送可能socket被其他进程关闭异常 { RaiseDisconnectedEvent(userToken); } catch (Exception ex) { RaiseErrorEvent(userToken, ex); RaiseDisconnectedEvent(userToken); } } }
/// <summary> /// 这个方法当一个异步发送操作完成时被调用. /// </summary> private void ProcessSend(SocketAsyncEventArgs e) { UserTokenEventArgs userToken = e.UserToken as UserTokenEventArgs; userToken.ActiveTime = DateTime.Now; Interlocked.Add(ref sendTotalBytes, e.BytesTransferred); // 增加发送的字节总数 // 回收SocketAsyncEventArgs以备再次被利用 userToken.SendBufferManager.Reset(); e.UserToken = null; // 清除UserToken对象引用 this.sendStackPool.Push(e); if (e.SocketError == SocketError.Success) { //发送完成后做清除,抛出事件等操作 这里暂时什么都不做 EventHandler <UserTokenEventArgs> handler = OnDataSendCompleted; if (handler != null) { handler(this, userToken);//抛出客户端发送完成事件 } } else { RaiseDisconnectedEvent(userToken); } }
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); }