解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
23.76 KiB
X
# NewLife.Net ÍøÂç¿âʹÓÃÊÖ²á ## Ŀ¼ - [¸ÅÊö](/NewLife/X/Blob/dev/Doc/#¸ÅÊö) - [¼Ü¹¹Éè¼Æ](/NewLife/X/Blob/dev/Doc/#¼Ü¹¹Éè¼Æ) - [¿ìËÙÈëÃÅ](/NewLife/X/Blob/dev/Doc/#¿ìËÙÈëÃÅ) - [ºËÐÄ×é¼þ](/NewLife/X/Blob/dev/Doc/#ºËÐÄ×é¼þ) - [¸ß¼¶ÌØÐÔ](/NewLife/X/Blob/dev/Doc/#¸ß¼¶ÌØÐÔ) - [×î¼Ñʵ¼ù](/NewLife/X/Blob/dev/Doc/#×î¼Ñʵ¼ù) - [ÐÔÄÜÓÅ»¯](/NewLife/X/Blob/dev/Doc/#ÐÔÄÜÓÅ»¯) - [³£¼ûÎÊÌâ](/NewLife/X/Blob/dev/Doc/#³£¼ûÎÊÌâ) --- ## ¸ÅÊö NewLife.Net ÊÇÐÂÉúÃüÍŶӿª·¢µÄ¸ßÐÔÄÜÍøÂçͨÐſ⣬֧³Ö TCP/UDP ЭÒ飬ͬʱ¼æÈÝ IPv4 ºÍ IPv6¡£¸Ã¿âÉè¼Æ¾«Á¼£¬¾Ã¾­Éú²ú»·¾³¿¼Ñ飬ÊÊÓÃÓÚ¹¹½¨¸÷ÖÖÍøÂçÓ¦Ó÷þÎñÆ÷¡£ ### ÌØÐÔ - **¶àЭÒéÖ§³Ö**£ºÍ¬Ê±Ö§³Ö TCP ºÍ UDP ЭÒé - **˫ջ֧³Ö**£ºÍêÃÀÖ§³Ö IPv4 ºÍ IPv6 - **¸ßÐÔÄÜ**£º»ùÓÚÒì²½ IO Ä£ÐÍ£¬Ê¹Óà IOCP ʵÏָ߲¢·¢ - **¹ÜµÀ´¦Àí**£ºÁé»îµÄÏûÏ¢¹ÜµÀ£¬Ö§³ÖЭÒé±à½âÂë - **SSL/TLS**£ºÔ­ÉúÖ§³Ö°²È«´«Êä - **»á»°¹ÜÀí**£ºÍêÉÆµÄÁ¬½Ó»á»°¹ÜÀí»úÖÆ - **Ḭ̈߳²È«**£ºËùÓкËÐIJÙ×÷²ÉÓÃÔ­×Ó²Ù×÷±£Ö¤Ḭ̈߳²È« - **¿ÉÀ©Õ¹**£ºÒ×ÓÚÀ©Õ¹µÄ¼Ü¹¹Éè¼Æ ### ÊÊÓó¡¾° - ¼´Ê±Í¨Ñ¶·þÎñÆ÷ - ÓÎÏ··þÎñÆ÷ - ÎïÁªÍøÊý¾Ý²É¼¯ - RPC Ô¶³Ìµ÷Óà - ×Ô¶¨ÒåЭÒé·þÎñ --- ## ¼Ü¹¹Éè¼Æ ### ÕûÌå¼Ü¹¹ ``` ©°©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©´ ©¦ Ó¦Óò㠩¦ ©¦ NetServer / NetServer<TSession> ©¦ ©¦ ©À©¤©¤ INetSession (»á»°¹ÜÀí) ©¦ ©¦ ©À©¤©¤ INetHandler (Êý¾Ý´¦ÀíÆ÷) ©¦ ©¦ ©¸©¤©¤ Pipeline (ÏûÏ¢¹ÜµÀ) ©¦ ©À©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©È ©¦ Socket·þÎñ²ã ©¦ ©¦ ISocketServer ©¦ ©¦ ©À©¤©¤ TcpServer (TCP·þÎñ¶Ë) ©¦ ©¦ ©¸©¤©¤ UdpServer (UDP·þÎñ¶Ë) ©¦ ©À©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©È ©¦ Socket»á»°²ã ©¦ ©¦ ISocketSession ©¦ ©¦ ©À©¤©¤ TcpSession (TCP»á»°) ©¦ ©¦ ©¸©¤©¤ UdpSession (UDP»á»°) ©¦ ©À©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©È ©¦ »ù´¡ÉèÊ©²ã ©¦ ©¦ SessionBase ©¦ ©¦ ©À©¤©¤ ProcessEvent (ºËÐĽÓÊÕ´¦Àí) ©¦ ©¦ ©À©¤©¤ Òì²½IO (SocketAsyncEventArgs) ©¦ ©¦ ©¸©¤©¤ »º³åÇø¹ÜÀí ©¦ ©¸©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¤©¼ ``` ### ºËÐÄÀà¹ØÏµ ``` NetServer ©À©¤©¤ ISocketServer[] Servers // Socket·þÎñÆ÷¼¯ºÏ ©¦ ©À©¤©¤ TcpServer // TCP·þÎñ ©¦ ©¸©¤©¤ UdpServer // UDP·þÎñ ©À©¤©¤ IDictionary<Int32, INetSession> Sessions // ÍøÂç»á»°¼¯ºÏ ©¸©¤©¤ IPipeline Pipeline // ÏûÏ¢¹ÜµÀ INetSession (ÍøÂç»á»°) ©À©¤©¤ ISocketSession Session // µ×²ãSocket»á»° ©À©¤©¤ NetServer Host // ËùÊô·þÎñÆ÷ ©¸©¤©¤ INetHandler Handler // Êý¾Ý´¦ÀíÆ÷ ISocketSession (Socket»á»°) ©À©¤©¤ TcpSession // TCPÁ¬½Ó»á»° ©¸©¤©¤ UdpSession // UDPÁ¬½Ó»á»° ``` ### Êý¾ÝÁ÷Ïò **½ÓÊÕÊý¾ÝÁ÷**£º ``` Socket½ÓÊÕ ¡ú ProcessEvent ¡ú OnPreReceive ¡ú Pipeline.Read ¡ú OnReceive ¡ú Receivedʼþ ``` **·¢ËÍÊý¾ÝÁ÷**£º ``` Send/SendMessage ¡ú Pipeline.Write ¡ú OnSend ¡ú Socket·¢ËÍ ``` ### ÉúÃüÖÜÆÚ ``` [¿Í»§¶ËÁ¬½Ó] ¡ú [´´½¨ISocketSession] ¡ú [Server_NewSession] ¡ý [OnNewSession] ¡ú [CreateSession] ¡ú [AddSession] ¡ý [NetSession.Start()] ¡ú [OnConnected] ¡ý [Êý¾ÝÊÕ·¢Ñ­»·] ¡ý [¿Í»§¶Ë¶Ï¿ª/³¬Ê±] ¡ú [Close(reason)] ¡ú [OnDisconnected] ¡ú [Dispose] ``` --- ## ¿ìËÙÈëÃÅ ### ×î¼òµ¥µÄ Echo ·þÎñÆ÷ ```csharp using NewLife.Net; // ´´½¨·þÎñÆ÷ var server = new NetServer { Port = 12345, // ¼àÌý¶Ë¿Ú Log = XTrace.Log, // ÆôÓÃÈÕÖ¾ }; // ´¦Àí½ÓÊÕÊý¾Ý server.Received += (sender, e) => { if (sender is INetSession session) { // Echo »Ø¸´ session.Send(e.Packet); } }; // Æô¶¯·þÎñ server.Start(); Console.WriteLine($"·þÎñÒÑÆô¶¯£¬¼àÌý¶Ë¿Ú£º{server.Port}"); Console.ReadLine(); // Í£Ö¹·þÎñ server.Stop("Manual"); ``` ### ´´½¨¿Í»§¶ËÁ¬½Ó ```csharp using NewLife.Net; // ´´½¨TCP¿Í»§¶Ë var uri = new NetUri("tcp://127.0.0.1:12345"); var client = uri.CreateRemote(); client.Log = XTrace.Log; // ´ò¿ªÁ¬½Ó client.Open(); // ·¢ËÍÊý¾Ý client.Send("Hello Server"); // ½ÓÊÕÊý¾Ý var pk = client.Receive(); Console.WriteLine($"ÊÕµ½£º{pk.ToStr()}"); // ¹Ø±ÕÁ¬½Ó client.Close("Done"); ``` ### ʹÓà UDP ЭÒé ```csharp // ·þÎñ¶Ë var server = new NetServer { Port = 12345, ProtocolType = NetType.Udp, // Ö¸¶¨UDP }; server.Start(); // ¿Í»§¶Ë var uri = new NetUri("udp://127.0.0.1:12345"); var client = uri.CreateRemote(); client.Open(); client.Send("Hello UDP"); ``` --- ## ºËÐÄ×é¼þ ### NetServer - ÍøÂç·þÎñÆ÷ NetServer ÊÇÍøÂç·þÎñÆ÷µÄÖ÷Èë¿Ú£¬¹ÜÀí¶à¸öµ×²ã Socket ·þÎñÆ÷¡£ #### »ù±¾ÅäÖà ```csharp var server = new NetServer { // »ù±¾ÅäÖà Name = "MyServer", // ·þÎñÃû£¨Ä¬ÈÏÀàÃûÈ¥µôServerºó׺£© Port = 12345, // ¼àÌý¶Ë¿Ú£¬0ÎªËæ»ú¶Ë¿Ú ProtocolType = NetType.Tcp, // ЭÒéÀàÐÍ£ºTcp/Udp/Unknown(ͬʱ¼àÌý) AddressFamily = AddressFamily.InterNetwork, // µØÖ·×壺IPv4/IPv6/Unspecified(ͬʱ) // »á»°ÅäÖà SessionTimeout = 1200, // »á»°³¬Ê±£¨Ã룩£¬Ä¬ÈÏ20·ÖÖÓ UseSession = true, // ÊÇ·ñʹÓûỰ¼¯ºÏ // SSLÅäÖà SslProtocol = SslProtocols.Tls12, // SSLЭÒé°æ±¾ Certificate = cert, // X509Ö¤Êé // ÈÕÖ¾ÅäÖà Log = XTrace.Log, // ·þÎñÆ÷ÈÕÖ¾ SocketLog = XTrace.Log, // SocketÈÕÖ¾ SessionLog = XTrace.Log, // »á»°ÈÕÖ¾ LogSend = true, // ¼Ç¼·¢ËÍÈÕÖ¾ LogReceive = true, // ¼Ç¼½ÓÊÕÈÕÖ¾ // ÐÔÄÜÅäÖà StatPeriod = 600, // ͳ¼ÆÖÜÆÚ£¨Ã룩£¬0½ûÓà ReuseAddress = true, // µØÖ·ÖØÓà // ×·×ÙÅäÖà Tracer = tracer, // APM×·×ÙÆ÷ SocketTracer = tracer, // Socket²ã×·×ÙÆ÷ // ÒÀÀµ×¢Èë ServiceProvider = serviceProvider, // ·þÎñÌṩÕß }; ``` #### ЭÒéÀàÐÍÅäÖà ```csharp // ½ö¼àÌý TCP server.ProtocolType = NetType.Tcp; // ½ö¼àÌý UDP server.ProtocolType = NetType.Udp; // ͬʱ¼àÌý TCP ºÍ UDP£¨Ä¬ÈÏ£© server.ProtocolType = NetType.Unknown; // HTTP/WebSocket£¨×Ô¶¯ÆôÓÃHTTP½âÎö£© server.ProtocolType = NetType.Http; ``` #### µØÖ·×åÅäÖà ```csharp // ½ö IPv4 server.AddressFamily = AddressFamily.InterNetwork; // ½ö IPv6 server.AddressFamily = AddressFamily.InterNetworkV6; // ͬʱ¼àÌý IPv4 ºÍ IPv6£¨Ä¬ÈÏ£© server.AddressFamily = AddressFamily.Unspecified; ``` #### ʼþ´¦Àí ```csharp // лỰʼþ server.NewSession += (sender, e) => { var session = e.Session; Console.WriteLine($"ÐÂÁ¬½Ó£º{session.Remote}"); }; // Êý¾Ý½ÓÊÕʼþ server.Received += (sender, e) => { if (sender is INetSession session) { Console.WriteLine($"ÊÕµ½[{session.Remote}]£º{e.Packet?.ToStr()}"); // ´¦Àí½âÂëºóµÄÏûÏ¢ if (e.Message != null) { // ´¦ÀíÏûÏ¢¶ÔÏó } } }; // ´íÎóʼþ server.Error += (sender, e) => { Console.WriteLine($"´íÎó£º{e.Exception.Message}"); }; ``` #### »á»°¹ÜÀí ```csharp // »ñȡָ¶¨»á»° var session = server.GetSession(sessionId); // ±éÀúËùÓлỰ foreach (var item in server.Sessions) { Console.WriteLine($"»á»° {item.Key}: {item.Value.Remote}"); } // µ±Ç°»á»°ÊýºÍ×î¸ß»á»°Êý Console.WriteLine($"ÔÚÏß: {server.SessionCount}/{server.MaxSessionCount}"); ``` #### ÊÖ¶¯Ìí¼Ó·þÎñÆ÷ ```csharp // ·½Ê½1£ºÊ¹Óà AddServer server.AddServer(IPAddress.Any, 8080, NetType.Tcp); server.AddServer(IPAddress.Any, 8081, NetType.Udp); // ·½Ê½2£ºÊ¹Óà AttachServer var tcpServer = new TcpServer { Port = 8080 }; server.AttachServer(tcpServer); // ·½Ê½3£ºÖØÔØ EnsureCreateServer public class MyServer : NetServer { public override void EnsureCreateServer() { if (Servers.Count > 0) return; var tcp = new TcpServer { Port = Port }; AttachServer(tcp); } } ``` ### NetSession - ÍøÂç»á»° ÿ¸öÁ¬½Ó¶ÔÓ¦Ò»¸ö»á»°£¬ÓÃÓÚ´¦Àí¸ÃÁ¬½ÓµÄÒµÎñÂß¼­¡£ #### ×Ô¶¨Òå»á»° ```csharp public class MySession : NetSession { /// <summary>Óû§ID</summary> public Int32 UserId { get; set; } /// <summary>Á¬½Óʱ¼ä</summary> public DateTime ConnectTime { get; set; } /// <summary>Á¬½Ó½¨Á¢</summary> protected override void OnConnected() { base.OnConnected(); ConnectTime = DateTime.Now; WriteLog("¿Í»§¶ËÒÑÁ¬½Ó"); // ·¢ËÍ»¶Ó­ÏûÏ¢ Send("Welcome!"); } /// <summary>Á¬½Ó¶Ï¿ª</summary> protected override void OnDisconnected(String reason) { base.OnDisconnected(reason); WriteLog($"¿Í»§¶ËÒѶϿª£º{reason}"); } /// <summary>ÊÕµ½Êý¾Ý</summary> protected override void OnReceive(ReceivedEventArgs e) { base.OnReceive(e); // ԭʼÊý¾Ý°ü var pk = e.Packet; // ¾­¹ý¹ÜµÀ½âÂëºóµÄÏûÏ¢¶ÔÏó var msg = e.Message; // ÒµÎñ´¦Àí ProcessData(pk, msg); } /// <summary>·¢Éú´íÎó</summary> protected override void OnError(Object? sender, ExceptionEventArgs e) { base.OnError(sender, e); WriteError("·¢Éú´íÎó£º{0}", e.Exception.Message); } private void ProcessData(IPacket? pk, Object? msg) { // ÒµÎñÂß¼­ } } // ʹÓ÷ºÐÍ·þÎñÆ÷ var server = new NetServer<MySession> { Port = 12345, }; server.Start(); // »ñȡָ¶¨»á»°£¨Ç¿ÀàÐÍ£© var session = server.GetSession(sessionId); if (session != null) { session.UserId = 123; session.Send("Hello"); } ``` #### ·¢ËÍÊý¾Ý ```csharp public class MySession : NetSession { public void SendData() { // ·¢ËÍ×Ö½ÚÊý×é Send(new Byte[] { 0x01, 0x02, 0x03 }); Send(data, offset, count); // ·¢ËÍ×Ö·û´®£¨Ä¬ÈÏUTF-8£© Send("Hello World"); Send("ÄãºÃ", Encoding.UTF8); // ·¢ËÍÊý¾Ý°ü var packet = new ArrayPacket(data); Send(packet); // ·¢ËÍÁ÷ using var stream = File.OpenRead("data.bin"); Send(stream); // ·¢ËÍSpan£¨¸ßÐÔÄÜ£¬Á㿽±´£© ReadOnlySpan<Byte> span = stackalloc Byte[100]; Send(span); // ͨ¹ý¹ÜµÀ·¢ËÍÏûÏ¢£¨»á¾­¹ý±àÂëÆ÷£© var bytes = SendMessage(new MyRequest { Cmd = "ping" }); // ·¢ËÍÏìÓ¦ÏûÏ¢£¨¹ØÁªÇëÇóÉÏÏÂÎÄ£© SendReply(new MyResponse { Result = "OK" }, e); } // Òì²½·¢ËͲ¢µÈ´ýÏìÓ¦ public async Task<MyResponse> QueryAsync() { var response = await SendMessageAsync(new MyRequest { Cmd = "query" }); return response as MyResponse; } // ´ø³¬Ê±µÄÒì²½ÇëÇó public async Task<MyResponse> QueryWithTimeoutAsync() { using var cts = new CancellationTokenSource(5000); var response = await SendMessageAsync(request, cts.Token); return response as MyResponse; } } ``` #### »á»°Êý¾Ý´æ´¢ ```csharp public class MySession : NetSession { protected override void OnConnected() { base.OnConnected(); // ʹÓÃË÷ÒýÆ÷´æ´¢Êý¾Ý£¨Óëµ×²ãSocket»á»°¹²Ïí£© this["userId"] = 12345; this["loginTime"] = DateTime.Now; // ʹÓà Items ×Öµä Items["userData"] = new UserData(); } protected override void OnReceive(ReceivedEventArgs e) { base.OnReceive(e); // ¶ÁÈ¡»á»°Êý¾Ý var userId = (Int32)this["userId"]; var userData = Items["userData"] as UserData; } } ``` #### ·ºÐͻỰ£¨Ç¿ÀàÐÍHost·ÃÎÊ£© ```csharp // ×Ô¶¨Òå·þÎñÆ÷ public class GameServer : NetServer<GameSession> { public GameConfig Config { get; set; } public IDatabase Database { get; set; } } // ×Ô¶¨Òå»á»° public class GameSession : NetSession<GameServer> { protected override void OnReceive(ReceivedEventArgs e) { base.OnReceive(e); // Ö±½Ó·ÃÎÊ×Ô¶¨Òå·þÎñÆ÷ÊôÐÔ£¨Ç¿ÀàÐÍ£© var config = Host.Config; var db = Host.Database; } } ``` ### Pipeline - ÏûÏ¢¹ÜµÀ ¹ÜµÀÓÃÓÚЭÒé±à½âÂ룬֧³ÖÁ´Ê½´¦Àí¡£ #### ±ê×¼±à½âÂëÆ÷ ```csharp using NewLife.Net.Handlers; var server = new NetServer { Port = 12345 }; // Ìí¼Ó±ê×¼±à½âÂëÆ÷£¨4×Ö½ÚÍ·²¿+Êý¾Ý£© server.Add<StandardCodec>(); // Ìí¼ÓJSON±à½âÂëÆ÷ server.Add<JsonCodec>(); // ½ÓÊÕ½âÂëºóµÄÏûÏ¢ server.Received += (s, e) => { // e.Message ÊǽâÂëºóµÄÏûÏ¢¶ÔÏó if (e.Message is DefaultMessage msg) { Console.WriteLine($"±êÖ¾£º{msg.Flag}"); Console.WriteLine($"ÐòÁкţº{msg.Sequence}"); Console.WriteLine($"¸ºÔØ£º{msg.Payload?.ToStr()}"); } }; server.Start(); ``` #### ×Ô¶¨Òå´¦ÀíÆ÷ ```csharp public class MyHandler : Handler { public override Boolean Read(IHandlerContext context, Object message) { // ½âÂë´¦Àí£¨½ÓÊÕÊý¾Ýʱ£© if (message is IPacket pk) { var myMsg = ParseMessage(pk); return context.FireRead(myMsg); } return base.Read(context, message); } public override Boolean Write(IHandlerContext context, Object message) { // ±àÂë´¦Àí£¨·¢ËÍÊý¾Ýʱ£© if (message is MyMessage msg) { var pk = EncodeMessage(msg); return context.FireWrite(pk); } return base.Write(context, message); } } // ×¢²á´¦ÀíÆ÷ server.Add(new MyHandler()); ``` ### INetHandler - ÍøÂç´¦ÀíÆ÷ ÓÃÓڻỰ¼¶±ðµÄÊý¾ÝÔ¤´¦Àí¡£ ```csharp public class MyServer : NetServer<MySession> { // Ϊÿ¸ö»á»°´´½¨´¦ÀíÆ÷ public override INetHandler? CreateHandler(INetSession session) { return new MyNetHandler(); } } public class MyNetHandler : INetHandler { public INetSession? Session { get; set; } public void Init(INetSession session) { Session = session; } public void Process(ReceivedEventArgs e) { // Ô¤´¦ÀíÊý¾Ý£¨ÔÚOnReceive֮ǰ£© // ¿ÉÒÔÐÞ¸Ä e.Packet »ò e.Message // ¿ÉÒÔÉèÖà e.Packet = null À´×èÖ¹ºóÐø´¦Àí } public void Dispose() { // ÇåÀí×ÊÔ´ } } ``` --- ## ¸ß¼¶ÌØÐÔ ### SSL/TLS ¼ÓÃÜ ```csharp // ·þÎñ¶ËSSL var cert = new X509Certificate2("server.pfx", "password"); var server = new NetServer { Port = 443, ProtocolType = NetType.Tcp, SslProtocol = SslProtocols.Tls12 | SslProtocols.Tls13, Certificate = cert, }; server.Start(); // ¿Í»§¶ËSSL var client = new TcpSession { Remote = new NetUri("tcp://127.0.0.1:443"), SslProtocol = SslProtocols.Tls12, // ¿ÉÑ¡£º¿Í»§¶ËÖ¤Êé Certificate = clientCert, }; client.Open(); ``` ### Ⱥ·¢ÏûÏ¢ ```csharp // Ⱥ·¢Êý¾Ý°ü¸øËùÓпͻ§¶Ë await server.SendAllAsync(new ArrayPacket(data)); // ´øÌõ¼þȺ·¢£¨¹ýÂËÆ÷£© await server.SendAllAsync(data, session => session["RoomId"]?.ToString() == "123"); // Ⱥ·¢¹ÜµÀÏûÏ¢£¨»á¾­¹ý±àÂëÆ÷£© server.SendAllMessage(new BroadcastMessage { Content = "Hello" }); // Ⱥ·¢²¢¹ýÂË server.SendAllMessage(message, session => session.ID > 100); // Åųý×Ô¼º server.SendAllMessage(message, session => session.ID != mySession.ID); ``` ### ÏûÏ¢ÇëÇóÏìÓ¦ ```csharp // ¿Í»§¶Ë·¢ËÍÇëÇ󲢵ȴýÏìÓ¦ var client = new TcpSession { Remote = uri }; client.Add<StandardCodec>(); client.Open(); // Òì²½·¢ËÍÏûÏ¢²¢µÈ´ýÏìÓ¦ var response = await client.SendMessageAsync(request); // ´ø³¬Ê±µÄÇëÇó using var cts = new CancellationTokenSource(5000); var response = await client.SendMessageAsync(request, cts.Token); ``` ### ÒÀÀµ×¢Èë ```csharp // ÅäÖ÷þÎñ services.AddSingleton<IMyService, MyService>(); services.AddScoped<IScopedService, ScopedService>(); var server = new NetServer<MySession> { Port = 12345, ServiceProvider = serviceProvider, }; // ÔڻỰÖÐʹÓã¨×Ô¶¯´´½¨Scope£© public class MySession : NetSession { protected override void OnConnected() { base.OnConnected(); // ServiceProvider ÒÑ×Ô¶¯´´½¨ Scope var service = ServiceProvider?.GetService<IMyService>(); var scoped = ServiceProvider?.GetService<IScopedService>(); } // ÄÚÖ÷þÎñ¿ìËÙ»ñÈ¡ public override Object GetService(Type serviceType) { if (serviceType == typeof(INetSession)) return this; if (serviceType == typeof(NetServer)) return (this as INetSession).Host; if (serviceType == typeof(ISocketSession)) return Session; if (serviceType == typeof(ISocketServer)) return Server; return base.GetService(serviceType); } } ``` ### APM ÐÔÄÜ×·×Ù ```csharp var server = new NetServer { Port = 12345, Tracer = tracer, // Ó¦Óòã×·×Ù SocketTracer = tracer, // Socket²ã×·×Ù }; // ×·×ٵIJÙ×÷°üÀ¨£º // - net:{Name}:Connect Á¬½Óʼþ // - net:{Name}:Receive ½ÓÊÕÊý¾Ý // - net:{Name}:Send ·¢ËÍÊý¾Ý // - net:{Name}:Disconnect ¶Ï¿ªÁ¬½Ó ``` --- ## ×î¼Ñʵ¼ù ### 1. ×ÊÔ´¹ÜÀí ```csharp // ʹÓÃusingÈ·±£×ÊÔ´ÊÍ·Å using var server = new NetServer { Port = 12345 }; server.Start(); // »òÕßÔÚfinallyÖÐÍ£Ö¹ var server = new NetServer { Port = 12345 }; try { server.Start(); // ... } finally { server.Stop("Shutdown"); server.Dispose(); } ``` ### 2. Òì³£´¦Àí ```csharp // »á»°¼¶Òì³£´¦Àí public class MySession : NetSession { protected override void OnReceive(ReceivedEventArgs e) { try { base.OnReceive(e); ProcessData(e.Packet); } catch (Exception ex) { WriteError("´¦ÀíÊý¾ÝÒì³££º{0}", ex.Message); // ²»ÒªÔÚÕâÀï¹Ø±ÕÁ¬½Ó£¬ÈÃÉϲã¾ö¶¨ } } } // ·þÎñÆ÷¼¶Òì³£´¦Àí server.Error += (s, e) => { XTrace.WriteException(e.Exception); }; ``` ### 3. ÈÕÖ¾ÅäÖà ```csharp // Éú²ú»·¾³ÅäÖà var server = new NetServer { Log = XTrace.Log, // ·þÎñÆ÷ÈÕÖ¾ SessionLog = null, // ¹Ø±Õ»á»°ÈÕÖ¾ SocketLog = null, // ¹Ø±ÕSocketÈÕÖ¾ LogSend = false, // ¹Ø±Õ·¢ËÍÈÕÖ¾ LogReceive = false, // ¹Ø±Õ½ÓÊÕÈÕÖ¾ StatPeriod = 600, // 10·ÖÖÓÊä³öÒ»´Îͳ¼Æ }; // µ÷ÊÔ»·¾³ÅäÖà var server = new NetServer { Log = XTrace.Log, SocketLog = XTrace.Log, SessionLog = XTrace.Log, LogSend = true, LogReceive = true, StatPeriod = 60, // 1·ÖÖÓÊä³öͳ¼Æ }; ``` ### 4. »á»°×´Ì¬¹ÜÀí ```csharp public class GameSession : NetSession { public Player Player { get; set; } protected override void OnConnected() { base.OnConnected(); // ³õʼ»¯Íæ¼Ò¶ÔÏó Player = new Player(); } protected override void OnReceive(ReceivedEventArgs e) { base.OnReceive(e); // ʹÓÃItems´æ´¢ÁÙʱÊý¾Ý this["LastActiveTime"] = DateTime.Now; // ʹÓÃÇ¿ÀàÐÍÊôÐÔ Player?.HandlePacket(e.Packet); } protected override void OnDisconnected(String reason) { base.OnDisconnected(reason); // ÇåÀíÍæ¼ÒÊý¾Ý Player?.SaveAndCleanup(); Player = null; } } ``` --- ## ÐÔÄÜÓÅ»¯ ### 1. »á»°¼¯ºÏÓÅ»¯ ```csharp // ¸ß²¢·¢³¡¾°ÏÂÈç²»ÐèÒª±éÀú»á»°£¬¿É½ûÓûỰ¼¯ºÏ server.UseSession = false; // »á»°¼¯ºÏʹÓà ConcurrentDictionary£¬±éÀúʱֱ½Ó±éÀú Values foreach (var session in server.Sessions.Values) { // ±ÜÃâ KeyValuePair µÄ¶îÍ⿪Ïú } ``` ### 2. Ⱥ·¢ÓÅ»¯ ```csharp // Ⱥ·¢ÒÑÓÅ»¯ÎªÍ¬²½·¢ËÍ£¬±ÜÃâ Task.Run ¿ªÏú // Ö±½Ó±éÀú _Sessions.Values£¬¼õÉÙ×Öµä²Ù×÷¿ªÏú await server.SendAllAsync(data); // Èç¹ûÐèÒª²¢Ðз¢ËÍ£¬×ÔÐÐʵÏÖ var tasks = server.Sessions.Values .Where(predicate) .Select(s => Task.Run(() => s.Send(data))); await Task.WhenAll(tasks); ``` ### 3. Ô­×Ó²Ù×÷ ```csharp // SessionCount ºÍ MaxSessionCount ʹÓÃÔ­×Ó²Ù×÷¸üР// ±ÜÃâËø¾ºÕù£¬Ìá¸ß²¢·¢ÐÔÄÜ var count = server.SessionCount; // µ±Ç°»á»°Êý var max = server.MaxSessionCount; // ÀúÊ·×î¸ß»á»°Êý ``` ### 4. ×·×ÙÊý¾ÝÓÅ»¯ ```csharp // Send ·½·¨×·×ÙÊý¾ÝÏÞÖÆ³¤¶È£¬±ÜÃâ´óÊý¾Ý°üÓ°Ïì×·×ÙÐÔÄÜ // ×Ö·û´®ºÍ×Ö½ÚÊý×é×î¶à¼Ç¼64×Ö½Ú public virtual INetSession Send(String msg, Encoding? encoding = null) { // ×·×Ùʱֻ¼Ç¼ǰ64×Ö·û using var span = host?.Tracer?.NewSpan($"net:{host.Name}:Send", msg.Length > 64 ? msg[..64] : msg, ...); ... } ``` ### 5. ·ÀÖØÈë±£»¤ ```csharp // Start ºÍ Close ·½·¨¶¼ÓзÀÖØÈë±£»¤ // ʹÓà Interlocked.CompareExchange È·±£Ö»Ö´ÐÐÒ»´Î public virtual void Start() { if (Interlocked.CompareExchange(ref _running, 1, 0) != 0) return; ... } public void Close(String reason) { if (Interlocked.CompareExchange(ref _running, 0, 1) != 1) return; ... } ``` ### 6. TCP ÐÔÄÜÅäÖà ```csharp // ·ÃÎʵײãTcpServer½øÐÐÅäÖà if (server.Server is TcpServer tcp) { tcp.NoDelay = true; // ½ûÓÃNagleËã·¨£¨µÍÑÓ³Ù£© tcp.KeepAliveInterval = 60; // KeepAlive¼ä¸ô } ``` --- ## ³£¼ûÎÊÌâ ### Q: ÈçºÎ´¦ÀíÕ³°ü/²ð°ü£¿ A: ʹÓà StandardCodec »ò×Ô¶¨ÒåЭÒé´¦ÀíÆ÷¡£StandardCodec ²ÉÓà 4 ×Ö½ÚÍ·²¿±êʶÊý¾Ý³¤¶È¡£ ```csharp server.Add<StandardCodec>(); ``` ### Q: ÈçºÎʵÏÖÐÄÌø¼ì²â£¿ A: ÉèÖûỰ³¬Ê±Ê±¼ä£¬¿Í»§¶Ë¶¨ÆÚ·¢ËÍÐÄÌø°ü¡£ ```csharp server.SessionTimeout = 120; // 2·ÖÖÓÎÞÊý¾ÝÔò¶Ï¿ª // ¿Í»§¶Ë¶¨Ê±·¢ËÍÐÄÌø timer.Elapsed += (s, e) => client.Send("ping"); ``` ### Q: ÈçºÎ»ñÈ¡¿Í»§¶ËÕæÊµIP£¿ A: ͨ¹ý»á»°µÄ Remote ÊôÐÔ»ñÈ¡¡£ ```csharp server.NewSession += (s, e) => { var ip = e.Session.Remote.Address; var port = e.Session.Remote.Port; Console.WriteLine($"¿Í»§¶Ë£º{ip}:{port}"); }; ``` ### Q: ÈçºÎÏÞÖÆ×î´óÁ¬½ÓÊý£¿ A: ÔÚ OnNewSession Öмì²é²¢¾Ü¾ø¡£ ```csharp public class MyServer : NetServer { public Int32 MaxConnections { get; set; } = 1000; protected override INetSession OnNewSession(ISocketSession session) { if (SessionCount >= MaxConnections) { WriteLog("Á¬½ÓÊý³¬ÏÞ£¬¾Ü¾øÁ¬½Ó£º{0}", session.Remote); session.Dispose(); return null; } return base.OnNewSession(session); } } ``` ### Q: ·þÎñÆ÷ÖØÆôʱ¶Ë¿Ú±»Õ¼Óã¿ A: ÆôÓõØÖ·ÖØÓᣠ```csharp server.ReuseAddress = true; ``` ### Q: ÈçºÎ·¢ËÍÎļþ£¿ A: ʹÓÃÁ÷·¢ËÍ»òÀ©Õ¹·½·¨¡£ ```csharp // ¼òµ¥·¢ËÍÁ÷ using var stream = File.OpenRead("data.bin"); session.Send(stream); // ·Ö°ü·¢ËÍ£¨ÅäºÏStandardCodec£© client.SendFile("data.bin"); ``` ### Q: UDP ÈçºÎÇø·Ö¿Í»§¶Ë£¿ A: UDP ЭÒéÏ£¬Ã¿¸ö²»Í¬µÄÔ¶³ÌµØÖ·»á´´½¨¶ÀÁ¢µÄ»á»°¡£ ```csharp server.Received += (s, e) => { var session = s as INetSession; Console.WriteLine($"À´×Ô {session.Remote} µÄÊý¾Ý"); }; ``` ### Q: ÈçºÎʵÏֹ㲥·¿¼ä£¿ A: ʹÓûỰÊý¾Ý±ê¼Ç·¿¼ä£¬Èº·¢Ê±¹ýÂË¡£ ```csharp // ¼ÓÈë·¿¼ä session["RoomId"] = "room1"; // ·¿¼ä¹ã²¥ server.SendAllMessage(message, s => s["RoomId"]?.ToString() == "room1"); ``` --- ## ¸½Â¼ ### ±ê×¼ÍøÂç·â°üЭÒé ÐÂÉúÃüÍŶӱê×¼ÍøÂç·â°üЭÒ飨DefaultMessage£©£º ``` | 1 Flag | 1 Sequence | 2 Length | N Payload | ``` - **Flag** (1×Ö½Ú)£º±êʶ룬¿ÉÓ÷¶Î§0~63£¬±êʶÏûÏ¢ÀàÐÍ/¼ÓÃÜ/ѹËõµÈ - **Sequence** (1×Ö½Ú)£ºÐòÁкţ¬ÓÃÓÚÇëÇóÏìÓ¦Åä¶Ô - **Length** (2×Ö½Ú)£ºÊý¾Ý³¤¶È£¬×î´ó64KB - **Payload** (N×Ö½Ú)£º¸ºÔØÊý¾Ý ### ¹Ø¼üÀàÐÍËÙ²é | ÀàÐÍ | ˵Ã÷ | |------|------| | `NetServer` | ÍøÂç·þÎñÆ÷£¬¹ÜÀí¶à¸öSocket·þÎñÆ÷ºÍ»á»° | | `NetServer<TSession>` | ·ºÐÍÍøÂç·þÎñÆ÷£¬×Ô¶¯´´½¨Ö¸¶¨ÀàÐͻỰ | | `NetSession` | ÍøÂç»á»°»ùÀ࣬´¦Àíµ¥¸öÁ¬½ÓµÄÒµÎñÂß¼­ | | `NetSession<TServer>` | ·ºÐÍÍøÂç»á»°£¬Ç¿ÀàÐÍ·ÃÎÊHost | | `INetSession` | ÍøÂç»á»°½Ó¿Ú | | `INetHandler` | ÍøÂç´¦ÀíÆ÷½Ó¿Ú£¬»á»°¼¶Êý¾ÝÔ¤´¦Àí | | `IPipeline` | ÏûÏ¢¹ÜµÀ½Ó¿Ú | | `ISocketServer` | Socket·þÎñÆ÷½Ó¿Ú | | `ISocketSession` | Socket»á»°½Ó¿Ú | | `TcpServer` | TCP·þÎñÆ÷ | | `UdpServer` | UDP·þÎñÆ÷ | | `TcpSession` | TCP¿Í»§¶Ë/»á»° | ### Ïà¹ØÁ´½Ó - GitHub: https://github.com/NewLifeX/X - Gitee: https://gitee.com/NewLifeX/X - Îĵµ: https://newlifex.com --- *±¾Îĵµ×îºó¸üУº2025Äê7ÔÂ*