| 
						
						
							
								
							
						
						
					 | 
					@ -3,6 +3,7 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					using Apewer; | 
					 | 
					 | 
					using Apewer; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					using System; | 
					 | 
					 | 
					using System; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					using System.Collections.Generic; | 
					 | 
					 | 
					using System.Collections.Generic; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					using System.Net; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					namespace Apewer.WebSocket | 
					 | 
					 | 
					namespace Apewer.WebSocket | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -11,15 +12,12 @@ namespace Apewer.WebSocket | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    public sealed class GenericServer : IDisposable | 
					 | 
					 | 
					    public sealed class GenericServer : IDisposable | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    { | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        const string DefaultAddress = "0.0.0.0"; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        const ushort DefaultPort = 8000; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        private Dictionary<int, Connection> _connections = new Dictionary<int, Connection>(); | 
					 | 
					 | 
					        private Dictionary<int, Connection> _connections = new Dictionary<int, Connection>(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        private WebSocketServer _server = null; | 
					 | 
					 | 
					        private WebSocketServer _server = null; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        private bool _running = false; | 
					 | 
					 | 
					        private bool _running = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        private string _address = null; | 
					 | 
					 | 
					        private IPAddress _address = null; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        private int _port = DefaultPort; | 
					 | 
					 | 
					        private int _port = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        /// <summary></summary>
 | 
					 | 
					 | 
					        /// <summary></summary>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        public event SocketEvent OnOpen; | 
					 | 
					 | 
					        public event SocketEvent OnOpen; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -54,7 +52,7 @@ namespace Apewer.WebSocket | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        /// <summary>监听的地址。</summary>
 | 
					 | 
					 | 
					        /// <summary>监听的地址。</summary>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        public string Address | 
					 | 
					 | 
					        public IPAddress Address | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        { | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            get { return _address; } | 
					 | 
					 | 
					            get { return _address; } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -101,28 +99,46 @@ namespace Apewer.WebSocket | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            _running = false; | 
					 | 
					 | 
					            _running = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <summary>启动监听,如果监听正在运行则失败。在所有 IPv4 网络接口上自动选择可用的端口号。</summary>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <returns>已监听的端口号。</returns>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="FormatException" />
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="InvalidOperationException" />
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        public void Start() => Start(0, null); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        /// <summary>启动监听,如果监听正在运行则失败。</summary>
 | 
					 | 
					 | 
					        /// <summary>启动监听,如果监听正在运行则失败。</summary>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        public bool Start(int port = DefaultPort, string address = DefaultAddress) | 
					 | 
					 | 
					        /// <param name="endPoint">要监听的终结点。指定为 NULL 时将在所有 IPv4 网络接口上自动选择可用的端口号。</param>
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <returns>已监听的端口号。</returns>
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="ArgumentOutOfRangeException" />
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="FormatException" />
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        /// <exception cref="InvalidOperationException" />
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        public void Start(IPEndPoint endPoint) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        { | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            if (address == null) return false; | 
					 | 
					 | 
					            if (endPoint == null) Start(0, null); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            if (_running) return false; | 
					 | 
					 | 
					            else Start(endPoint.Port, endPoint.Address); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					        } | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					            _address = address ?? ""; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            _port = NumberUtility.Restrict( port, 0, ushort.MaxValue); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            try | 
					 | 
					 | 
					        /// <summary>启动监听,如果监听正在运行则失败。</summary>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            { | 
					 | 
					 | 
					        /// <param name="port">要监听的端口号。指定为 0 时将自动选择可用的端口号。</param>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                var location = "ws://" + address + ":" + port.ToString(); | 
					 | 
					 | 
					        /// <param name="address">要监听的网络接口。指定为 NULL 时将在所有 IPv4 网络接口监听,等同于 <see cref="IPAddress.Any"/>。</param>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                _server = new WebSocketServer(location); | 
					 | 
					 | 
					        /// <returns>已监听的端口号。</returns>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                _server.Start(Initialize); | 
					 | 
					 | 
					        /// <exception cref="ArgumentOutOfRangeException" />
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                _running = true; | 
					 | 
					 | 
					        /// <exception cref="FormatException" />
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                return true; | 
					 | 
					 | 
					        /// <exception cref="InvalidOperationException" />
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            } | 
					 | 
					 | 
					        public void Start(int port, IPAddress address = null) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            catch (Exception exception) | 
					 | 
					 | 
					        { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            { | 
					 | 
					 | 
					            if (address == null) address = IPAddress.Any; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                RaiseExcepted(exception); | 
					 | 
					 | 
					            if (port < 0) throw new ArgumentOutOfRangeException(nameof(port)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                return false; | 
					 | 
					 | 
					            if (port > 65535) throw new ArgumentOutOfRangeException(nameof(port)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            } | 
					 | 
					 | 
					            if (_running) throw new InvalidOperationException("示例已经在运行中,无法再次启动。"); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _address = address; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _port = port; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            var location = "ws://" + _address.ToString() + ":" + port.ToString(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _server = new WebSocketServer(location); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _server.Start(Initialize); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _port = _server.Port; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _running = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        /// <summary>对所有连接发送文本。</summary>
 | 
					 | 
					 | 
					        /// <summary>对所有连接发送文本。</summary>
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |