123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Net;
- using System.Net.Sockets;
- using System.IO;
- using System.Collections;
- namespace SocketSrv
- {
- //控制台输出日志
- //public class Logger
- //{
- // public bool LogEvents { get; set; }
- // public Logger()
- // {
- // LogEvents = true;
- // }
- // public void Log(string Text)
- // {
- // if (LogEvents) Console.WriteLine(Text);
- // }
- //}
- public enum ServerStatusLevel { Off, WaitingConnection, ConnectionEstablished };
- public delegate void NewConnectionEventHandler(Object sender,string loginName,EventArgs e);
- public delegate void DataReceivedEventHandler(Object sender, string message, EventArgs e);
- public delegate void DisconnectedEventHandler(Object sender,EventArgs e);
- public delegate void BroadcastEventHandler(string message, EventArgs e);
- public class WebSocketServer : IDisposable
- {
- private bool AlreadyDisposed;
- private Socket Listener;
- private int ConnectionsQueueLength;
- private int MaxBufferSize;
- private string Handshake;
- private StreamReader ConnectionReader;
- private StreamWriter ConnectionWriter;
- // private Logger logger;
- private byte[] FirstByte;
- private byte[] LastByte;
- private byte[] ServerKey1;
- private byte[] ServerKey2;
- private Hashtable onlineList;
- List<SocketConnection> connectionSocketList = new List<SocketConnection>();
- public ServerStatusLevel Status { get; private set; }
- public int ServerPort { get; set; }
- public string ServerLocation { get; set; }
- public string ConnectionOrigin { get; set; }
- //public bool LogEvents {
- // get { return logger.LogEvents; }
- // set { logger.LogEvents = value; }
- //}
- public event NewConnectionEventHandler NewConnection;
- public event DataReceivedEventHandler DataReceived;
- public event DisconnectedEventHandler Disconnected;
- private void Initialize()
- {
- AlreadyDisposed = false;
- // logger = new Logger();
- Status = ServerStatusLevel.Off;
- ConnectionsQueueLength = 500;
- MaxBufferSize = 1024 * 100;
- FirstByte = new byte[MaxBufferSize];
- LastByte = new byte[MaxBufferSize];
- FirstByte[0] = 0x00;
- LastByte[0] = 0xFF;
- // logger.LogEvents = true;
- onlineList=new Hashtable();
- }
- //构造函数 .默认设置
- public WebSocketServer()
- {
- ServerPort = 4141;
- ServerLocation = string.Format("ws://{0}:4141/chat", "192.168.0.102");
- Initialize();
- }
- //构造函数 . 用户设置
- public WebSocketServer(int serverPort, string serverLocation, string connectionOrigin)
- {
- ServerPort = serverPort;
- ConnectionOrigin = connectionOrigin;
- ServerLocation = serverLocation;
- Initialize();
- }
- ~WebSocketServer()
- {
- Close();
- }
- public void Dispose()
- {
- Close();
- }
- //服务关闭
- private void Close()
- {
- if (!AlreadyDisposed)
- {
- AlreadyDisposed = true;
- if (Listener != null) Listener.Close();
- foreach (SocketConnection item in connectionSocketList)
- {
- item.ConnectionSocket.Close();
- }
- connectionSocketList.Clear();
- GC.SuppressFinalize(this);
- }
- }
- //获取本机IP
- //public static IPAddress getLocalmachineIPAddress()
- //{
- // string strHostName = Dns.GetHostName();
- // IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
- // foreach (IPAddress ip in ipEntry.AddressList)
- // {
- // //IPV4
- // if (ip.AddressFamily == AddressFamily.InterNetwork)
- // return ip;
- // }
- // return ipEntry.AddressList[0];
- //}
- //服务器开始运行 监听
- public void StartServer()
- {
- Char char1 = Convert.ToChar(65533);
- Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
- Listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.102"), ServerPort));
-
- Listener.Listen(ConnectionsQueueLength);
- //logger.Log(string.Format("聊天服务器启动。监听地址:{0}, 端口:{1}",getLocalmachineIPAddress(),ServerPort));
- //logger.Log(string.Format("WebSocket服务器地址: ws://{0}:{1}/chat", getLocalmachineIPAddress(), ServerPort));
- //等待客户端连接
- while (true)
- {
- Socket sc = Listener.Accept();
- if (sc != null)
- {
- System.Threading.Thread.Sleep(100);
- SocketConnection socketConn = new SocketConnection();
- socketConn.ConnectionSocket = sc;
- socketConn.NewConnection += new NewConnectionEventHandler(socketConn_NewConnection);
- socketConn.DataReceived += new DataReceivedEventHandler(socketConn_BroadcastMessage);
- socketConn.Disconnected += new DisconnectedEventHandler(socketConn_Disconnected);
- socketConn.ConnectionSocket.BeginReceive(socketConn.receivedDataBuffer,
- 0, socketConn.receivedDataBuffer.Length,
- 0, new AsyncCallback(socketConn.ManageHandshake),
- socketConn.ConnectionSocket.Available);
- //保存每一个连接的客户端
- connectionSocketList.Add(socketConn);
- }
- }
- }
- //客户端断开连接
- void socketConn_Disconnected(Object sender, EventArgs e)
- {
- SocketConnection sConn = sender as SocketConnection;
- if (sConn != null)
- {
- //重新发送在线用户列表
- onlineList.Remove(sConn.Id);
- Send("onLineList:" + GetOnlineName());
-
- //关闭和移除该客户端
- sConn.ConnectionSocket.Close();
- connectionSocketList.Remove(sConn);
- }
- }
- //客户端消息传递
- void socketConn_BroadcastMessage(Object sender, string message, EventArgs e)
- {
- //服务器中转信息
- SendChat(message);
- }
- //新的用户连接
- void socketConn_NewConnection(Object sender,string message, EventArgs e)
- {
- SocketConnection sConn = sender as SocketConnection;
- string idName = message.Replace( "login:","");
- sConn.Id = idName.Split(',')[0];
- sConn.Name = idName.Split(',')[1];
- if (!onlineList.ContainsKey(sConn.Id))
- {
- //保存到在线列表
- onlineList[sConn.Id] = sConn;
- }
- //发送在线列表
- Send("onLineList:" + GetOnlineName());
- }
- //获取在线列表的用户名和ID 格式为 id|name,id|name,id|name
- private string GetOnlineName()
- {
- string names = string.Empty;
- foreach (SocketConnection sc in onlineList.Values)
- {
- names += sc.Id+"|"+ sc.Name + ",";
- }
- return names.TrimEnd(',');
- }
- //服务器群发消息
- public void Send(string message)
- {
- foreach (SocketConnection item in connectionSocketList)
- {
- if (!item.ConnectionSocket.Connected) return;
- try
- {
- if (item.IsDataMasked)
- {
- DataFrame dr = new DataFrame(message);
- item.ConnectionSocket.Send(dr.GetBytes());
- }
- else
- {
- item.ConnectionSocket.Send(FirstByte);
- item.ConnectionSocket.Send(Encoding.UTF8.GetBytes(message));
- item.ConnectionSocket.Send(LastByte);
- }
- }
- catch(Exception ex)
- {
- //logger.Log(ex.Message);
- }
- }
- }
- //服务器转发消息
- public void SendChat(string message)
- {
- string[] info = message.Split('|');
- foreach (SocketConnection item in onlineList.Values)
- {
- if (!item.ConnectionSocket.Connected) continue;
- if (item.Id != info[0])continue;
- //找到需要转发的对象
- string newMsg = info[1] + "|" + info[2];
- try
- {
- if (item.IsDataMasked)
- {
- DataFrame dr = new DataFrame(newMsg);
- item.ConnectionSocket.Send(dr.GetBytes());
- }
- else
- {
- item.ConnectionSocket.Send(FirstByte);
- item.ConnectionSocket.Send(Encoding.UTF8.GetBytes(newMsg));
- item.ConnectionSocket.Send(LastByte);
- }
- }
- catch (Exception ex)
- {
- //logger.Log(ex.Message);
- }
- }
- }
- }
- }
|