/// <summary> /// 将数据发送到远程端 /// </summary> /// <param name="client">客户端</param> /// <param name="cmd">数据包的Action值</param> /// <param name="parameters">参数列表</param> protected void InvokeRemote(SocketAsync <FastPacket> client, int cmd, params object[] parameters) { var packet = new FastPacket(cmd); packet.SetBodyBinary(this.Serializer, parameters); client.Send(packet); }
/// <summary> /// 当接收到客户端数据包时,将触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="packet">数据包</param> protected override void OnRecvComplete(SocketAsync <FastPacket> client, FastPacket packet) { var method = this.serverMethods.Find(item => item.ServiceAttribute.Command == packet.Command); if (method == null) { var exception = new Exception(string.Format("Command为{0}的数据包参数有误", packet.Command)); this.OnException(client, exception, packet); return; } // 如果是Cmd值对应是Self类型方法 也就是客户端主动调用服务方法 if (method.ServiceAttribute.Implement == Implements.Self) { this.InvokeService(method, client, packet); return; } // 如果是收到返回值 从回调表找出相关回调来调用 var callBack = CallbackTable.Take(packet.HashCode); if (callBack != null) { callBack.Invoke(packet.GetBodyParameter().FirstOrDefault()); } }
/// <summary> /// 发送数据到客户端 /// </summary> /// <param name="client">客户端</param> /// <param name="frameType">帧类型</param> /// <param name="bytes">内容</param> private void Send(SocketAsync <Hybi13Packet> client, FrameTypes frameType, byte[] bytes) { var packet = new ResponsePacket(); packet.SetBody(frameType, bytes); client.Send(packet); }
/// <summary> /// 当接收到远程端的数据时,将触发此方法 /// 此方法用于处理和分析收到的数据 /// 如果得到一个数据包,将触发OnRecvComplete方法 /// [注]这里只需处理一个数据包的流程 /// </summary> /// <param name="client">客户端</param> /// <param name="recvBuilder">接收到的历史数据</param> /// <returns>如果不够一个数据包,则请返回null</returns> protected override Hybi13Packet OnReceive(SocketAsync <Hybi13Packet> client, ByteBuilder recvBuilder) { if (client.IsConnected == false) { return(null); } // 获取处理接收的数据的容器 var resultBuilder = client.TagBag.ResultBuilder as ByteBuilder; // 说明不是第一次握手请求 if (resultBuilder != null) { return(RequestPacket.GetPacket(recvBuilder, resultBuilder)); } // 设置ResultBuilder client.TagBag.ResultBuilder = new ByteBuilder(); // 处理握手请求 var request = HandshakeRequest.Parse(recvBuilder.ToArrayThenClear()); if (request == null || this.CheckHandshake(client, request) == false) { this.CloseClient(client, CloseStatus.ProtocolError); } else { var packet = new ResponsePacket(); packet.SetHandshake(request.ToHandshake()); client.Send(packet); } return(null); }
/// <summary> /// 调用服务方法 /// </summary> /// <param name="method">方法</param> /// <param name="client">客户端对象</param> /// <param name="packet">数据</param> private void InvokeService(ServiceMethod method, SocketAsync <FastPacket> client, FastPacket packet) { // 执行Filter特性 foreach (var filter in method.Filters) { if (filter.OnExecuting(client, packet) == false) { return; } } try { var parameters = this.GetParameters(method, client, packet); var returnValue = method.Invoke(this, parameters); if (method.HasReturn && client.IsConnected) { packet.SetBodyBinary(this.Serializer, returnValue); client.Send(packet); } } catch (Exception ex) { this.OnException(client, ex, packet); } }
/// <summary> /// 向客户端发送关闭指令 /// 断开客户端的连接并回收利用client对象 /// </summary> /// <param name="client">客户端</param> /// <param name="reason">关闭原因</param> public void CloseClient(SocketAsync <Hybi13Packet> client, CloseStatus reason) { var reasonByes = ByteConverter.ToBytes((ushort)(reason), Endians.Big); this.Send(client, FrameTypes.Close, reasonByes); this.CloseClient(client); }
/// <summary> /// 完成一次策略请求解析 /// </summary> /// <param name="client">客户端</param> /// <param name="packet">请求的数据包</param> protected override void OnRecvComplete(SocketAsync <PolicyPacket> client, PolicyPacket packet) { string xml = "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0"; // 需要把字符串转为Char[] packet.Bytes = Encoding.UTF8.GetBytes(xml.ToCharArray()); client.Send(packet); Console.WriteLine(client.ToString()); }
/// <summary> /// 生成服务方法的调用参数 /// </summary> /// <param name="method">方法</param> /// <param name="client">客户端对象</param> /// <param name="packet">数据</param> private object[] GetParameters(ServiceMethod method, SocketAsync <FastPacket> client, FastPacket packet) { // 生成参数数组 var items = packet.GetBodyParameter(); var parameters = new object[items.Count + 1]; parameters[0] = client; for (var i = 0; i < items.Count; i++) { var param = this.Serializer.Deserialize(items[i], method.ParameterTypes[i + 1]); parameters[i + 1] = param; } return(parameters); }
/// <summary> /// 将数据发送到远程端 /// 并返回结果数据任务 /// </summary> /// <typeparam name="T">返回值类型</typeparam> /// <param name="client">客户端</param> /// <param name="cmd">数据包的命令值</param> /// <param name="parameters"></param> /// <returns>参数列表</returns> protected Task <T> InvokeRemote <T>(SocketAsync <FastPacket> client, int cmd, params object[] parameters) { var taskSource = new TaskCompletionSource <T>(); var packet = new FastPacket(cmd); packet.SetBodyBinary(this.Serializer, parameters); // 发送之前记录回参数 Action <byte[]> callBack = (bytes) => { // 收到数据后反序化 var result = (T)this.Serializer.Deserialize(bytes, typeof(T)); taskSource.SetResult(result); }; CallbackTable.Add(packet.HashCode, callBack); client.Send(packet); return(taskSource.Task); }
/// <summary> /// 当收到到数据包时,将触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="packet">数据包</param> protected override void OnRecvComplete(SocketAsync <Hybi13Packet> client, Hybi13Packet packet) { switch (packet.FrameType) { case FrameTypes.Close: var reason = CloseStatus.Empty; if (packet.Bytes.Length > 1) { var status = ByteConverter.ToUInt16(packet.Bytes, 0, Endians.Big); if (Enum.IsDefined(typeof(CloseStatus), status)) { reason = (CloseStatus)status; } } this.OnClose(client, reason); this.CloseClient(client); break; case FrameTypes.Binary: this.OnBinary(client, packet.Bytes); break; case FrameTypes.Text: var text = Encoding.UTF8.GetString(packet.Bytes); this.OnText(client, text); break; case FrameTypes.Ping: this.Send(client, FrameTypes.Pong, packet.Bytes); this.OnPing(client, packet.Bytes); break; case FrameTypes.Pong: this.OnPong(client, packet.Bytes); break; default: break; } }
public bool Login(SocketAsync <FastPacket> client, User user, bool ifAdmin) { if (user == null) { return(false); } Console.WriteLine("用户{0}登录操作...", user.Account); var dataBase = new List <User> { new User { Account = "abc", Password = "******" }, new User { Account = "admin", Password = "******" } }; var state = dataBase.Exists(item => item.Account == user.Account && item.Password == user.Password); // 登录客户是否已验证通过 client.TagBag.IsValidated = state; return(state); }
/// <summary> /// 完成一次策略请求解析 /// </summary> /// <param name="client">客户端</param> /// <param name="packet">请求的数据包</param> protected override void OnRecvComplete(SocketAsync <PolicyPacket> client, PolicyPacket packet) { var xml = new StringBuilder(); xml.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); xml.AppendLine("<access-policy>"); xml.AppendLine("<cross-domain-access>"); xml.AppendLine("<policy>"); xml.AppendLine("<allow-from>"); xml.AppendLine("<domain uri=\"*\"/>"); xml.AppendLine("</allow-from>"); xml.AppendLine("<grant-to>"); xml.AppendLine("<socket-resource port=\"4502-4534\" protocol=\"tcp\"/>"); xml.AppendLine("</grant-to>"); xml.AppendLine("</policy>"); xml.AppendLine("</cross-domain-access>"); xml.AppendLine("</access-policy>"); packet.Bytes = Encoding.UTF8.GetBytes(xml.ToString()); client.Send(packet); // 一定要关闭才生效 this.CloseClient(client); }
/// <summary> /// Ping客户端 /// </summary> /// <param name="client">客户端</param> /// <param name="bytes">内容</param> protected void SendPing(SocketAsync <Hybi13Packet> client, byte[] bytes) { this.Send(client, FrameTypes.Ping, bytes); }
/// <summary> /// 发送给客户端二进制内容 /// </summary> /// <param name="client">客户端</param> /// <param name="bytes">二进制内容</param> protected void SendBinary(SocketAsync <Hybi13Packet> client, byte[] bytes) { this.Send(client, FrameTypes.Binary, bytes); }
/// <summary> /// 发送给客户端文本内容 /// </summary> /// <param name="client">客户端</param> /// <param name="text">文本内容</param> protected void SendText(SocketAsync <Hybi13Packet> client, string text) { var bytes = Encoding.UTF8.GetBytes(text); this.Send(client, FrameTypes.Text, bytes); }
/// <summary> /// 收到客户端关闭信息 /// 在触发此方法后,基础类将自动安全关闭客户端 /// </summary> /// <param name="client">客户端</param> /// <param name="reason">关闭原因</param> protected virtual void OnClose(SocketAsync <Hybi13Packet> client, CloseStatus reason) { }
/// <summary> /// ping后客户端将回复pong触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="bytes">二进制内容</param> protected virtual void OnPong(SocketAsync <Hybi13Packet> client, byte[] bytes) { }
public Task <List <int> > SortByClient(SocketAsync <FastPacket> client, List <int> list) { return(this.InvokeRemote <List <int> >(client, 103, list)); }
/// <summary> /// 接收到策略请求 /// </summary> /// <param name="client">客户端</param> /// <param name="recvBuilder">数据</param> /// <returns></returns> protected override PolicyPacket OnReceive(SocketAsync <PolicyPacket> client, ByteBuilder recvBuilder) { return(PolicyPacket.GetPacket(recvBuilder)); }
public int GetSun(SocketAsync <FastPacket> client, int x, int y, int z) { Console.WriteLine("收到GetSum({0}, {1}, {2})", x, y, z); return(x + y + z); }
/// <summary> /// 当操作中遇到处理异常时,将触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="exception">异常</param> /// <param name="packet">相关数据事件</param> protected virtual void OnException(SocketAsync <FastPacket> client, Exception exception, FastPacket packet) { }
/// <summary> /// 异常时触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="exception">异常</param> /// <param name="FastPacket">封包</param> /// <param name="needReturn">是否需要返回数据</param> protected override void OnException(SocketAsync <FastPacket> client, Exception exception, FastPacket FastPacket) { base.OnException(client, exception, FastPacket); }
/// <summary> /// 接收到客户端断开连接 /// </summary> /// <param name="client">客户端</param> protected override void OnDisconnect(SocketAsync <FastPacket> client) { Console.WriteLine("客户端{0}断开连接,当前连接数为:{1}", client, this.AliveClients.Count); }
/// <summary> /// 收到文本请求时触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="text">文本内容</param> protected abstract void OnText(SocketAsync <Hybi13Packet> client, string text);
/// <summary> /// 收到二进制请求时触发此方法 /// </summary> /// <param name="client">客户端</param> /// <param name="bytes">二进制内容</param> protected abstract void OnBinary(SocketAsync <Hybi13Packet> client, byte[] bytes);
/// <summary> /// 在执行服务方法前触发 /// 如果返回false,将不执行服务方法 /// </summary> /// <param name="client">客户端</param> /// <param name="packet">数据包</param> /// <returns></returns> public abstract bool OnExecuting(SocketAsync <FastPacket> client, FastPacket packet);
/// <summary> /// 当收到握手请求时,将触发此方法 /// 返回true说明验证握手请求参数合格 /// 否则将安全关闭客户端 /// </summary> /// <param name="client">客户端</param> /// <param name="request">握手请求</param> /// <returns></returns> protected virtual bool CheckHandshake(SocketAsync <Hybi13Packet> client, HandshakeRequest request) { return(true); }
public void WarmingClient(SocketAsync <FastPacket> client, string title, string contents) { this.InvokeRemote(client, 102, title, contents); }