├── Assets ├── Scenes.meta ├── Scenes │ ├── SampleScene.unity │ └── SampleScene.unity.meta ├── TcpNetwork.meta ├── TcpNetwork │ ├── Runtime.meta │ ├── Runtime │ │ ├── MainThread.cs │ │ ├── MainThread.cs.meta │ │ ├── SendItem.cs │ │ ├── SendItem.cs.meta │ │ ├── SendItemPool.cs │ │ ├── SendItemPool.cs.meta │ │ ├── TcpBase.cs │ │ ├── TcpBase.cs.meta │ │ ├── TcpMono.cs │ │ ├── TcpMono.cs.meta │ │ ├── TcpNetwork.asmdef │ │ ├── TcpNetwork.asmdef.meta │ │ ├── TcpNetwork.cs │ │ └── TcpNetwork.cs.meta │ ├── package.json │ └── package.json.meta ├── Test.cs └── Test.cs.meta ├── LICENSE ├── README.md └── Release ├── TcpNetwork.dll ├── TcpNetwork.pdb ├── TcpNetwork1.0.1.dll └── TcpNetwork1.0.1.pdb /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ea315d0fd7389c41b19996891e99ae3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 705507994} 41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &433021226 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 433021228} 135 | - component: {fileID: 433021227} 136 | m_Layer: 0 137 | m_Name: TcpNetwork 138 | m_TagString: Untagged 139 | m_Icon: {fileID: 0} 140 | m_NavMeshLayer: 0 141 | m_StaticEditorFlags: 0 142 | m_IsActive: 1 143 | --- !u!114 &433021227 144 | MonoBehaviour: 145 | m_ObjectHideFlags: 0 146 | m_CorrespondingSourceObject: {fileID: 0} 147 | m_PrefabInstance: {fileID: 0} 148 | m_PrefabAsset: {fileID: 0} 149 | m_GameObject: {fileID: 433021226} 150 | m_Enabled: 1 151 | m_EditorHideFlags: 0 152 | m_Script: {fileID: 11500000, guid: 19524a79ec400c9418173a4c72e23ee2, type: 3} 153 | m_Name: 154 | m_EditorClassIdentifier: 155 | --- !u!4 &433021228 156 | Transform: 157 | m_ObjectHideFlags: 0 158 | m_CorrespondingSourceObject: {fileID: 0} 159 | m_PrefabInstance: {fileID: 0} 160 | m_PrefabAsset: {fileID: 0} 161 | m_GameObject: {fileID: 433021226} 162 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 163 | m_LocalPosition: {x: 415.9016, y: 1093.1838, z: -5.5220776} 164 | m_LocalScale: {x: 1, y: 1, z: 1} 165 | m_ConstrainProportionsScale: 0 166 | m_Children: [] 167 | m_Father: {fileID: 0} 168 | m_RootOrder: 2 169 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 170 | --- !u!1 &705507993 171 | GameObject: 172 | m_ObjectHideFlags: 0 173 | m_CorrespondingSourceObject: {fileID: 0} 174 | m_PrefabInstance: {fileID: 0} 175 | m_PrefabAsset: {fileID: 0} 176 | serializedVersion: 6 177 | m_Component: 178 | - component: {fileID: 705507995} 179 | - component: {fileID: 705507994} 180 | m_Layer: 0 181 | m_Name: Directional Light 182 | m_TagString: Untagged 183 | m_Icon: {fileID: 0} 184 | m_NavMeshLayer: 0 185 | m_StaticEditorFlags: 0 186 | m_IsActive: 1 187 | --- !u!108 &705507994 188 | Light: 189 | m_ObjectHideFlags: 0 190 | m_CorrespondingSourceObject: {fileID: 0} 191 | m_PrefabInstance: {fileID: 0} 192 | m_PrefabAsset: {fileID: 0} 193 | m_GameObject: {fileID: 705507993} 194 | m_Enabled: 1 195 | serializedVersion: 10 196 | m_Type: 1 197 | m_Shape: 0 198 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 199 | m_Intensity: 1 200 | m_Range: 10 201 | m_SpotAngle: 30 202 | m_InnerSpotAngle: 21.80208 203 | m_CookieSize: 10 204 | m_Shadows: 205 | m_Type: 2 206 | m_Resolution: -1 207 | m_CustomResolution: -1 208 | m_Strength: 1 209 | m_Bias: 0.05 210 | m_NormalBias: 0.4 211 | m_NearPlane: 0.2 212 | m_CullingMatrixOverride: 213 | e00: 1 214 | e01: 0 215 | e02: 0 216 | e03: 0 217 | e10: 0 218 | e11: 1 219 | e12: 0 220 | e13: 0 221 | e20: 0 222 | e21: 0 223 | e22: 1 224 | e23: 0 225 | e30: 0 226 | e31: 0 227 | e32: 0 228 | e33: 1 229 | m_UseCullingMatrixOverride: 0 230 | m_Cookie: {fileID: 0} 231 | m_DrawHalo: 0 232 | m_Flare: {fileID: 0} 233 | m_RenderMode: 0 234 | m_CullingMask: 235 | serializedVersion: 2 236 | m_Bits: 4294967295 237 | m_RenderingLayerMask: 1 238 | m_Lightmapping: 1 239 | m_LightShadowCasterMode: 0 240 | m_AreaSize: {x: 1, y: 1} 241 | m_BounceIntensity: 1 242 | m_ColorTemperature: 6570 243 | m_UseColorTemperature: 0 244 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 245 | m_UseBoundingSphereOverride: 0 246 | m_UseViewFrustumForShadowCasterCull: 1 247 | m_ShadowRadius: 0 248 | m_ShadowAngle: 0 249 | --- !u!4 &705507995 250 | Transform: 251 | m_ObjectHideFlags: 0 252 | m_CorrespondingSourceObject: {fileID: 0} 253 | m_PrefabInstance: {fileID: 0} 254 | m_PrefabAsset: {fileID: 0} 255 | m_GameObject: {fileID: 705507993} 256 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 257 | m_LocalPosition: {x: 0, y: 3, z: 0} 258 | m_LocalScale: {x: 1, y: 1, z: 1} 259 | m_ConstrainProportionsScale: 0 260 | m_Children: [] 261 | m_Father: {fileID: 0} 262 | m_RootOrder: 1 263 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 264 | --- !u!1 &963194225 265 | GameObject: 266 | m_ObjectHideFlags: 0 267 | m_CorrespondingSourceObject: {fileID: 0} 268 | m_PrefabInstance: {fileID: 0} 269 | m_PrefabAsset: {fileID: 0} 270 | serializedVersion: 6 271 | m_Component: 272 | - component: {fileID: 963194228} 273 | - component: {fileID: 963194227} 274 | - component: {fileID: 963194226} 275 | m_Layer: 0 276 | m_Name: Main Camera 277 | m_TagString: MainCamera 278 | m_Icon: {fileID: 0} 279 | m_NavMeshLayer: 0 280 | m_StaticEditorFlags: 0 281 | m_IsActive: 1 282 | --- !u!81 &963194226 283 | AudioListener: 284 | m_ObjectHideFlags: 0 285 | m_CorrespondingSourceObject: {fileID: 0} 286 | m_PrefabInstance: {fileID: 0} 287 | m_PrefabAsset: {fileID: 0} 288 | m_GameObject: {fileID: 963194225} 289 | m_Enabled: 1 290 | --- !u!20 &963194227 291 | Camera: 292 | m_ObjectHideFlags: 0 293 | m_CorrespondingSourceObject: {fileID: 0} 294 | m_PrefabInstance: {fileID: 0} 295 | m_PrefabAsset: {fileID: 0} 296 | m_GameObject: {fileID: 963194225} 297 | m_Enabled: 1 298 | serializedVersion: 2 299 | m_ClearFlags: 1 300 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 301 | m_projectionMatrixMode: 1 302 | m_GateFitMode: 2 303 | m_FOVAxisMode: 0 304 | m_SensorSize: {x: 36, y: 24} 305 | m_LensShift: {x: 0, y: 0} 306 | m_FocalLength: 50 307 | m_NormalizedViewPortRect: 308 | serializedVersion: 2 309 | x: 0 310 | y: 0 311 | width: 1 312 | height: 1 313 | near clip plane: 0.3 314 | far clip plane: 1000 315 | field of view: 60 316 | orthographic: 0 317 | orthographic size: 5 318 | m_Depth: -1 319 | m_CullingMask: 320 | serializedVersion: 2 321 | m_Bits: 4294967295 322 | m_RenderingPath: -1 323 | m_TargetTexture: {fileID: 0} 324 | m_TargetDisplay: 0 325 | m_TargetEye: 3 326 | m_HDR: 1 327 | m_AllowMSAA: 1 328 | m_AllowDynamicResolution: 0 329 | m_ForceIntoRT: 0 330 | m_OcclusionCulling: 1 331 | m_StereoConvergence: 10 332 | m_StereoSeparation: 0.022 333 | --- !u!4 &963194228 334 | Transform: 335 | m_ObjectHideFlags: 0 336 | m_CorrespondingSourceObject: {fileID: 0} 337 | m_PrefabInstance: {fileID: 0} 338 | m_PrefabAsset: {fileID: 0} 339 | m_GameObject: {fileID: 963194225} 340 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 341 | m_LocalPosition: {x: 0, y: 1, z: -10} 342 | m_LocalScale: {x: 1, y: 1, z: 1} 343 | m_ConstrainProportionsScale: 0 344 | m_Children: [] 345 | m_Father: {fileID: 0} 346 | m_RootOrder: 0 347 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 348 | -------------------------------------------------------------------------------- /Assets/Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fc0d4010bbf28b4594072e72b8655ab 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/TcpNetwork.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5321fb0c200e351418062c652f51ef25 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4b3c17bfd5347a4a9e44217e077263a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/MainThread.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace LeeFramework.Tcp 6 | { 7 | public class MainThread : SynchronizationContext 8 | { 9 | public static MainThread instance 10 | { 11 | get 12 | { 13 | if (_Instance == null) 14 | { 15 | _Instance = new MainThread(Thread.CurrentThread.ManagedThreadId); 16 | } 17 | return _Instance; 18 | } 19 | } 20 | private static MainThread _Instance; 21 | private Queue _AllAction = new Queue(); 22 | private int _ThreadId = 0; 23 | 24 | 25 | public MainThread(int id) 26 | { 27 | _ThreadId = id; 28 | TcpMono.instance.callback = OnUpdate; 29 | } 30 | 31 | public override void Post(SendOrPostCallback d, object state) 32 | { 33 | Post(() => 34 | { 35 | d?.Invoke(state); 36 | }); 37 | } 38 | 39 | public void Post(Action action) 40 | { 41 | try 42 | { 43 | if (Thread.CurrentThread.ManagedThreadId == _ThreadId) 44 | { 45 | action?.Invoke(); 46 | return; 47 | } 48 | lock (_AllAction) 49 | { 50 | _AllAction.Enqueue(action); 51 | } 52 | 53 | } 54 | catch (Exception e) 55 | { 56 | 57 | } 58 | } 59 | 60 | /// 61 | /// 下一阵执行 62 | /// 63 | public void Run(Action action) 64 | { 65 | lock (_AllAction) 66 | { 67 | _AllAction.Enqueue(action); 68 | } 69 | } 70 | 71 | public void OnUpdate() 72 | { 73 | lock (_AllAction) 74 | { 75 | if (_AllAction.Count > 0) 76 | { 77 | while (_AllAction.Count > 0) 78 | { 79 | Action action = _AllAction.Dequeue(); 80 | action?.Invoke(); 81 | } 82 | } 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/MainThread.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2087d914df002534fa9f364f7a148151 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/SendItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LeeFramework.Tcp 4 | { 5 | public class SendItem: IDisposable 6 | { 7 | public byte[] buff = null; 8 | 9 | public SendItem() 10 | { 11 | 12 | } 13 | 14 | public SendItem(byte[] data) 15 | { 16 | buff = data; 17 | } 18 | 19 | public void Dispose() 20 | { 21 | buff = null; 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/SendItem.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e92b8552a2b6f7c4e83ae71ec0595e2e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/SendItemPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace LeeFramework.Tcp 6 | { 7 | public class SendItemPool 8 | { 9 | private Stack _Pool; 10 | //最大对象个数,<=0表示不限个数 11 | protected int _MaxCount = 0; 12 | //没有回收的对象个数 13 | protected int _NoRecycleCount = 0; 14 | 15 | public SendItemPool(int count) 16 | { 17 | _Pool = new Stack(count); 18 | } 19 | 20 | 21 | public SendItem Spawn(bool isCreate = true) 22 | { 23 | if (_Pool.Count > 0) 24 | { 25 | SendItem rtn = _Pool.Pop(); 26 | if (rtn == null) 27 | { 28 | if (isCreate) 29 | { 30 | rtn = new SendItem(); 31 | } 32 | } 33 | 34 | _NoRecycleCount++; 35 | return rtn; 36 | } 37 | else 38 | { 39 | if (isCreate) 40 | { 41 | SendItem rtn = new SendItem(); 42 | _NoRecycleCount++; 43 | return rtn; 44 | } 45 | } 46 | return null; 47 | } 48 | 49 | public bool Recycle(SendItem item) 50 | { 51 | if (item == null) 52 | { 53 | return false; 54 | } 55 | 56 | _NoRecycleCount--; 57 | 58 | if (_Pool.Count >= _MaxCount && _MaxCount > 0) 59 | { 60 | item = null; 61 | return false; 62 | } 63 | 64 | item.Dispose(); 65 | _Pool.Push(item); 66 | return true; 67 | } 68 | 69 | public void Dispose() 70 | { 71 | _Pool.Clear(); 72 | } 73 | 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/SendItemPool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c0de3e8ada267445929482028ecd278 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpBase.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Assets/TcpNetwork/Runtime/TcpBase.cs -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cddba92694cdedc4a98b0becd0db7b35 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpMono.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace LeeFramework.Tcp 5 | { 6 | public class TcpMono : MonoBehaviour 7 | { 8 | private static TcpMono _Instance; 9 | private static GameObject _GameObject; 10 | public static TcpMono instance 11 | { 12 | get 13 | { 14 | if (_Instance == null) 15 | { 16 | _GameObject = new GameObject(typeof(TcpMono).ToString()); 17 | _GameObject.hideFlags = HideFlags.HideAndDontSave; 18 | DontDestroyOnLoad(_GameObject); 19 | _Instance = _GameObject.AddComponent(); 20 | } 21 | return _Instance; 22 | } 23 | } 24 | 25 | public Action callback = null; 26 | 27 | private void Awake() 28 | { 29 | if (_Instance == null) 30 | { 31 | gameObject.name = (typeof(TcpMono).ToString()); 32 | DontDestroyOnLoad(this); 33 | if (gameObject.GetComponent() == null) 34 | { 35 | _Instance = gameObject.AddComponent(); 36 | } 37 | else 38 | { 39 | _Instance = gameObject.GetComponent(); 40 | } 41 | } 42 | else 43 | { 44 | Destroy(this); 45 | } 46 | } 47 | 48 | 49 | private void Update() 50 | { 51 | callback?.Invoke(); 52 | } 53 | 54 | public virtual void Dispose() 55 | { 56 | _Instance = default; 57 | GameObject.Destroy(_GameObject.gameObject); 58 | GC.Collect(); 59 | } 60 | 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpMono.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5063d328edb7aa488c32b735fae8156 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpNetwork.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TcpNetwork" 3 | } 4 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpNetwork.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15375c0e1b647bb46853938227132d6c 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpNetwork.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Assets/TcpNetwork/Runtime/TcpNetwork.cs -------------------------------------------------------------------------------- /Assets/TcpNetwork/Runtime/TcpNetwork.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71e6adbf125e09247bea775cce3b7a65 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/TcpNetwork/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.leeframework.tcpnetwork", 3 | "displayName": "TcpNetwork", 4 | "description": "TcpNetwork", 5 | "version": "1.0.0", 6 | "unity": "2021.2", 7 | "license": "MIT", 8 | "dependencies": { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/TcpNetwork/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8646fc7968b29ac4eb3c0fceb7f48c8c 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Test.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Assets/Test.cs -------------------------------------------------------------------------------- /Assets/Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19524a79ec400c9418173a4c72e23ee2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Catson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TcpNetwork 2 | 3 | **联系作者:419731519(QQ)** 4 | 5 | ### =================TcpNetwork介绍================= 6 | #### 笔者一直寻求一种异步高性能的网络通讯方式,而在.Net中,微软提供了SocketAsyncEventArgs来实现IOCP 7 | #### 关于IOCP的优点,笔者不过多阐述,我这里对SocketAsyncEventArgs,Socket进行完整的封装,直接监听即可连接,发送,接收数据等 8 | #### 最终的性能,会比常规的BeginReceive,BeginSend高2倍以上! 9 | #### 具体的网络业务,需要开发者自行处理 10 | #### 觉得我的插件能帮助到你,麻烦帮我点个Star支持一下❤️ 11 | 12 | ### =================关于异步接收消息================= 13 | #### TcpNetwork.onConnect连接状态成功后,会立马开始接收消息 14 | #### 所以开发者,只需要监听TcpNetwork.onReceive即可接收消息 15 | #### 一般情况下,网络消息是在多线程下接收的,而多线程的消息,不能直接给Unity使用 16 | #### 笔者使用了MainThread,使得多线程的消息,安全转移到Unity主线程中 17 | #### 所以开发者可以安全的使用TcpNetwork.onReceive返回的消息,不需要再次转移到Unity主线程中 18 | 19 | ### =================关于异步发送消息================= 20 | #### 笔者使用了消息队列的方式来处理异步发送的消息,即上一条消息未发送完成,就不会发送下一条消息 21 | #### 以确保服务器所收到的消息,是有序 22 | 23 | ### =================使用方法================= 24 | - manifest.json中添加插件路径 或 直接引用Release内的dll(二选一) 25 | ```json 26 | { 27 | "dependencies": { 28 | "com.leeframework.tcpnetwork":"https://e.coding.net/ggdevlee/leeframework/TcpNetwork.git#1.0.1" 29 | } 30 | } 31 | ``` 32 | 33 | - 引入命名空间 34 | ```csharp 35 | using LeeFramework.Tcp; 36 | ``` 37 | 38 | - TcpNetwork初始化 39 | ```csharp 40 | private TcpNetwork _TcpNetwork; 41 | 42 | private void Start() 43 | { 44 | //ip与端口号 45 | _TcpNetwork = new TcpNetwork("127.0.0.1",1000); 46 | _TcpNetwork.onConnect = (state, args) => 47 | { 48 | Debug.Log("Connect : " + state.ToString()); 49 | }; 50 | 51 | _TcpNetwork.onDisconnect = (state, args) => 52 | { 53 | Debug.Log("Disconnect : " + state.ToString()); 54 | }; 55 | 56 | _TcpNetwork.onReceive = (state, buff) => 57 | { 58 | 59 | if (state) 60 | { 61 | Debug.Log("Receive : " + state + " " + Encoding.UTF8.GetString(buff)); 62 | } 63 | else 64 | { 65 | Debug.LogError("Receive : " + state + " " + Encoding.UTF8.GetString(buff)); 66 | } 67 | }; 68 | 69 | _TcpNetwork.onSend = (state, args) => 70 | { 71 | if (state) 72 | { 73 | Debug.Log("发送成功"); 74 | } 75 | else 76 | { 77 | Debug.LogError("发送失败"); 78 | } 79 | }; 80 | } 81 | ``` 82 | 83 | - 异步创建网络连接 84 | - 异步连接成功与失败,都会触发到TcpNetwork.onConnect事件 85 | - 异步连接成功后,会自动接收消息,接收到的消息,都会触发TcpNetwork.onReceive事件 86 | ```csharp 87 | 88 | public void ConnectAsync() 89 | { 90 | _TcpNetwork.ConnectAsync(); 91 | } 92 | 93 | ``` 94 | 95 | - 异步发送消息 96 | - 异步发送成功与失败,都会触发到TcpNetwork.onSend事件 97 | ```csharp 98 | 99 | public void SendAsync() 100 | { 101 | _TcpNetwork.SendAsync(Encoding.UTF8.GetBytes("HelloWorld!")); 102 | } 103 | 104 | ``` 105 | 106 | - 异步断开连接 107 | - 异步断开连接成功与失败,都会触发到TcpNetwork.onDisconnect事件 108 | 109 | ```csharp 110 | 111 | public void DisconnectAsync() 112 | { 113 | _TcpNetwork.DisconnectAsync(); 114 | } 115 | 116 | ``` 117 | 118 | - TcpNetwork网络状态 119 | ```csharp 120 | 121 | _TcpNetwork.client //Socket套接字 122 | 123 | _TcpNetwork.isConnecting //正在网络连接 124 | 125 | _TcpNetwork.isConnected //是否已经网络连接 126 | 127 | _TcpNetwork.isDisconnecting //正在断开连接 128 | 129 | _TcpNetwork.isDisconnected //是否已经断开连接 130 | 131 | _TcpNetwork.isSending //正在发送消息 132 | 133 | ``` 134 | 135 | -------------------------------------------------------------------------------- /Release/TcpNetwork.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Release/TcpNetwork.dll -------------------------------------------------------------------------------- /Release/TcpNetwork.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Release/TcpNetwork.pdb -------------------------------------------------------------------------------- /Release/TcpNetwork1.0.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Release/TcpNetwork1.0.1.dll -------------------------------------------------------------------------------- /Release/TcpNetwork1.0.1.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GGDevLee/UnityTcpNetwork/3b7448c585a360262cde3af5fde53d6babc8cb59/Release/TcpNetwork1.0.1.pdb --------------------------------------------------------------------------------