diff --git a/Assets/MsgTransmitTools/ExtendLinkModel.meta b/Assets/MsgTransmitTools/ExtendLinkModel.meta new file mode 100644 index 0000000..704c7d8 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8ed219fcc5699874f896054b77910c9e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/TCPClient.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient.meta diff --git a/Assets/MsgTransmitTools/TCPClient/Prefeb.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Prefeb.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb.meta diff --git a/Assets/MsgTransmitTools/TCPClient/Prefeb/TCPPrinter.prefab b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb/TCPPrinter.prefab similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Prefeb/TCPPrinter.prefab rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb/TCPPrinter.prefab diff --git a/Assets/MsgTransmitTools/TCPClient/Prefeb/TCPPrinter.prefab.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb/TCPPrinter.prefab.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Prefeb/TCPPrinter.prefab.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Prefeb/TCPPrinter.prefab.meta diff --git a/Assets/MsgTransmitTools/TCPClient/Script.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Script.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script.meta diff --git a/Assets/MsgTransmitTools/TCPClient/Script/TCPClientModel.cs b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientModel.cs similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Script/TCPClientModel.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientModel.cs diff --git a/Assets/MsgTransmitTools/TCPClient/Script/TCPClientModel.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientModel.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Script/TCPClientModel.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientModel.cs.meta diff --git a/Assets/MsgTransmitTools/TCPClient/Script/TCPClientView.cs b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientView.cs similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Script/TCPClientView.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientView.cs diff --git a/Assets/MsgTransmitTools/TCPClient/Script/TCPClientView.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientView.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPClient/Script/TCPClientView.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPClient/Script/TCPClientView.cs.meta diff --git a/Assets/MsgTransmitTools/TCPServer.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPServer.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer.meta diff --git a/Assets/MsgTransmitTools/TCPServer/Script.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPServer/Script.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script.meta diff --git a/Assets/MsgTransmitTools/TCPServer/Script/SocketServer.cs b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/SocketServer.cs similarity index 98% rename from Assets/MsgTransmitTools/TCPServer/Script/SocketServer.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/SocketServer.cs index e99eaf3..75dbc95 100644 --- a/Assets/MsgTransmitTools/TCPServer/Script/SocketServer.cs +++ b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/SocketServer.cs @@ -3,6 +3,8 @@ using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; +using System.Net.WebSockets; +using System.Web; using System.Text; using System.Threading; using UnityEngine; diff --git a/Assets/MsgTransmitTools/TCPServer/Script/SocketServer.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/SocketServer.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPServer/Script/SocketServer.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/SocketServer.cs.meta diff --git a/Assets/MsgTransmitTools/TCPServer/Script/TCPServerModel.cs b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/TCPServerModel.cs similarity index 100% rename from Assets/MsgTransmitTools/TCPServer/Script/TCPServerModel.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/TCPServerModel.cs diff --git a/Assets/MsgTransmitTools/TCPServer/Script/TCPServerModel.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/TCPServerModel.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/TCPServer/Script/TCPServerModel.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/TCPServer/Script/TCPServerModel.cs.meta diff --git a/Assets/MsgTransmitTools/UDPClient.meta b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient.meta similarity index 100% rename from Assets/MsgTransmitTools/UDPClient.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient.meta diff --git a/Assets/MsgTransmitTools/UDPClient/UDPClientView.cs b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPClientView.cs similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPClientView.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPClientView.cs diff --git a/Assets/MsgTransmitTools/UDPClient/UDPClientView.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPClientView.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPClientView.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPClientView.cs.meta diff --git a/Assets/MsgTransmitTools/UDPClient/UDPEventModel.cs b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPEventModel.cs similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPEventModel.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPEventModel.cs diff --git a/Assets/MsgTransmitTools/UDPClient/UDPEventModel.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPEventModel.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPEventModel.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPEventModel.cs.meta diff --git a/Assets/MsgTransmitTools/UDPClient/UDPPrinter.cs b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPPrinter.cs similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPPrinter.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPPrinter.cs diff --git a/Assets/MsgTransmitTools/UDPClient/UDPPrinter.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPPrinter.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPPrinter.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPPrinter.cs.meta diff --git a/Assets/MsgTransmitTools/UDPClient/UDPUtility.cs b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPUtility.cs similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPUtility.cs rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPUtility.cs diff --git a/Assets/MsgTransmitTools/UDPClient/UDPUtility.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPUtility.cs.meta similarity index 100% rename from Assets/MsgTransmitTools/UDPClient/UDPUtility.cs.meta rename to Assets/MsgTransmitTools/ExtendLinkModel/UDPClient/UDPUtility.cs.meta diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket.meta new file mode 100644 index 0000000..31851dc --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 799120a631a78f74da78ed6ca397818a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server.meta new file mode 100644 index 0000000..99cdf30 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1af376cc70619ba4ba8877d7442e8e55 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs new file mode 100644 index 0000000..af5b799 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +using WebSocketServer; + +public class MyWebSocketServer : WebSocketServer.WebSocketServer +{ + override public void OnOpen(WebSocketConnection connection) { + // Here, (string)connection.id gives you a unique ID to identify the client. + Debug.Log(connection.id); + } + + override public void OnMessage(WebSocketMessage message) { + // (WebSocketConnection)message.connection gives you the connection that send the message. + // (string)message.id gives you a unique ID for the message. + // (string)message.data gives you the message content. + Debug.Log(message.connection.id); + Debug.Log(message.id); + Debug.Log(message.data); + } + + + override public void OnClose(WebSocketConnection connection) { + // Here is the same as OnOpen + Debug.Log(connection.id); + } + + public void onConnectionOpened (WebSocketConnection connection) { + Debug.Log("Connection opened: " + connection.id); + } + + public void onMessageReceived (WebSocketMessage message) { + Debug.Log("Received new message: " + message.data); + } + + public void onConnectionClosed (WebSocketConnection connection) { + Debug.Log("Connection closed: " + connection.id); + } +} diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs.meta new file mode 100644 index 0000000..d152835 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/MyWebSocketServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cae6cd5a80444e79b49b1b23e819bb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes.meta new file mode 100644 index 0000000..ceb8af1 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4ebafb77ac26644d5add696267d4e150 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity new file mode 100644 index 0000000..f41ec8b --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity @@ -0,0 +1,293 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + - component: {fileID: 519420029} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &519420029 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &944133941 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 944133943} + - component: {fileID: 944133942} + m_Layer: 0 + m_Name: WebSocket Server + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &944133942 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 944133941} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5cae6cd5a80444e79b49b1b23e819bb0, type: 3} + m_Name: + m_EditorClassIdentifier: + address: 192.168.1.41 + port: 20000 + onOpen: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 944133942} + m_MethodName: onConnectionOpened + m_Mode: 0 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + onMessage: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 944133942} + m_MethodName: onMessageReceived + m_Mode: 0 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + onClose: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 944133942} + m_MethodName: onConnectionClosed + m_Mode: 0 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!4 &944133943 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 944133941} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity.meta new file mode 100644 index 0000000..c1e3c88 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2cda990e2423bbf4892e6590ba056729 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer.meta new file mode 100644 index 0000000..3904def --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 90c4b056dd07146b4b6f2a9d235c0be9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs new file mode 100644 index 0000000..8f88596 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs @@ -0,0 +1,165 @@ +using UnityEngine; + +using System; +using System.Net; +using System.Net.Sockets; +using System.Collections.Concurrent; +// For parsing the client websocket requests +using System.Text; +using System.Text.RegularExpressions; +// For creating a thread +using System.Threading; + + +namespace WebSocketServer { + + public enum WebSocketEventType { + Open, + Close, + Message + } + + public struct WebSocketMessage { + public WebSocketMessage(WebSocketConnection connection, string data) { + this.id = Guid.NewGuid().ToString(); + this.connection = connection; + this.data = data; + } + + public string id { get; } + public WebSocketConnection connection { get; } + public string data { get; } + } + + public struct WebSocketEvent { + public WebSocketEvent(WebSocketConnection connection, WebSocketEventType type, string data) { + this.id = Guid.NewGuid().ToString(); + this.connection = connection; + this.type = type; + this.data = data; + } + + public string id { get; } + public WebSocketEventType type { get; } + public WebSocketConnection connection { get; } + public string data { get; } + } + + public class WebSocketConnection { + + public string id; + private TcpClient client; + private NetworkStream stream; + private WebSocketServer server; + private Thread connectionHandler; + + public WebSocketConnection(TcpClient client, WebSocketServer server) { + this.id = Guid.NewGuid().ToString(); + this.client = client; + this.stream = client.GetStream(); + this.server = server; + } + + public bool Establish() { + // Wait for enough bytes to be available + while (!stream.DataAvailable); + while(client.Available < 3); + // Translate bytes of request to a RequestHeader object + Byte[] bytes = new Byte[client.Available]; + stream.Read(bytes, 0, bytes.Length); + RequestHeader request = new RequestHeader(Encoding.UTF8.GetString(bytes)); + + // Check if the request complies with WebSocket protocol. + if (WebSocketProtocol.CheckConnectionHandshake(request)) { + // If so, initiate the connection by sending a reply according to protocol. + Byte[] response = WebSocketProtocol.CreateHandshakeReply(request); + stream.Write(response, 0, response.Length); + + Debug.Log("WebSocket client connected."); + + // Start message handling + connectionHandler = new Thread(new ThreadStart(HandleConnection)); + connectionHandler.IsBackground = true; + connectionHandler.Start(); + + // Call the server callback. + WebSocketEvent wsEvent = new WebSocketEvent(this, WebSocketEventType.Open, null); + server.events.Enqueue(wsEvent); + return true; + } else { + return false; + } + } + + private void HandleConnection () { + while (true) { + WebSocketDataFrame dataframe = ReadDataFrame(); + + if (dataframe.fin) { + if ((WebSocketOpCode)dataframe.opcode == WebSocketOpCode.Text) { + // Let the server know of the message. + string data = WebSocketProtocol.DecodeText(dataframe); + WebSocketEvent wsEvent = new WebSocketEvent(this, WebSocketEventType.Message, data); + server.events.Enqueue(wsEvent); + } else if ((WebSocketOpCode)dataframe.opcode == WebSocketOpCode.Close) { + // Handle closing the connection. + Debug.Log("Client closed the connection."); + // Close the connection. + stream.Close(); + client.Close(); + // Call server callback. + WebSocketEvent wsEvent = new WebSocketEvent(this, WebSocketEventType.Close, null); + server.events.Enqueue(wsEvent); + // Jump out of the loop. + break; + } + } else { + Debug.Log("Framentation encoutered."); + } + } + } + + + private WebSocketDataFrame ReadDataFrame() { + const int DataframeHead = 2; // Length of dataframe head + const int ShortPayloadLength = 2; // Length of a short payload length field + const int LongPayloadLength = 8; // Length of a long payload length field + const int Mask = 4; // Length of the payload mask + + // Wait for a dataframe head to be available, then read the data. + while (!stream.DataAvailable && client.Available < DataframeHead); + Byte[] bytes = new Byte[DataframeHead]; + stream.Read(bytes, 0, DataframeHead); + + // Decode the message head, including FIN, OpCode, and initial byte of the payload length. + WebSocketDataFrame dataframe = WebSocketProtocol.CreateDataFrame(); + WebSocketProtocol.ParseDataFrameHead(bytes, ref dataframe); + + // Depending on the dataframe length, read & decode the next bytes for payload length + if (dataframe.length == 126) { + while (client.Available < ShortPayloadLength); // Wait until data is available + Array.Resize(ref bytes, bytes.Length + ShortPayloadLength); + stream.Read(bytes, bytes.Length - ShortPayloadLength, ShortPayloadLength); // Read the next two bytes for length + } else if (dataframe.length == 127) { + while (client.Available < LongPayloadLength); // Wait until data is available + Array.Resize(ref bytes, bytes.Length + LongPayloadLength); + stream.Read(bytes, bytes.Length - LongPayloadLength, LongPayloadLength); // Read the next two bytes for length + } + WebSocketProtocol.ParseDataFrameLength(bytes, ref dataframe); // Parse the length + + if (dataframe.mask) { + while (client.Available < Mask); // Wait until data is available + Array.Resize(ref bytes, bytes.Length + Mask); + stream.Read(bytes, bytes.Length - Mask, Mask); // Read the next four bytes for mask + } + + while (client.Available < dataframe.length); // Wait until data is available + Array.Resize(ref bytes, bytes.Length + dataframe.length); + stream.Read(bytes, bytes.Length - dataframe.length, dataframe.length); // Read the payload + dataframe.data = bytes; + + return dataframe; + } + } + +} \ No newline at end of file diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs.meta new file mode 100644 index 0000000..a5bb20b --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb7ccee6494e64db7bd20c7e8cfd0a78 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs new file mode 100644 index 0000000..efdeb1e --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs @@ -0,0 +1,188 @@ +using UnityEngine; +// For String +using System; +// For dictionary +using System.Collections.Generic; +// For parsing the client websocket requests +using System.Text; +using System.Text.RegularExpressions; + +namespace WebSocketServer { + + struct WebSocketDataFrame { + public WebSocketDataFrame(bool fin, bool mask, int opcode, int length, int offset, Byte[] data) { + this.fin = fin; + this.mask = mask; + this.opcode = opcode; + this.length = length; + this.offset = offset; + this.data = data; + } + + public bool fin { get; set; } + public bool mask { get; set; } + public int opcode { get; set; } + public int length { get; set; } + public int offset { get; set; } + public byte[] data { get; set; } + } + + class RequestHeader { + + static Regex head = new Regex("^(GET|POST|PUT|DELETE|OPTIONS) (.+) HTTP/([0-9.]+)", RegexOptions.Compiled); + static Regex body = new Regex("([A-Za-z0-9-]+): ?([^\n^\r]+)", RegexOptions.Compiled); + + public string method = ""; + public string uri = ""; + public string version = ""; + public Dictionary headers; + + public RequestHeader(string data) { + headers = new Dictionary(); + + MatchCollection matches = head.Matches(data); + foreach (Match match in matches) { + method = match.Groups[1].Value.Trim(); + uri = match.Groups[2].Value.Trim(); + version = match.Groups[3].Value.Trim(); + } + + matches = body.Matches(data); + foreach (Match match in matches) { + headers.Add(match.Groups[1].Value.Trim(), match.Groups[2].Value.Trim()); + } + } + } + + class WebSocketProtocol { + + public static bool CheckConnectionHandshake(RequestHeader request) { + // The method must be GET. + if (!String.Equals(request.method, "GET")) { + Debug.Log("Request does not begin with GET."); + return false; + } + // TODO: Version must be greater than "1.1". + // Must have a Host. + if (!request.headers.ContainsKey("Host")) { + Debug.Log("Request does not have a Host."); + return false; + } + // Must have a Upgrade: websocket + if (!request.headers.ContainsKey("Upgrade") || !String.Equals(request.headers["Upgrade"], "websocket")) { + Debug.Log("Request does not have Upgrade: websocket."); + return false; + } + + // Must have a Connection: Upgrade + if (!request.headers.ContainsKey("Connection") || request.headers["Connection"].IndexOf("Upgrade") == -1) { + Debug.Log("Request does not have Connection: Upgrade."); + return false; + } + + // Must have a Sec-WebSocket-Key + if (!request.headers.ContainsKey("Sec-WebSocket-Key")) { + Debug.Log("Request does not have Sec-WebSocket-Key"); + return false; + } + + // Must have a Sec-WebSocket-Key + if (!request.headers.ContainsKey("Sec-WebSocket-Key")) { + Debug.Log("Request does not have Sec-WebSocket-Key"); + return false; + } + + // Must have a Sec-WebSocket-Version: 13 + if (!request.headers.ContainsKey("Sec-WebSocket-Version") || !String.Equals(request.headers["Sec-WebSocket-Version"], "13")) { + Debug.Log("Request does not have Sec-WebSocket-Version: 13"); + return false; + } + + return true; + } + + public static Byte[] CreateHandshakeReply(RequestHeader request) { + const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker + + Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol + + "Connection: Upgrade" + eol + + "Upgrade: websocket" + eol + + "Sec-WebSocket-Accept: " + Convert.ToBase64String( + System.Security.Cryptography.SHA1.Create().ComputeHash( + Encoding.UTF8.GetBytes( + request.headers["Sec-WebSocket-Key"] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + ) + ) + ) + eol + + eol); + + return response; + } + + public static WebSocketDataFrame CreateDataFrame() { + return new WebSocketDataFrame(false, false, 0, 0, 0, null); + } + + public static void ParseDataFrameHead(byte[] bytes, ref WebSocketDataFrame dataframe) { + bool fin = (bytes[0] & 0b10000000) != 0, + mask = (bytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set" + + int opcode = bytes[0] & 0b00001111; + int msglen = bytes[1] & 0b01111111, + offset = 2; + + dataframe.fin = fin; + dataframe.mask = mask; + dataframe.opcode = opcode; + dataframe.length = msglen; + dataframe.offset = offset; + dataframe.data = bytes; + } + + public static void ParseDataFrameLength(byte[] bytes, ref WebSocketDataFrame dataframe) { + if (dataframe.length == 126) { + // was ToUInt16(bytes, offset) but the result is incorrect + dataframe.length = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0); + dataframe.offset = 4; + } else if (dataframe.length == 127) { + dataframe.length = (int) BitConverter.ToUInt64(new byte[] { + bytes[9], bytes[8], bytes[7], bytes[6], + bytes[5], bytes[4], bytes[3], bytes[2] + }, 0); + dataframe.offset = 10; + } + } + + public static string DecodeText(WebSocketDataFrame dataframe) { + if (dataframe.length > 0 && dataframe.mask) { + byte[] decoded = new byte[dataframe.length]; + byte[] masks = new byte[4] { + dataframe.data[dataframe.offset], + dataframe.data[dataframe.offset + 1], + dataframe.data[dataframe.offset + 2], + dataframe.data[dataframe.offset + 3] + }; + int payloadOffset = dataframe.offset + 4; + + for (int i = 0; i < dataframe.length; ++i) { + decoded[i] = (byte)(dataframe.data[payloadOffset + i] ^ masks[i % 4]); + } + + string text = Encoding.UTF8.GetString(decoded); + return text; + } + return ""; + } + + } + + enum WebSocketOpCode { + Continuation = 0x0, + Text = 0x1, + Binary = 0x2, + Close = 0x8, + Ping = 0x9, + Pong = 0xA + } + +} \ No newline at end of file diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs.meta new file mode 100644 index 0000000..b894380 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7f4a1fb063a4455d96289977a51d644 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs new file mode 100644 index 0000000..9668503 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs @@ -0,0 +1,154 @@ +using System; +// Networking libs +using System.Net; +using System.Net.Sockets; +// For creating a thread +using System.Threading; +// For List & ConcurrentQueue +using System.Collections.Generic; +using System.Collections.Concurrent; +// Unity & Unity events +using UnityEngine; +using UnityEngine.Events; + +namespace WebSocketServer { + [System.Serializable] + public class WebSocketOpenEvent : UnityEvent {} + + [System.Serializable] + public class WebSocketMessageEvent : UnityEvent {} + + [System.Serializable] + public class WebSocketCloseEvent : UnityEvent {} + + public class WebSocketServer : MonoBehaviour + { + // The tcpListenerThread listens for incoming WebSocket connections, then assigns the client to handler threads; + private TcpListener tcpListener; + private Thread tcpListenerThread; + private List workerThreads; + private TcpClient connectedTcpClient; + + public ConcurrentQueue events; + + public string address; + public int port; + public WebSocketOpenEvent onOpen; + public WebSocketMessageEvent onMessage; + public WebSocketCloseEvent onClose; + + void Awake() { + if (onMessage == null) onMessage = new WebSocketMessageEvent(); + } + + void Start() { + events = new ConcurrentQueue(); + workerThreads = new List(); + + tcpListenerThread = new Thread (new ThreadStart(ListenForTcpConnection)); + tcpListenerThread.IsBackground = true; + tcpListenerThread.Start(); + } + + void Update() { + WebSocketEvent wsEvent; + while (events.TryDequeue(out wsEvent)) { + if (wsEvent.type == WebSocketEventType.Open) { + onOpen.Invoke(wsEvent.connection); + this.OnOpen(wsEvent.connection); + } else if (wsEvent.type == WebSocketEventType.Close) { + onClose.Invoke(wsEvent.connection); + this.OnClose(wsEvent.connection); + } else if (wsEvent.type == WebSocketEventType.Message) { + WebSocketMessage message = new WebSocketMessage(wsEvent.connection, wsEvent.data); + onMessage.Invoke(message); + this.OnMessage(message); + } + } + } + + private void ListenForTcpConnection () { + try { + // Create listener on
:. + tcpListener = new TcpListener(IPAddress.Parse(address), port); + tcpListener.Start(); + Debug.Log("WebSocket server is listening for incoming connections."); + while (true) { + // Accept a new client, then open a stream for reading and writing. + connectedTcpClient = tcpListener.AcceptTcpClient(); + // Create a new connection + WebSocketConnection connection = new WebSocketConnection(connectedTcpClient, this); + // Establish connection + connection.Establish(); + // // Start a new thread to handle the connection. + // Thread worker = new Thread (new ParameterizedThreadStart(HandleConnection)); + // worker.IsBackground = true; + // worker.Start(connection); + // // Add it to the thread list. TODO: delete thread when disconnecting. + // workerThreads.Add(worker); + } + } + catch (SocketException socketException) { + Debug.Log("SocketException " + socketException.ToString()); + } + } + + // private void HandleConnection (object parameter) { + // WebSocketConnection connection = (WebSocketConnection)parameter; + // while (true) { + // string message = ReceiveMessage(connection.client, connection.stream); + // connection.queue.Enqueue(message); + // } + // } + + // private string ReceiveMessage(TcpClient client, NetworkStream stream) { + // // Wait for data to be available, then read the data. + // while (!stream.DataAvailable); + // Byte[] bytes = new Byte[client.Available]; + // stream.Read(bytes, 0, bytes.Length); + + // return WebSocketProtocol.DecodeMessage(bytes); + // } + + public virtual void OnOpen(WebSocketConnection connection) {} + + public virtual void OnMessage(WebSocketMessage message) {} + + public virtual void OnClose(WebSocketConnection connection) {} + + public virtual void OnError(WebSocketConnection connection) {} + + + public void OnDestroy() + { + if (null != tcpListener) { + tcpListenerThread.Abort(); + tcpListener.Stop(); + } + } + + + // private void SendMessage() { + // if (connectedTcpClient == null) { + // return; + // } + + // try { + // // Get a stream object for writing. + // NetworkStream stream = connectedTcpClient.GetStream(); + // if (stream.CanWrite) { + // string serverMessage = "This is a message from your server."; + // // Convert string message to byte array. + // byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(serverMessage); + // // Write byte array to socketConnection stream. + // stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length); + // Debug.Log("Server sent his message - should be received by client"); + // } + // } + // catch (SocketException socketException) { + // Debug.Log("Socket exception: " + socketException); + // } + // } + } +} + diff --git a/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs.meta b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs.meta new file mode 100644 index 0000000..983caa3 --- /dev/null +++ b/Assets/MsgTransmitTools/ExtendLinkModel/WebSocket/Server/WebSocketServer/WebSocketServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ac217db4dad5436d9927ea08182cd9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: