{"id":14963499,"url":"https://github.com/beetlex-io/beetlex","last_synced_at":"2025-05-14T12:11:15.109Z","repository":{"id":43574472,"uuid":"147439433","full_name":"beetlex-io/BeetleX","owner":"beetlex-io","description":"high performance dotnet core socket tcp communication components,  support TLS, HTTP, HTTPS, WebSocket, RPC, Redis protocols, custom protocols  and 1M connections problem solution","archived":false,"fork":false,"pushed_at":"2024-08-05T14:49:02.000Z","size":1785,"stargazers_count":1195,"open_issues_count":4,"forks_count":244,"subscribers_count":76,"default_branch":"master","last_synced_at":"2025-05-04T11:43:28.354Z","etag":null,"topics":["http-server","https","mqtt","mqtt-client","mqtt-server","non-blocking","rpc","rpc-framework","rpc-server","socket","socket-server","socketasynceventargs","ssl","tcp","tcp-server","tls","webserver","websocket","websocket-server","websockets"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beetlex-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"beetlex","custom":["https://www.paypal.me/henryfancn","http://beetlex.io"]}},"created_at":"2018-09-05T01:02:44.000Z","updated_at":"2025-04-16T17:15:30.000Z","dependencies_parsed_at":"2022-09-04T19:11:27.175Z","dependency_job_id":"bf9d53ec-5b76-415d-8d30-daeb316a5ae1","html_url":"https://github.com/beetlex-io/BeetleX","commit_stats":{"total_commits":123,"total_committers":5,"mean_commits":24.6,"dds":0.03252032520325199,"last_synced_commit":"52681f2656db853aa55184082dde59e2c67bfcb8"},"previous_names":["ikende/beetlex"],"tags_count":5,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beetlex-io%2FBeetleX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beetlex-io%2FBeetleX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beetlex-io%2FBeetleX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beetlex-io%2FBeetleX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beetlex-io","download_url":"https://codeload.github.com/beetlex-io/BeetleX/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140768,"owners_count":22021220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http-server","https","mqtt","mqtt-client","mqtt-server","non-blocking","rpc","rpc-framework","rpc-server","socket","socket-server","socketasynceventargs","ssl","tcp","tcp-server","tls","webserver","websocket","websocket-server","websockets"],"created_at":"2024-09-24T13:31:42.193Z","updated_at":"2025-05-14T12:11:15.014Z","avatar_url":"https://github.com/beetlex-io.png","language":"C#","funding_links":["https://opencollective.com/beetlex","https://www.paypal.me/henryfancn","http://beetlex.io"],"categories":[],"sub_categories":[],"readme":"# BeetleX\nhigh performance dotnet core socket tcp communication components,  support TCP, SSL, HTTP, HTTPS, WebSocket,MQTT,RPC, Redis protocols ... and 1M connections problem solution\n\n\n\u003ca href=\"https://www.nuget.org/packages/BeetleX/\" target=\"_blank\"\u003e \u003cimg src=\"https://img.shields.io/nuget/vpre/beetlex?label=BeetleX\"\u003e \n\t\t\t\t\t\t\t  \u003cimg src=\"https://img.shields.io/nuget/dt/BeetleX\"\u003e\n\t\t\t\t\t\t\t  \u003c/a\u003e\n## Extended Components\n- [High performance lightweight http and websocket server components](https://github.com/beetlex-io/FastHttpApi)\n   \n- [High performance http and websocket gateway components](https://github.com/beetlex-io/Bumblebee)\n\n- [High-performance async/non-blocking  redis client components](https://github.com/beetlex-io/BeetleX.Redis)   \n\n- [High-performance async/non-blocking  MQTT protocol components](https://github.com/beetlex-io/mqtt)   \n  \n- [High performance remote interface invoke(RPC) communication components](https://github.com/beetlex-io/XRPC)\n\n- [Http and websocket clients](https://github.com/IKende/HttpClients)\n \n## samples\n[BeetleX's tcp, http, websocket, xprc ... Samples](https://github.com/beetlex-io/BeetleX-Samples)\n\n\n\n## Web Framework Benchmarks\n[Round 20](https://www.techempower.com/benchmarks/#section=data-r20\u0026hw=ph\u0026test=composite)\n![benchmarks-round20](https://user-images.githubusercontent.com/2564178/107942248-eec41380-6fc5-11eb-94e4-410cadc8ae13.png)\n## ServerBuilder\n``` csharp\n    class Program : IApplication\n    {\n        private static ServerBuilder\u003cProgram, User\u003e server;\n        public static void Main(string[] args)\n        {\n            server = new ServerBuilder\u003cProgram, User\u003e();\n            server.SetOptions(option =\u003e\n            {\n                option.DefaultListen.Port = 9090;\n                option.DefaultListen.Host = \"127.0.0.1\";\n            })\n            .OnStreamReceive(e =\u003e\n            {\n                Console.WriteLine($\"session:{e.Session}\\t application:{e.Application}\");\n                if (e.Reader.TryReadLine(out string name))\n                {\n                    Console.WriteLine(name);\n                    e.Writer.WriteLine(\"hello \" + name);\n                    e.Flush();\n                }\n            })\n            .Run();\n            Console.Read();\n        }\n\n        public void Init(IServer server)\n        {\n            Console.WriteLine(\"application init\");\n        }\n    }\n\n    public class User : ISessionToken\n    {\n        public void Dispose()\n        {\n\n        }\n\n        public void Init(IServer server, ISession session)\n        {\n            Console.WriteLine(\"session token init\");\n        }\n    }\n\n    public class Program : IApplication\n    {\n        private static ServerBuilder\u003cProgram, User, Messages.JsonPacket\u003e server;\n        public static void Main(string[] args)\n        {\n\n            server = new ServerBuilder\u003cProgram, User, Messages.JsonPacket\u003e();\n            server.ConsoleOutputLog = true;\n            server.SetOptions(option =\u003e\n            {\n                option.DefaultListen.Port = 9090;\n                option.DefaultListen.Host = \"127.0.0.1\";\n                option.LogLevel = LogType.Trace;\n            })\n            .OnMessageReceive\u003cMessages.Register\u003e((e) =\u003e\n            {\n                Console.WriteLine($\"application:{e.Application}\\t session:{e.Session}\");\n                e.Message.DateTime = DateTime.Now;\n                e.Return(e.Message);\n            })\n            .OnMessageReceive((e) =\u003e\n            {\n\n            })\n            .Run();\n            Console.Read();\n        }\n\n        public void Init(IServer server)\n        {\n            Console.WriteLine(\"application init\");\n        }\n    }\n\n    public class User : ISessionToken\n    {\n        public void Dispose()\n        {\n            Console.WriteLine(\"client disposed\");\n        }\n\n        public void Init(IServer server, ISession session)\n        {\n            Console.WriteLine(\"session init\");\n        }\n    }\n\n```\n## Base server\n``` csharp\nclass Program : ServerHandlerBase\n{\n    private static IServer server;\n    public static void Main(string[] args)\n    {\n        server = SocketFactory.CreateTcpServer\u003cProgram\u003e();\n        //server.Options.DefaultListen.Port =9090;\n        //server.Options.DefaultListen.Host = \"127.0.0.1\";\n        server.Open();\n        Console.Read();\n    }\n    public override void SessionReceive(IServer server, SessionReceiveEventArgs e)\n    {\n        var pipeStream = e.Stream.ToPipeStream();\n        if (pipeStream.TryReadLine(out string name))\n        {\n            Console.WriteLine(name);\n            e.Session.Stream.ToPipeStream().WriteLine(\"hello \" + name);\n            e.Session.Stream.Flush();\n        }\n        base.SessionReceive(server, e);\n    }\n}\n```\n## SSL\n``` csharp\nclass Program : ServerHandlerBase\n{\n    private static IServer server;\n    public static void Main(string[] args)\n    {\n        server = SocketFactory.CreateTcpServer\u003cProgram, Messages.JsonPacket\u003e();\n        server.Options.LogLevel = LogType.Debug;\n        server.Options.DefaultListen.SSL = true;\n        server.Options.DefaultListen.CertificateFile = @\"test.pfx\";\n        server.Options.DefaultListen.CertificatePassword = \"123456\";\n        //server.Options.DefaultListen.Port =9090;\n        //server.Options.DefaultListen.Host = \"127.0.0.1\";\n        server.Open();\n        Console.Read();\n    }\n    protected override void OnReceiveMessage(IServer server, ISession session, object message)\n    {\n        ((Messages.Register)message).DateTime = DateTime.Now;\n        server.Send(message, session);\n    }\n}\n```\n\n## Custom packet\n``` csharp\n    public abstract class FixedHeaderPacket : IPacket\n    {\n\n        public FixedHeaderPacket()\n        {\n            SizeType = FixedSizeType.INT;\n        }\n\n        public FixedSizeType SizeType\n        { get; set; }\n\n        public EventHandler\u003cPacketDecodeCompletedEventArgs\u003e Completed { get; set; }\n\n        public abstract IPacket Clone();\n\n        private PacketDecodeCompletedEventArgs mCompletedArgs = new PacketDecodeCompletedEventArgs();\n\n        private int mSize;\n\n\n        protected int CurrentSize =\u003e mSize;\n\n        protected abstract object OnRead(ISession session, PipeStream stream);\n\n        public void Decode(ISession session, System.IO.Stream stream)\n        {\n            PipeStream pstream = stream.ToPipeStream();\n        START:\n            object data;\n            if (mSize == 0)\n            {\n                if (SizeType == FixedSizeType.INT)\n                {\n                    if (pstream.Length \u003c 4)\n                        return;\n                    mSize = pstream.ReadInt32();\n                }\n                else\n                {\n                    if (pstream.Length \u003c 2)\n                        return;\n                    mSize = pstream.ReadInt16();\n                }\n            }\n            if (pstream.Length \u003c mSize)\n                return;\n            data = OnRead(session, pstream);\n            mSize = 0;\n            Completed?.Invoke(this, mCompletedArgs.SetInfo(session, data));\n            goto START;\n\n        }\n\n\n        public virtual\n            void Dispose()\n        {\n\n        }\n\n        protected abstract void OnWrite(ISession session, object data, PipeStream stream);\n\n        private void OnEncode(ISession session, object data, System.IO.Stream stream)\n        {\n            PipeStream pstream = stream.ToPipeStream();\n            MemoryBlockCollection msgsize;\n            if (SizeType == FixedSizeType.INT)\n                msgsize = pstream.Allocate(4);\n            else\n                msgsize = pstream.Allocate(2);\n            int length = (int)pstream.CacheLength;\n            OnWrite(session, data, pstream);\n            if (SizeType == FixedSizeType.INT)\n            {\n                int len = (int)pstream.CacheLength - length;\n                if (!pstream.LittleEndian)\n                    len = BitHelper.SwapInt32(len);\n                msgsize.Full(len);\n            }\n            else\n            {\n                short len = (short)(pstream.CacheLength - length);\n                if (!pstream.LittleEndian)\n                    len = BitHelper.SwapInt16(len);\n                msgsize.Full(len);\n            }\n\n        }\n\n        public byte[] Encode(object data, IServer server)\n        {\n            byte[] result = null;\n            using (Buffers.PipeStream stream = new PipeStream(server.SendBufferPool.Next(), server.Options.LittleEndian, server.Options.Encoding))\n            {\n                OnEncode(null, data, stream);\n                stream.Position = 0;\n                result = new byte[stream.Length];\n                stream.Read(result, 0, result.Length);\n            }\n            return result;\n        }\n\n        public ArraySegment\u003cbyte\u003e Encode(object data, IServer server, byte[] buffer)\n        {\n            using (Buffers.PipeStream stream = new PipeStream(server.SendBufferPool.Next(), server.Options.LittleEndian, server.Options.Encoding))\n            {\n                OnEncode(null, data, stream);\n                stream.Position = 0;\n                int count = (int)stream.Length;\n                stream.Read(buffer, 0, count);\n                return new ArraySegment\u003cbyte\u003e(buffer, 0, count);\n            }\n        }\n\n        public void Encode(object data, ISession session, System.IO.Stream stream)\n        {\n            OnEncode(session, data, stream);\n        }\n    }\n    //json packet\n    public class JsonPacket : BeetleX.Packets.FixedHeaderPacket\n    {\n        static JsonPacket()\n        {\n            TypeHeader.Register(typeof(JsonClientPacket).Assembly);\n        }\n        public static BeetleX.Packets.CustomTypeHeader TypeHeader { get; set; } = new BeetleX.Packets.CustomTypeHeader(BeetleX.Packets.MessageIDType.INT);\n\n        public override IPacket Clone()\n        {\n            return new JsonPacket();\n        }\n\n        protected override object OnRead(ISession session, PipeStream stream)\n        {\n            Type type = TypeHeader.ReadType(stream);\n            var size = CurrentSize - 4;\n            var buffer = System.Buffers.ArrayPool\u003cbyte\u003e.Shared.Rent(size);\n            stream.Read(buffer, 0, size);\n            try\n            {\n                return SpanJson.JsonSerializer.NonGeneric.Utf8.Deserialize(new ReadOnlySpan\u003cbyte\u003e(buffer, 0, size), type);\n            }\n            finally\n            {\n                System.Buffers.ArrayPool\u003cbyte\u003e.Shared.Return(buffer);\n            }\n        }\n\n        protected override void OnWrite(ISession session, object data, PipeStream stream)\n        {\n            TypeHeader.WriteType(data, stream);\n            var buffer = SpanJson.JsonSerializer.NonGeneric.Utf8.SerializeToArrayPool(data);\n            try\n            {\n                stream.Write(buffer.Array, buffer.Offset, buffer.Count);\n            }\n            finally\n            {\n                System.Buffers.ArrayPool\u003cbyte\u003e.Shared.Return(buffer.Array);\n            }\n        }\n    }\n```\n## Client\n```csharp\nAsyncTcpClient client = SocketFactory.CreateClient\u003cAsyncTcpClient\u003e(\"127.0.0.1\", 9090);\nclient.DataReceive = (o, e) =\u003e\n{\n    var pipestream = e.Stream.ToPipeStream();\n    if (pipestream.TryReadLine(out string line))\n    {\n        Console.WriteLine(line);\n    }\n};\nclient.ClientError = (o, e) =\u003e\n{\n    Console.WriteLine(e.Error.Message);\n};\nBytesHandler line = Console.ReadLine() + \"\\r\\n\";\nclient.Send(line);\n```\n## AwaiterClient\n``` csharp\nvar client = new AwaiterClient(\"127.0.0.1\", 9090, new Messages.JsonClientPacket());\nwhile (true)\n{\n    Messages.Register register = new Messages.Register();\n    Console.Write(\"Enter Name:\");\n    register.Name = Console.ReadLine();\n    Console.Write(\"Enter Email:\");\n    register.EMail = Console.ReadLine();\n    Console.Write(\"Enter City:\");\n    register.City = Console.ReadLine();\n    Console.Write(\"Enter Password:\");\n    register.PassWord = Console.ReadLine();\n    await client.Send(register);\n    var result = await client.Receive\u003cMessages.Register\u003e();\n    Console.WriteLine($\"{result.Name} {result.EMail} {result.City} {result.DateTime}\");\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeetlex-io%2Fbeetlex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeetlex-io%2Fbeetlex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeetlex-io%2Fbeetlex/lists"}