├── .editorconfig ├── .gitattributes ├── .gitignore ├── .vscode ├── launch.json ├── settings.json ├── solution-explorer │ ├── class.cs-template │ ├── class.ts-template │ ├── class.vb-template │ ├── default.ts-template │ ├── enum.cs-template │ ├── interface.cs-template │ ├── interface.ts-template │ ├── template-list.json │ └── template-parameters.js └── tasks.json ├── LICENSE.txt ├── Peach.sln ├── README.md ├── RELEASE_NOTES.md ├── build ├── releasenotes.props └── version.props ├── doc ├── .gitignore ├── api │ ├── .gitignore │ └── index.md ├── articles │ ├── intro.md │ ├── quickstart.md │ └── toc.yml ├── docfx.json ├── index.md ├── template │ ├── ManagedReference.html.primary.tmpl │ ├── partials │ │ └── enum.tmpl.partial │ └── toc.html.tmpl └── toc.yml ├── samples ├── CommandLine.Client │ ├── CommandLine.Client.csproj │ └── Program.cs ├── CommandLine.Server │ ├── CommandLine.Server.csproj │ ├── MyService.cs │ └── Program.cs ├── Mqtt.Client │ ├── Mqtt.Client.csproj │ └── Program.cs └── Mqtt.Server │ ├── Mqtt.Server.csproj │ ├── MqttSampleService.cs │ └── Program.cs ├── scripts └── publish_peach.sh ├── shared └── dotnetty.com.pfx ├── src ├── Peach.Mqtt │ ├── AbsMqttSocketService.cs │ ├── IMqttAuthorize.cs │ ├── IMqttResult.cs │ ├── IPacketProcessor.cs │ ├── MqttChannelHandlerPipeline.cs │ ├── MqttClientConnection.cs │ ├── MqttClientSession.cs │ ├── MqttClientSessionManager.cs │ ├── MqttClientSubscriptionsManager.cs │ ├── MqttErrorCodes.cs │ ├── MqttMessage.cs │ ├── MqttMessageDecodeHandler.cs │ ├── MqttMessageEncodeHandler.cs │ ├── MqttOptions.cs │ ├── MqttSubscription.cs │ ├── MqttSubscriptionManager.cs │ ├── PacketProcessorManager.cs │ ├── Peach.Mqtt.csproj │ ├── Processor │ │ ├── AbsPacketProcessor.cs │ │ ├── ConnectPacketProcessor .cs │ │ ├── DisConnectPacketProcessor.cs │ │ ├── PingReqPacketProcessor.cs │ │ ├── PubAckPacketProcessor.cs │ │ ├── PubCompPacketProcessor.cs │ │ ├── PubRecPacketProcessor.cs │ │ ├── PubRelPacketProcessor.cs │ │ ├── PublishPacketProcessor.cs │ │ ├── SubscribePacketProcessor.cs │ │ └── UnSubscribePacketProcessor.cs │ └── ServiceCollectionExtensions.cs └── Peach │ ├── AbsSocketService.cs │ ├── Buffer │ ├── ByteBufferManager.cs │ ├── ByteBufferReader.cs │ ├── ByteBufferWriter.cs │ ├── IBufferReader.cs │ └── IBufferWriter.cs │ ├── Config │ ├── TcpClientOption.cs │ └── TcpHostOption.cs │ ├── Diagnostics │ └── DiagnosticListenerExtensions.cs │ ├── EventArgs │ ├── ConnectedEventArgs.cs │ ├── DisconnectedEventArgs.cs │ ├── ErrorEventArgs.cs │ ├── IdleStateEventArgs.cs │ └── MessageRecievedEventArgs.cs │ ├── HostBuilderExtensions.cs │ ├── Hosting │ ├── HostBuilderExtensions.cs │ └── PeachHostedService.cs │ ├── IChannelHandlerPipeline.cs │ ├── IServerBootstrap.cs │ ├── ISocketClient.cs │ ├── ISocketContext.cs │ ├── ISocketService.cs │ ├── Infrastructure │ ├── IPUtility.cs │ └── Preconditions.cs │ ├── Messaging │ ├── CommandLineMessage.cs │ ├── IMessage.cs │ └── MessageMeta.cs │ ├── Peach.csproj │ ├── Protocol │ ├── CommandLineChannelHandlerPipeline.cs │ ├── CommandLineDecodeHandler.cs │ ├── CommandLineEncodeHandler.cs │ └── CommandLineProtocol.cs │ ├── ServiceCollectionExtensions.cs │ ├── SocketContext.cs │ ├── Tcp │ ├── TcpClient.cs │ ├── TcpClientChannelHandlerAdapter.cs │ ├── TcpServerBootstrap.cs │ └── TcpServerChannelHandlerAdapter.cs │ └── icon.png └── tests └── Peach.UnitTests ├── Peach.UnitTests.csproj └── Tcp ├── TcpServerBootsrapTests.cs └── TcpServerChannelHandlerAdapterTests.cs /.editorconfig: -------------------------------------------------------------------------------- 1 | # Rules in this file were initially inferred by Visual Studio IntelliCode from the NetEscapades.AspNetCore.SecurityHeaders codebase based on best match to current usage at 16/11/2018 2 | # You can modify the rules from these initially generated values to suit your own policies 3 | # You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference 4 | [*.cs] 5 | 6 | #Core editorconfig formatting - indentation 7 | 8 | #use soft tabs (spaces) for indentation 9 | indent_style = space 10 | 11 | #Formatting - indentation options 12 | 13 | #indent switch case contents. 14 | csharp_indent_case_contents = true 15 | #indent switch labels 16 | csharp_indent_switch_labels = true 17 | 18 | #Formatting - new line options 19 | 20 | #require braces to be on a new line for types, object_collection, methods, control_blocks, and lambdas (also known as "Allman" style) 21 | csharp_new_line_before_open_brace = types, object_collection, methods, control_blocks, lambdas 22 | 23 | #Formatting - organize using options 24 | 25 | #sort System.* using directives alphabetically, and place them before other usings 26 | dotnet_sort_system_directives_first = true 27 | 28 | ... 29 | 30 | #Style - qualification options 31 | 32 | #prefer fields not to be prefaced with this. or Me. in Visual Basic 33 | dotnet_style_qualification_for_field = false:suggestion 34 | #prefer methods not to be prefaced with this. or Me. in Visual Basic 35 | dotnet_style_qualification_for_method = false:suggestion 36 | #prefer properties not to be prefaced with this. or Me. in Visual Basic 37 | dotnet_style_qualification_for_property = false:suggestion -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.doc diff=astextplain 2 | *.DOC diff=astextplain 3 | *.docx diff=astextplain 4 | *.DOCX diff=astextplain 5 | *.dot diff=astextplain 6 | *.DOT diff=astextplain 7 | *.pdf diff=astextplain 8 | *.PDF diff=astextplain 9 | *.rtf diff=astextplain 10 | *.RTF diff=astextplain 11 | 12 | *.jpg binary 13 | *.png binary 14 | *.gif binary 15 | 16 | *.cs text=auto diff=csharp 17 | *.vb text=auto 18 | *.resx text=auto 19 | *.c text=auto 20 | *.cpp text=auto 21 | *.cxx text=auto 22 | *.h text=auto 23 | *.hxx text=auto 24 | *.py text=auto 25 | *.rb text=auto 26 | *.java text=auto 27 | *.html text=auto 28 | *.htm text=auto 29 | *.css text=auto 30 | *.scss text=auto 31 | *.sass text=auto 32 | *.less text=auto 33 | *.js text=auto 34 | *.lisp text=auto 35 | *.clj text=auto 36 | *.sql text=auto 37 | *.php text=auto 38 | *.lua text=auto 39 | *.m text=auto 40 | *.asm text=auto 41 | *.erl text=auto 42 | *.fs text=auto 43 | *.fsx text=auto 44 | *.hs text=auto 45 | *.txt eol=crlf 46 | 47 | *.csproj text=auto 48 | *.vbproj text=auto 49 | *.fsproj text=auto 50 | *.dbproj text=auto 51 | *.sln text=auto eol=crlf 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Misc folders 2 | [Bb]in/ 3 | [Oo]bj/ 4 | [Pp]ackages/ 5 | 6 | # Build related 7 | tools/** 8 | !tools/packages.config 9 | 10 | ## Ignore Visual Studio temporary files, build results, and 11 | ## files generated by popular Visual Studio add-ons. 12 | 13 | # User-specific files 14 | *.suo 15 | *.user 16 | *.sln.docstates 17 | *.sln.ide/ 18 | *.userprefs 19 | *.GhostDoc.xml 20 | 21 | # Build results 22 | [Dd]ebug/ 23 | [Rr]elease/ 24 | x64/ 25 | *_i.c 26 | *_p.c 27 | *.ilk 28 | *.meta 29 | *.obj 30 | *.pch 31 | *.pdb 32 | *.pgc 33 | *.pgd 34 | *.rsp 35 | *.sbr 36 | *.tlb 37 | *.tli 38 | *.tlh 39 | *.tmp 40 | *.log 41 | *.vspscc 42 | *.vssscc 43 | .builds 44 | 45 | # Visual Studio profiler 46 | *.psess 47 | *.vsp 48 | *.vspx 49 | 50 | # ReSharper is a .NET coding add-in 51 | _ReSharper* 52 | 53 | # NCrunch 54 | *.ncrunch* 55 | .*crunch*.local.xml 56 | _NCrunch_* 57 | 58 | artifacts/ 59 | # NuGet Packages Directory 60 | packages 61 | 62 | # Windows 63 | Thumbs.db 64 | 65 | # NUnit 66 | TestResult.xml 67 | .vs/ 68 | .idea/ 69 | 70 | doc/_site/ 71 | 72 | node_modules/ 73 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "CommandLineServer", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/samples/CommandLine.Server/bin/Debug/netcoreapp2.2/CommandLine.Server.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/samples/CommandLine.Server", 16 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 17 | "console": "internalConsole", 18 | "stopAtEntry": false, 19 | "internalConsoleOptions": "openOnSessionStart" 20 | }, 21 | { 22 | "name": "CommandLineClient", 23 | "type": "coreclr", 24 | "request": "launch", 25 | "preLaunchTask": "build", 26 | // If you have changed target frameworks, make sure to update the program path. 27 | "program": "${workspaceFolder}/samples/CommandLine.Client/bin/Debug/netcoreapp2.2/CommandLine.Client.dll", 28 | "args": [], 29 | "cwd": "${workspaceFolder}/samples/CommandLine.Client", 30 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 31 | "console": "internalConsole", 32 | "stopAtEntry": false, 33 | "internalConsoleOptions": "openOnSessionStart" 34 | }, 35 | { 36 | "name": ".NET Core Attach", 37 | "type": "coreclr", 38 | "request": "attach", 39 | "processId": "${command:pickProcess}" 40 | } 41 | ,] 42 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "csharp2plantuml.inputPath": "./src/Peach", 3 | "csharp2plantuml.outputPath": "../../docs/puml", 4 | "plantuml.diagramsRoot": "./docs/puml", 5 | "plantuml.exportOutDir": "./docs/puml/diagram", 6 | } -------------------------------------------------------------------------------- /.vscode/solution-explorer/class.cs-template: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace {{namespace}} 4 | { 5 | public class {{name}} 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/solution-explorer/class.ts-template: -------------------------------------------------------------------------------- 1 | export class {{name}} { 2 | 3 | } -------------------------------------------------------------------------------- /.vscode/solution-explorer/class.vb-template: -------------------------------------------------------------------------------- 1 | Imports System 2 | 3 | Namespace {{namespace}} 4 | 5 | Public Class {{name}} 6 | 7 | End Class 8 | 9 | End Namespace 10 | -------------------------------------------------------------------------------- /.vscode/solution-explorer/default.ts-template: -------------------------------------------------------------------------------- 1 | export default {{name}} { 2 | 3 | } -------------------------------------------------------------------------------- /.vscode/solution-explorer/enum.cs-template: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace {{namespace}} 4 | { 5 | public enum {{name}} 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/solution-explorer/interface.cs-template: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace {{namespace}} 4 | { 5 | public interface {{name}} 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/solution-explorer/interface.ts-template: -------------------------------------------------------------------------------- 1 | export interface {{name}} { 2 | 3 | } -------------------------------------------------------------------------------- /.vscode/solution-explorer/template-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "templates": [ 3 | { 4 | "name": "Class", 5 | "extension": "cs", 6 | "file": "./class.cs-template", 7 | "parameters": "./template-parameters.js" 8 | }, 9 | { 10 | "name": "Interface", 11 | "extension": "cs", 12 | "file": "./interface.cs-template", 13 | "parameters": "./template-parameters.js" 14 | }, 15 | { 16 | "name": "Enum", 17 | "extension": "cs", 18 | "file": "./enum.cs-template", 19 | "parameters": "./template-parameters.js" 20 | }, 21 | { 22 | "name": "Class", 23 | "extension": "ts", 24 | "file": "./class.ts-template", 25 | "parameters": "./template-parameters.js" 26 | }, 27 | { 28 | "name": "Interface", 29 | "extension": "ts", 30 | "file": "./interface.ts-template", 31 | "parameters": "./template-parameters.js" 32 | }, 33 | { 34 | "name": "Default", 35 | "extension": "ts", 36 | "file": "./default.ts-template", 37 | "parameters": "./template-parameters.js" 38 | }, 39 | { 40 | "name": "Class", 41 | "extension": "vb", 42 | "file": "./class.vb-template", 43 | "parameters": "./template-parameters.js" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /.vscode/solution-explorer/template-parameters.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | 3 | module.exports = function(filename, projectPath, folderPath) { 4 | var namespace = "Unknown"; 5 | if (projectPath) { 6 | namespace = path.basename(projectPath, path.extname(projectPath)); 7 | if (folderPath) { 8 | namespace += "." + folderPath.replace(path.dirname(projectPath), "").substring(1).replace(/[\\\/]/g, "."); 9 | } 10 | } 11 | 12 | return { 13 | namespace: namespace, 14 | name: path.basename(filename, path.extname(filename)) 15 | } 16 | }; -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Peach.sln" 11 | ], 12 | "problemMatcher": "$msCompile", 13 | "group": { 14 | "kind": "build", 15 | "isDefault": true 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Xuanye Wong 2018 2 | All rights reserved. 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /Peach.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28803.452 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Peach", "src\Peach\Peach.csproj", "{9A445378-5A9A-46E4-B326-F8DC02E9FD5D}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{78D25C92-817A-4731-B4C5-9C4CC70AAF76}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D8B94637-5C7F-4C7E-8325-F2FCC5E98C43}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{59597665-809B-48F5-86F9-7432546C05CE}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommandLine.Server", "samples\CommandLine.Server\CommandLine.Server.csproj", "{7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommandLine.Client", "samples\CommandLine.Client\CommandLine.Client.csproj", "{BB965825-5D8B-4A97-80F1-46BCAD16E6AD}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Peach.UnitTests", "tests\Peach.UnitTests\Peach.UnitTests.csproj", "{97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Peach.Mqtt", "src\Peach.Mqtt\Peach.Mqtt.csproj", "{97316C3C-2C77-491F-BD63-CF3D1778E6CD}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mqtt.Server", "samples\Mqtt.Server\Mqtt.Server.csproj", "{3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mqtt.Client", "samples\Mqtt.Client\Mqtt.Client.csproj", "{D3680403-06BA-4F72-9D74-0A3FE8D4A637}" 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Any CPU = Debug|Any CPU 29 | Debug|x64 = Debug|x64 30 | Debug|x86 = Debug|x86 31 | Release|Any CPU = Release|Any CPU 32 | Release|x64 = Release|x64 33 | Release|x86 = Release|x86 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|x64.ActiveCfg = Debug|Any CPU 39 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|x64.Build.0 = Debug|Any CPU 40 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|x86.ActiveCfg = Debug|Any CPU 41 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Debug|x86.Build.0 = Debug|Any CPU 42 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|x64.ActiveCfg = Release|Any CPU 45 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|x64.Build.0 = Release|Any CPU 46 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|x86.ActiveCfg = Release|Any CPU 47 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D}.Release|x86.Build.0 = Release|Any CPU 48 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|x64.ActiveCfg = Debug|Any CPU 51 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|x64.Build.0 = Debug|Any CPU 52 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|x86.ActiveCfg = Debug|Any CPU 53 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Debug|x86.Build.0 = Debug|Any CPU 54 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|x64.ActiveCfg = Release|Any CPU 57 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|x64.Build.0 = Release|Any CPU 58 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|x86.ActiveCfg = Release|Any CPU 59 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2}.Release|x86.Build.0 = Release|Any CPU 60 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|x64.ActiveCfg = Debug|Any CPU 63 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|x64.Build.0 = Debug|Any CPU 64 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|x86.ActiveCfg = Debug|Any CPU 65 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Debug|x86.Build.0 = Debug|Any CPU 66 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|x64.ActiveCfg = Release|Any CPU 69 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|x64.Build.0 = Release|Any CPU 70 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|x86.ActiveCfg = Release|Any CPU 71 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD}.Release|x86.Build.0 = Release|Any CPU 72 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|x64.ActiveCfg = Debug|Any CPU 75 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|x64.Build.0 = Debug|Any CPU 76 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|x86.ActiveCfg = Debug|Any CPU 77 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Debug|x86.Build.0 = Debug|Any CPU 78 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|Any CPU.Build.0 = Release|Any CPU 80 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|x64.ActiveCfg = Release|Any CPU 81 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|x64.Build.0 = Release|Any CPU 82 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|x86.ActiveCfg = Release|Any CPU 83 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF}.Release|x86.Build.0 = Release|Any CPU 84 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 85 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|Any CPU.Build.0 = Debug|Any CPU 86 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|x64.ActiveCfg = Debug|Any CPU 87 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|x64.Build.0 = Debug|Any CPU 88 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|x86.ActiveCfg = Debug|Any CPU 89 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Debug|x86.Build.0 = Debug|Any CPU 90 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|Any CPU.ActiveCfg = Release|Any CPU 91 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|Any CPU.Build.0 = Release|Any CPU 92 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|x64.ActiveCfg = Release|Any CPU 93 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|x64.Build.0 = Release|Any CPU 94 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|x86.ActiveCfg = Release|Any CPU 95 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD}.Release|x86.Build.0 = Release|Any CPU 96 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 97 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|Any CPU.Build.0 = Debug|Any CPU 98 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|x64.ActiveCfg = Debug|Any CPU 99 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|x64.Build.0 = Debug|Any CPU 100 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|x86.ActiveCfg = Debug|Any CPU 101 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Debug|x86.Build.0 = Debug|Any CPU 102 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|Any CPU.ActiveCfg = Release|Any CPU 103 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|Any CPU.Build.0 = Release|Any CPU 104 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|x64.ActiveCfg = Release|Any CPU 105 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|x64.Build.0 = Release|Any CPU 106 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|x86.ActiveCfg = Release|Any CPU 107 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9}.Release|x86.Build.0 = Release|Any CPU 108 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 109 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|Any CPU.Build.0 = Debug|Any CPU 110 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|x64.ActiveCfg = Debug|Any CPU 111 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|x64.Build.0 = Debug|Any CPU 112 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|x86.ActiveCfg = Debug|Any CPU 113 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Debug|x86.Build.0 = Debug|Any CPU 114 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|Any CPU.ActiveCfg = Release|Any CPU 115 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|Any CPU.Build.0 = Release|Any CPU 116 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|x64.ActiveCfg = Release|Any CPU 117 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|x64.Build.0 = Release|Any CPU 118 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|x86.ActiveCfg = Release|Any CPU 119 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637}.Release|x86.Build.0 = Release|Any CPU 120 | EndGlobalSection 121 | GlobalSection(SolutionProperties) = preSolution 122 | HideSolutionNode = FALSE 123 | EndGlobalSection 124 | GlobalSection(NestedProjects) = preSolution 125 | {9A445378-5A9A-46E4-B326-F8DC02E9FD5D} = {D8B94637-5C7F-4C7E-8325-F2FCC5E98C43} 126 | {7E107A0B-6FF6-4A3E-AEBE-AF0DE62EF9B2} = {78D25C92-817A-4731-B4C5-9C4CC70AAF76} 127 | {BB965825-5D8B-4A97-80F1-46BCAD16E6AD} = {78D25C92-817A-4731-B4C5-9C4CC70AAF76} 128 | {97D4A91E-201F-4AD7-BBBE-7DD38ED6CBCF} = {59597665-809B-48F5-86F9-7432546C05CE} 129 | {97316C3C-2C77-491F-BD63-CF3D1778E6CD} = {D8B94637-5C7F-4C7E-8325-F2FCC5E98C43} 130 | {3A1D0ED9-EA6C-4FE2-8C34-C1E0EBB87AA9} = {78D25C92-817A-4731-B4C5-9C4CC70AAF76} 131 | {D3680403-06BA-4F72-9D74-0A3FE8D4A637} = {78D25C92-817A-4731-B4C5-9C4CC70AAF76} 132 | EndGlobalSection 133 | GlobalSection(ExtensibilityGlobals) = postSolution 134 | SolutionGuid = {F7455434-600D-4641-A642-06558190CF07} 135 | EndGlobalSection 136 | EndGlobal 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🍑Peach -- A lightweight and fast socket communication library based on DotNetty 2 | 3 | 基于DotNetty的Socket通讯类库,可通过扩展来实现任意协议,内置实现一个简单的文本协议.`CommandLineProtocol` 4 | 5 | # 使用 6 | 7 | ## 服务端 8 | 9 | ### 1. 实现MyService 10 | 可分别重写 11 | 1. `OnConnected` 有客户端连接上的事件 12 | 2. `OnDisConnected` 客户端断开连接时的事件 13 | 3. `OnReceive` 收到客户端消息的事件 14 | 4. `OnException` 发生异常时的事件,如异常断开 15 | 16 | ``` 17 | public class MyService : Peach.AbsSocketService 18 | { 19 | private readonly ILogger _logger; 20 | 21 | public MyService(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | public override void OnConnected(ISocketContext context) 26 | { 27 | _logger.LogInformation("client connected from {0}", context.RemoteEndPoint); 28 | base.OnConnected(context); 29 | } 30 | 31 | public override void OnDisconnected(ISocketContext context) 32 | { 33 | _logger.LogInformation("client disconnected from {0}", context.RemoteEndPoint); 34 | base.OnDisconnected(context); 35 | } 36 | 37 | public override void OnException(ISocketContext context, Exception ex) 38 | { 39 | _logger.LogError(ex,"client from {0}, occ error {1}", context.RemoteEndPoint,ex.Message); 40 | base.OnException(context, ex); 41 | } 42 | 43 | public override void OnReceive(ISocketContext context, CommandLineMessage msg) 44 | { 45 | string replyMessage = string.Empty; 46 | string replyCmd = string.Empty; 47 | switch (msg.Command) 48 | { 49 | case "echo": 50 | replyMessage = msg.Parameters[0]; 51 | replyCmd = "echo"; 52 | break; 53 | case "init": 54 | replyMessage = "ok"; 55 | replyCmd = "init_reply"; 56 | 57 | break; 58 | default: 59 | replyMessage = "error unknow command"; 60 | break; 61 | } 62 | 63 | 64 | Task.Run(async () => 65 | { 66 | await context.SendAsync(new CommandLineMessage(replyCmd, replyMessage)); 67 | }); 68 | } 69 | 70 | } 71 | ``` 72 | ### 2. 挂载服务 73 | 74 | 服务默认挂载在5566端口 75 | 76 | ``` 77 | static void Main(string[] args) 78 | { 79 | var builder = new HostBuilder() 80 | .ConfigureServices((context,services) => 81 | { 82 | //协议 83 | services.AddSingleton, CommandLineProtocol>(); 84 | //挂载服务逻辑 85 | services.AddSingleton, MyService>(); 86 | //添加挂载的宿主服务 87 | services.AddTcpServer(); 88 | }) 89 | .ConfigureLogging( 90 | logger => 91 | { 92 | logger.AddConsole(); 93 | } 94 | ); 95 | builder.RunConsoleAsync().Wait(); 96 | } 97 | ``` 98 | 99 | ## 客户端 100 | 101 | ### 1. 使用内置的TcpClient 102 | 103 | 监听接收消息和链接的消息,如下所示: 104 | ``` 105 | TcpClient client = new TcpClient(new CommandLineProtocol()); 106 | client.OnReceived += Client_OnReceived; 107 | client.OnConnected += Client_OnConnected; 108 | 109 | Task.Run(async () => 110 | { 111 | //连接服务器,可以链接多个哦 112 | var socketContext = await client.ConnectAsync(new IPEndPoint(Hey.IPUtility.GetLocalIntranetIP(), 5566)); 113 | //发送消息 114 | var initCmd = new Hey.Messaging.CommandLineMessage("init"); 115 | await socketContext.SendAsync(initCmd); 116 | }).Wait(); 117 | ``` 118 | 119 | 可用的事件: 120 | - `OnReceived` 当收到服务端消息时 121 | - `OnError` 当通讯发生异常时 122 | - `OnConnected` 当连接上服务器时 123 | - `OnDisconnected` 当与服务端断开链接时 124 | - `OnIdleState` 链接闲置时触发,一般在此事件中发送心跳包 125 | 126 | 127 | ## 扩展协议 128 | Peach支持使用自定义协议,扩展协议需要自行实现两个接口,可参考https://github.com/dotbpe/dotbpe 框架中关于Amp协议的实现 129 | 130 | ### 1. IMessage 接口 131 | 132 | 实现类具体实现通讯消息的内容载体,只需实现如何获取消息长度的属性 133 | 134 | ``` 135 | public interface IMessage 136 | { 137 | int Length { get; } 138 | } 139 | ``` 140 | 141 | ### 2. IProtocol 接口 142 | 143 | 实现类需要描述消息头信息和具体打包解包逻辑,头信息描述参见`ProtocolMeta`字段描述 144 | 145 | 146 | ``` 147 | /// 148 | /// 协议接口 149 | /// 150 | /// 151 | public interface IProtocol 152 | where TMessage : Messaging.IMessage 153 | { 154 | ProtocolMeta GetProtocolMeta(); 155 | 156 | TMessage Parse(Buffer.IBufferReader reader); 157 | 158 | void Pack(Buffer.IBufferWriter writer, TMessage message); 159 | 160 | } 161 | ``` -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | #### 0.1.4 Feb 27, 2019 2 | - 新增ssl支持 3 | 4 | #### 0.1.3 Feb 12, 2019 5 | - 修复没有正确发送心跳包的问题 6 | 7 | #### 0.1.2 Jan 10, 2019 8 | - 修复一些已知的问题 9 | - 找了一个好看的图标 10 | 11 | #### 0.1.1 December 31, 2018 12 | - 修复了使用中一些易用性问题 13 | - 新增ISocketClient的事件机制,方便扩展 14 | 15 | #### 0.1.0 December 24, 2018 16 | - 第一次发布,实现基本的通讯功能,内置CommandLine文本协议。 17 | -------------------------------------------------------------------------------- /build/releasenotes.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1. 重构Netty编解码管道插入方式,便于支持更多的扩展协议 5 | 2. 修改某些网络环境不存在内网IP的情况,导致默认绑定内网IP的行为出错。 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build/version.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0.2.2 4 | 0.1.1 5 | 6 | 7 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | _site 10 | -------------------------------------------------------------------------------- /doc/api/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # temp file # 3 | ############### 4 | *.yml 5 | .manifest 6 | -------------------------------------------------------------------------------- /doc/api/index.md: -------------------------------------------------------------------------------- 1 | # PLACEHOLDER 2 | TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*! 3 | -------------------------------------------------------------------------------- /doc/articles/intro.md: -------------------------------------------------------------------------------- 1 | # Add your introductions here! 2 | -------------------------------------------------------------------------------- /doc/articles/quickstart.md: -------------------------------------------------------------------------------- 1 | # 🍑Peach -- A lightweight and fast socket communication library based on DotNetty 2 | 3 | 基于DotNetty的Socket通讯类库,可通过扩展来实现任意协议,内置实现一个简单的文本协议.`CommandLineProtocol` 4 | 5 | # 使用 6 | 7 | ## 服务端 8 | 9 | ### 1. 实现MyService 10 | 可分别重写 11 | 1. `OnConnected` 有客户端连接上的事件 12 | 2. `OnDisConnected` 客户端断开连接时的事件 13 | 3. `OnReceive` 收到客户端消息的事件 14 | 4. `OnException` 发生异常时的事件,如异常断开 15 | 16 | ``` 17 | public class MyService : Peach.AbsSocketService 18 | { 19 | private readonly ILogger _logger; 20 | 21 | public MyService(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | public override void OnConnected(ISocketContext context) 26 | { 27 | _logger.LogInformation("client connected from {0}", context.RemoteEndPoint); 28 | base.OnConnected(context); 29 | } 30 | 31 | public override void OnDisconnected(ISocketContext context) 32 | { 33 | _logger.LogInformation("client disconnected from {0}", context.RemoteEndPoint); 34 | base.OnDisconnected(context); 35 | } 36 | 37 | public override void OnException(ISocketContext context, Exception ex) 38 | { 39 | _logger.LogError(ex,"client from {0}, occ error {1}", context.RemoteEndPoint,ex.Message); 40 | base.OnException(context, ex); 41 | } 42 | 43 | public override void OnReceive(ISocketContext context, CommandLineMessage msg) 44 | { 45 | string replyMessage = string.Empty; 46 | string replyCmd = string.Empty; 47 | switch (msg.Command) 48 | { 49 | case "echo": 50 | replyMessage = msg.Parameters[0]; 51 | replyCmd = "echo"; 52 | break; 53 | case "init": 54 | replyMessage = "ok"; 55 | replyCmd = "init_reply"; 56 | 57 | break; 58 | default: 59 | replyMessage = "error unknow command"; 60 | break; 61 | } 62 | 63 | 64 | Task.Run(async () => 65 | { 66 | await context.SendAsync(new CommandLineMessage(replyCmd, replyMessage)); 67 | }); 68 | } 69 | 70 | } 71 | ``` 72 | ### 2. 挂载服务 73 | 74 | 服务默认挂载在5566端口 75 | 76 | ``` 77 | static void Main(string[] args) 78 | { 79 | var builder = new HostBuilder() 80 | .ConfigureServices((context,services) => 81 | { 82 | //协议 83 | services.AddSingleton, CommandLineProtocol>(); 84 | //挂载服务逻辑 85 | services.AddSingleton, MyService>(); 86 | //添加挂载的宿主服务 87 | services.AddTcpServer(); 88 | }) 89 | .ConfigureLogging( 90 | logger => 91 | { 92 | logger.AddConsole(); 93 | } 94 | ); 95 | builder.RunConsoleAsync().Wait(); 96 | } 97 | ``` 98 | 99 | ## 客户端 100 | 101 | ### 1. 使用内置的TcpClient 102 | 103 | 监听接收消息和链接的消息,如下所示: 104 | ``` 105 | TcpClient client = new TcpClient(new CommandLineProtocol()); 106 | client.OnReceived += Client_OnReceived; 107 | client.OnConnected += Client_OnConnected; 108 | 109 | Task.Run(async () => 110 | { 111 | //连接服务器,可以链接多个哦 112 | var socketContext = await client.ConnectAsync(new IPEndPoint(Hey.IPUtility.GetLocalIntranetIP(), 5566)); 113 | //发送消息 114 | var initCmd = new Hey.Messaging.CommandLineMessage("init"); 115 | await socketContext.SendAsync(initCmd); 116 | }).Wait(); 117 | ``` 118 | 119 | 可用的事件: 120 | - `OnReceived` 当收到服务端消息时 121 | - `OnError` 当通讯发生异常时 122 | - `OnConnected` 当连接上服务器时 123 | - `OnDisconnected` 当与服务端断开链接时 124 | - `OnIdleState` 链接闲置时触发,一般在此事件中发送心跳包 125 | 126 | 127 | ## 扩展协议 128 | Peach支持使用自定义协议,扩展协议需要自行实现两个接口,可参考https://github.com/dotbpe/dotbpe 框架中关于Amp协议的实现 129 | 130 | ### 1. IMessage 接口 131 | 132 | 实现类具体实现通讯消息的内容载体,只需实现如何获取消息长度的属性 133 | 134 | ``` 135 | public interface IMessage 136 | { 137 | int Length { get; } 138 | } 139 | ``` 140 | 141 | ### 2. IProtocol 接口 142 | 143 | 实现类需要描述消息头信息和具体打包解包逻辑,头信息描述参见`ProtocolMeta`字段描述 144 | 145 | 146 | ``` 147 | /// 148 | /// 协议接口 149 | /// 150 | /// 151 | public interface IProtocol 152 | where TMessage : Messaging.IMessage 153 | { 154 | ProtocolMeta GetProtocolMeta(); 155 | 156 | TMessage Parse(Buffer.IBufferReader reader); 157 | 158 | void Pack(Buffer.IBufferWriter writer, TMessage message); 159 | 160 | } 161 | ``` -------------------------------------------------------------------------------- /doc/articles/toc.yml: -------------------------------------------------------------------------------- 1 | - name: 快速开始 2 | href: quickstart.md 3 | -------------------------------------------------------------------------------- /doc/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "src": "../src", 7 | "files": "**/*.csproj" 8 | } 9 | ], 10 | "dest": "api", 11 | "disableGitFeatures": false, 12 | "disableDefaultFilter": false 13 | } 14 | ], 15 | "build": { 16 | "content": [ 17 | { 18 | "files": [ 19 | "api/**.yml", 20 | "api/index.md" 21 | ] 22 | }, 23 | { 24 | "files": [ 25 | "articles/**.md", 26 | "articles/**/toc.yml", 27 | "toc.yml", 28 | "*.md" 29 | ] 30 | } 31 | ], 32 | "resource": [ 33 | { 34 | "files": [ 35 | "images/**" 36 | ] 37 | } 38 | ], 39 | "overwrite": [ 40 | { 41 | "files": [ 42 | "apidoc/**.md" 43 | ], 44 | "exclude": [ 45 | "obj/**", 46 | "_site/**" 47 | ] 48 | } 49 | ], 50 | "dest": "_site", 51 | "globalMetadataFiles": [], 52 | "fileMetadataFiles": [], 53 | "template": [ 54 | "default" 55 | ], 56 | "postProcessors": [], 57 | "markdownEngineName": "markdig", 58 | "noLangKeyword": false, 59 | "keepFileLink": false, 60 | "cleanupCacheHistory": false, 61 | "disableGitFeatures": false 62 | } 63 | } -------------------------------------------------------------------------------- /doc/index.md: -------------------------------------------------------------------------------- 1 | # 🍑Peach -- A lightweight and fast socket communication library based on DotNetty 2 | 3 | 基于DotNetty的Socket通讯类库,可通过扩展来实现任意协议,内置实现一个简单的文本协议.`CommandLineProtocol` 4 | 5 | # 使用 6 | 7 | ## 服务端 8 | 9 | ### 1. 实现MyService 10 | 可分别重写 11 | 1. `OnConnected` 有客户端连接上的事件 12 | 2. `OnDisConnected` 客户端断开连接时的事件 13 | 3. `OnReceive` 收到客户端消息的事件 14 | 4. `OnException` 发生异常时的事件,如异常断开 15 | 16 | ``` 17 | public class MyService : Peach.AbsSocketService 18 | { 19 | private readonly ILogger _logger; 20 | 21 | public MyService(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | public override void OnConnected(ISocketContext context) 26 | { 27 | _logger.LogInformation("client connected from {0}", context.RemoteEndPoint); 28 | base.OnConnected(context); 29 | } 30 | 31 | public override void OnDisconnected(ISocketContext context) 32 | { 33 | _logger.LogInformation("client disconnected from {0}", context.RemoteEndPoint); 34 | base.OnDisconnected(context); 35 | } 36 | 37 | public override void OnException(ISocketContext context, Exception ex) 38 | { 39 | _logger.LogError(ex,"client from {0}, occ error {1}", context.RemoteEndPoint,ex.Message); 40 | base.OnException(context, ex); 41 | } 42 | 43 | public override void OnReceive(ISocketContext context, CommandLineMessage msg) 44 | { 45 | string replyMessage = string.Empty; 46 | string replyCmd = string.Empty; 47 | switch (msg.Command) 48 | { 49 | case "echo": 50 | replyMessage = msg.Parameters[0]; 51 | replyCmd = "echo"; 52 | break; 53 | case "init": 54 | replyMessage = "ok"; 55 | replyCmd = "init_reply"; 56 | 57 | break; 58 | default: 59 | replyMessage = "error unknow command"; 60 | break; 61 | } 62 | 63 | 64 | Task.Run(async () => 65 | { 66 | await context.SendAsync(new CommandLineMessage(replyCmd, replyMessage)); 67 | }); 68 | } 69 | 70 | } 71 | ``` 72 | ### 2. 挂载服务 73 | 74 | 服务默认挂载在5566端口 75 | 76 | ``` 77 | static void Main(string[] args) 78 | { 79 | var builder = new HostBuilder() 80 | .ConfigureServices((context,services) => 81 | { 82 | //协议 83 | services.AddSingleton, CommandLineProtocol>(); 84 | //挂载服务逻辑 85 | services.AddSingleton, MyService>(); 86 | //添加挂载的宿主服务 87 | services.AddTcpServer(); 88 | }) 89 | .ConfigureLogging( 90 | logger => 91 | { 92 | logger.AddConsole(); 93 | } 94 | ); 95 | builder.RunConsoleAsync().Wait(); 96 | } 97 | ``` 98 | 99 | ## 客户端 100 | 101 | ### 1. 使用内置的TcpClient 102 | 103 | 监听接收消息和链接的消息,如下所示: 104 | ``` 105 | TcpClient client = new TcpClient(new CommandLineProtocol()); 106 | client.OnReceived += Client_OnReceived; 107 | client.OnConnected += Client_OnConnected; 108 | 109 | Task.Run(async () => 110 | { 111 | //连接服务器,可以链接多个哦 112 | var socketContext = await client.ConnectAsync(new IPEndPoint(Hey.IPUtility.GetLocalIntranetIP(), 5566)); 113 | //发送消息 114 | var initCmd = new Hey.Messaging.CommandLineMessage("init"); 115 | await socketContext.SendAsync(initCmd); 116 | }).Wait(); 117 | ``` 118 | 119 | 可用的事件: 120 | - `OnReceived` 当收到服务端消息时 121 | - `OnError` 当通讯发生异常时 122 | - `OnConnected` 当连接上服务器时 123 | - `OnDisconnected` 当与服务端断开链接时 124 | - `OnIdleState` 链接闲置时触发,一般在此事件中发送心跳包 125 | 126 | 127 | ## 扩展协议 128 | Peach支持使用自定义协议,扩展协议需要自行实现两个接口,可参考https://github.com/dotbpe/dotbpe 框架中关于Amp协议的实现 129 | 130 | ### 1. IMessage 接口 131 | 132 | 实现类具体实现通讯消息的内容载体,只需实现如何获取消息长度的属性 133 | 134 | ``` 135 | public interface IMessage 136 | { 137 | int Length { get; } 138 | } 139 | ``` 140 | 141 | ### 2. IProtocol 接口 142 | 143 | 实现类需要描述消息头信息和具体打包解包逻辑,头信息描述参见`ProtocolMeta`字段描述 144 | 145 | 146 | ``` 147 | /// 148 | /// 协议接口 149 | /// 150 | /// 151 | public interface IProtocol 152 | where TMessage : Messaging.IMessage 153 | { 154 | ProtocolMeta GetProtocolMeta(); 155 | 156 | TMessage Parse(Buffer.IBufferReader reader); 157 | 158 | void Pack(Buffer.IBufferWriter writer, TMessage message); 159 | 160 | } 161 | ``` -------------------------------------------------------------------------------- /doc/template/ManagedReference.html.primary.tmpl: -------------------------------------------------------------------------------- 1 | {{#item}} 2 | 3 | {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} 4 | 5 | 6 |
7 |
8 | {{^_disableBreadcrumb}} 9 | {{>partials/breadcrumb}} 10 | {{/_disableBreadcrumb}} 11 |
12 | {{#_enableSearch}} 13 |
14 | {{>partials/searchResults}} 15 |
16 | {{/_enableSearch}} 17 |