WebSocketsServer.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.IO;
  7. using System.Collections;
  8. namespace SocketSrv
  9. {
  10. //控制台输出日志
  11. //public class Logger
  12. //{
  13. // public bool LogEvents { get; set; }
  14. // public Logger()
  15. // {
  16. // LogEvents = true;
  17. // }
  18. // public void Log(string Text)
  19. // {
  20. // if (LogEvents) Console.WriteLine(Text);
  21. // }
  22. //}
  23. public enum ServerStatusLevel { Off, WaitingConnection, ConnectionEstablished };
  24. public delegate void NewConnectionEventHandler(Object sender,string loginName,EventArgs e);
  25. public delegate void DataReceivedEventHandler(Object sender, string message, EventArgs e);
  26. public delegate void DisconnectedEventHandler(Object sender,EventArgs e);
  27. public delegate void BroadcastEventHandler(string message, EventArgs e);
  28. public class WebSocketServer : IDisposable
  29. {
  30. private bool AlreadyDisposed;
  31. private Socket Listener;
  32. private int ConnectionsQueueLength;
  33. private int MaxBufferSize;
  34. private string Handshake;
  35. private StreamReader ConnectionReader;
  36. private StreamWriter ConnectionWriter;
  37. // private Logger logger;
  38. private byte[] FirstByte;
  39. private byte[] LastByte;
  40. private byte[] ServerKey1;
  41. private byte[] ServerKey2;
  42. private Hashtable onlineList;
  43. List<SocketConnection> connectionSocketList = new List<SocketConnection>();
  44. public ServerStatusLevel Status { get; private set; }
  45. public int ServerPort { get; set; }
  46. public string ServerLocation { get; set; }
  47. public string ConnectionOrigin { get; set; }
  48. //public bool LogEvents {
  49. // get { return logger.LogEvents; }
  50. // set { logger.LogEvents = value; }
  51. //}
  52. public event NewConnectionEventHandler NewConnection;
  53. public event DataReceivedEventHandler DataReceived;
  54. public event DisconnectedEventHandler Disconnected;
  55. private void Initialize()
  56. {
  57. AlreadyDisposed = false;
  58. // logger = new Logger();
  59. Status = ServerStatusLevel.Off;
  60. ConnectionsQueueLength = 500;
  61. MaxBufferSize = 1024 * 100;
  62. FirstByte = new byte[MaxBufferSize];
  63. LastByte = new byte[MaxBufferSize];
  64. FirstByte[0] = 0x00;
  65. LastByte[0] = 0xFF;
  66. // logger.LogEvents = true;
  67. onlineList=new Hashtable();
  68. }
  69. //构造函数 .默认设置
  70. public WebSocketServer()
  71. {
  72. ServerPort = 4141;
  73. ServerLocation = string.Format("ws://{0}:4141/chat", "192.168.0.102");
  74. Initialize();
  75. }
  76. //构造函数 . 用户设置
  77. public WebSocketServer(int serverPort, string serverLocation, string connectionOrigin)
  78. {
  79. ServerPort = serverPort;
  80. ConnectionOrigin = connectionOrigin;
  81. ServerLocation = serverLocation;
  82. Initialize();
  83. }
  84. ~WebSocketServer()
  85. {
  86. Close();
  87. }
  88. public void Dispose()
  89. {
  90. Close();
  91. }
  92. //服务关闭
  93. private void Close()
  94. {
  95. if (!AlreadyDisposed)
  96. {
  97. AlreadyDisposed = true;
  98. if (Listener != null) Listener.Close();
  99. foreach (SocketConnection item in connectionSocketList)
  100. {
  101. item.ConnectionSocket.Close();
  102. }
  103. connectionSocketList.Clear();
  104. GC.SuppressFinalize(this);
  105. }
  106. }
  107. //获取本机IP
  108. //public static IPAddress getLocalmachineIPAddress()
  109. //{
  110. // string strHostName = Dns.GetHostName();
  111. // IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
  112. // foreach (IPAddress ip in ipEntry.AddressList)
  113. // {
  114. // //IPV4
  115. // if (ip.AddressFamily == AddressFamily.InterNetwork)
  116. // return ip;
  117. // }
  118. // return ipEntry.AddressList[0];
  119. //}
  120. //服务器开始运行 监听
  121. public void StartServer()
  122. {
  123. Char char1 = Convert.ToChar(65533);
  124. Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
  125. Listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.102"), ServerPort));
  126. Listener.Listen(ConnectionsQueueLength);
  127. //logger.Log(string.Format("聊天服务器启动。监听地址:{0}, 端口:{1}",getLocalmachineIPAddress(),ServerPort));
  128. //logger.Log(string.Format("WebSocket服务器地址: ws://{0}:{1}/chat", getLocalmachineIPAddress(), ServerPort));
  129. //等待客户端连接
  130. while (true)
  131. {
  132. Socket sc = Listener.Accept();
  133. if (sc != null)
  134. {
  135. System.Threading.Thread.Sleep(100);
  136. SocketConnection socketConn = new SocketConnection();
  137. socketConn.ConnectionSocket = sc;
  138. socketConn.NewConnection += new NewConnectionEventHandler(socketConn_NewConnection);
  139. socketConn.DataReceived += new DataReceivedEventHandler(socketConn_BroadcastMessage);
  140. socketConn.Disconnected += new DisconnectedEventHandler(socketConn_Disconnected);
  141. socketConn.ConnectionSocket.BeginReceive(socketConn.receivedDataBuffer,
  142. 0, socketConn.receivedDataBuffer.Length,
  143. 0, new AsyncCallback(socketConn.ManageHandshake),
  144. socketConn.ConnectionSocket.Available);
  145. //保存每一个连接的客户端
  146. connectionSocketList.Add(socketConn);
  147. }
  148. }
  149. }
  150. //客户端断开连接
  151. void socketConn_Disconnected(Object sender, EventArgs e)
  152. {
  153. SocketConnection sConn = sender as SocketConnection;
  154. if (sConn != null)
  155. {
  156. //重新发送在线用户列表
  157. onlineList.Remove(sConn.Id);
  158. Send("onLineList:" + GetOnlineName());
  159. //关闭和移除该客户端
  160. sConn.ConnectionSocket.Close();
  161. connectionSocketList.Remove(sConn);
  162. }
  163. }
  164. //客户端消息传递
  165. void socketConn_BroadcastMessage(Object sender, string message, EventArgs e)
  166. {
  167. //服务器中转信息
  168. SendChat(message);
  169. }
  170. //新的用户连接
  171. void socketConn_NewConnection(Object sender,string message, EventArgs e)
  172. {
  173. SocketConnection sConn = sender as SocketConnection;
  174. string idName = message.Replace( "login:","");
  175. sConn.Id = idName.Split(',')[0];
  176. sConn.Name = idName.Split(',')[1];
  177. if (!onlineList.ContainsKey(sConn.Id))
  178. {
  179. //保存到在线列表
  180. onlineList[sConn.Id] = sConn;
  181. }
  182. //发送在线列表
  183. Send("onLineList:" + GetOnlineName());
  184. }
  185. //获取在线列表的用户名和ID 格式为 id|name,id|name,id|name
  186. private string GetOnlineName()
  187. {
  188. string names = string.Empty;
  189. foreach (SocketConnection sc in onlineList.Values)
  190. {
  191. names += sc.Id+"|"+ sc.Name + ",";
  192. }
  193. return names.TrimEnd(',');
  194. }
  195. //服务器群发消息
  196. public void Send(string message)
  197. {
  198. foreach (SocketConnection item in connectionSocketList)
  199. {
  200. if (!item.ConnectionSocket.Connected) return;
  201. try
  202. {
  203. if (item.IsDataMasked)
  204. {
  205. DataFrame dr = new DataFrame(message);
  206. item.ConnectionSocket.Send(dr.GetBytes());
  207. }
  208. else
  209. {
  210. item.ConnectionSocket.Send(FirstByte);
  211. item.ConnectionSocket.Send(Encoding.UTF8.GetBytes(message));
  212. item.ConnectionSocket.Send(LastByte);
  213. }
  214. }
  215. catch(Exception ex)
  216. {
  217. //logger.Log(ex.Message);
  218. }
  219. }
  220. }
  221. //服务器转发消息
  222. public void SendChat(string message)
  223. {
  224. string[] info = message.Split('|');
  225. foreach (SocketConnection item in onlineList.Values)
  226. {
  227. if (!item.ConnectionSocket.Connected) continue;
  228. if (item.Id != info[0])continue;
  229. //找到需要转发的对象
  230. string newMsg = info[1] + "|" + info[2];
  231. try
  232. {
  233. if (item.IsDataMasked)
  234. {
  235. DataFrame dr = new DataFrame(newMsg);
  236. item.ConnectionSocket.Send(dr.GetBytes());
  237. }
  238. else
  239. {
  240. item.ConnectionSocket.Send(FirstByte);
  241. item.ConnectionSocket.Send(Encoding.UTF8.GetBytes(newMsg));
  242. item.ConnectionSocket.Send(LastByte);
  243. }
  244. }
  245. catch (Exception ex)
  246. {
  247. //logger.Log(ex.Message);
  248. }
  249. }
  250. }
  251. }
  252. }