Superwebsocket 模擬微信聊天室


在園子里潛水幾年了,工作以來算是有些積累,突然想寫點東西方便以后溫故而知新,希望自己能夠堅持下去。

關於Superwebsocket的介紹我就不多說了,請點擊:http://www.cnblogs.com/shanyou/archive/2012/07/21/2602269.html
說下Superwebsocket幾個常用的偵聽事件:
NewSessionConnected:有新會話握手並連接成功時觸發
SessionClosed:有會話被關閉 可能是服務端關閉 也可能是客戶端關閉時觸發
ws_NewMessageReceived:有客戶端發送新的消息時觸發

客戶端的實現代碼:

<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script type="text/javascript">
            var url = "ws://192.168.1.114:75";//連接到服務器IP和端口
            var ws = null;
          function onLogin() {
  var name = document.getElementById('txt_name');
 var content = document.getElementsByTagName('ul')[0];
if(name.value == '') {
                    alert("請先輸入用戶名");
                    return;
                }
 var name1= document.getElementById('txt_name').value + "/" + returnCitySN["cip"] + "/" + returnCitySN["cname"];
                var fullUrl = url + "/" + name1;


 if ("WebSocket" in window) {
                    ws = new WebSocket(fullUrl);
                }
                else if ("MozWebSocket" in window) {
                    ws = new MozWebSocket(fullUrl);
                } else {
                    content.innerHTML += '<li style="text-align: center;"><span>瀏覽器不支持WebSocket</span></li>';
                }

                ws.onopen = function () {
                    content.innerHTML += '<li style="text-align: center;"><span>連接服務器成功</span></li>';
                    changeElementEnabled(true); 
                }
                ws.onclose = function () {
                    content.innerHTML += '<li style="text-align: center;"><span>與服務器斷開連接</span></li>';
                    changeElementEnabled(false); 
                }

                ws.onerror = function () {
                    content.innerHTML += '<li style="text-align: center;"><span>通信發生錯誤</span></li>';
                }

                ws.onmessage = function (msg) {
                    if (num == 0) {
                        content.innerHTML += '<li><img src="Img/mz1.png" class="imgright"/><span class="spanright">' + 

msg.data + '</span></li>';
                    } else {
                        content.innerHTML += '<li><img src="Img/mz2.png" class="imgleft"/><span class="spanleft">' + 

msg.data + '</span></li>';
                    }
                    num = 0;
                }

            }

         var num = 0;
            function sendMessage() { //發送消息
                //alert("send");
                num = 1;
                var msg = document.getElementById("text").value;
                if (ws) {
                    ws.send(msg);
                }
         //content.scrollTop = content.scrollHeight;這一句不知道為什么不能讓滾動條保持最下面,知道的請告知一下
            }
  </script>
View Code

服務端代碼:

private const string ip = "192.168.1.114";
        private const int port = 75;
        private WebSocketServer ws = null;//SuperWebSocket中的WebSocketServer對象
        private Dictionary<string, WebSocketSession> dicSession = new Dictionary<string, WebSocketSession>();
        delegate void SetTextCallBack(string text);
        public string msg = "";

        public Server()
        {
            InitializeComponent();

            ws = new WebSocketServer();//實例化WebSocketServer

            //添加事件偵聽
            ws.NewSessionConnected += ws_NewSessionConnected;//有新會話握手並連接成功
            ws.SessionClosed += ws_SessionClosed;//有會話被關閉 可能是服務端關閉 也可能是客戶端關閉
            ws.NewMessageReceived += ws_NewMessageReceived;//有客戶端發送新的消息
        }
    
void ws_NewSessionConnected(WebSocketSession session)
        {
            msg = Environment.NewLine + DateTime.Now + " " + GetSessionName(session).Split('/')[0]+"登錄到服務器";
            SendToAll(session, msg);

            if (!dicSession.ContainsKey(GetSessionName(session)))
            {
                dicSession.Add(GetSessionName(session).Split('/')[0], session);
            }
            LoadData();
        }

        void ws_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
        {
            msg = Environment.NewLine + string.Format("{0:HH:MM:ss} {1} 離開聊天室", DateTime.Now, GetSessionName

(session).Split('/')[0]);
            SendToAll(session, msg);

            if (dicSession.ContainsKey(GetSessionName(session)))
            {
                dicSession.Remove(GetSessionName(session).Split('/')[0]);
            }
            LoadData();
        }
        void ws_NewMessageReceived(WebSocketSession session, string value)
        {
            var msg = string.Format("{0:HH:MM:ss} {1}說: {2}", DateTime.Now, GetSessionName(session).Split('/')[0], 

value);

            SendToAll(session, msg);

        }

public void Start()
        {
            if (!ws.Setup(ip, port))
            {
                textBox1.Text += "ChatWebSocket 設置WebSocket服務偵聽地址失敗" + "\n";
                return;
            }

            if (!ws.Start())
            {
                textBox1.Text += "ChatWebSocket 啟動WebSocket服務偵聽失敗" + "\n";
                return;
            }
            textBox1.Text += "ChatWebSocket 啟動服務成功" + "\n";
        }

        /// <summary>
        /// 停止偵聽服務
        /// </summary>
        public void Stop()
        {

            if (ws != null)
            {
                ws.Stop();
            }
        }

private string GetSessionName(WebSocketSession session)
        {
            //這里用Path來取Name 不太科學…… 
            return HttpUtility.UrlDecode(session.Path.TrimStart('/'));
        }
        private void SendToAll(WebSocketSession session, string msg)
        {
            //廣播
            foreach (var sendSession in session.AppServer.GetAllSessions())
            {
                sendSession.Send(msg);
            }
        }

    //發送數據
     private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView1.CurrentRow == null) return;
                var name = dataGridView1.CurrentRow.Cells["用戶"].Value.ToString();
                if (dicSession.ContainsKey(name))
                {
                    dicSession[name].Send("管理員對你說:" + textBox2.Text);
                    LoadData();
                }
                MessageBox.Show("發送成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           
        }

    //斷開某個客戶機
    private void btnClose_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView1.CurrentRow == null) return;
                var name = dataGridView1.CurrentRow.Cells["用戶"].Value.ToString();
                if (dicSession.ContainsKey(name))
                {
                    dicSession[name].Close(SuperSocket.SocketBase.CloseReason.Unknown);
                    dicSession.Remove(name);
                    LoadData();
                    MessageBox.Show(name + "已經被剔除服務器");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            
        }

    //對所有聊天室用戶進行廣播
    private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView1.CurrentRow == null) return;
                var name = dataGridView1.CurrentRow.Cells["用戶"].Value.ToString();
                if (dicSession.ContainsKey(name))
                {
        #region 這里測試局域網的連接如果發送數量過大可能會導致局域網很卡
            //for (int i = 1; i < 10000; i++)
                    //{
                    //    SendToAll(dicSession[name], "廣播:" +"NO:"+i+ textBox2.Text);
                    //}
        #endregion
                    SendToAll(dicSession[name], "廣播:"+ textBox2.Text);
                }
                MessageBox.Show("廣播成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
View Code

最后效果圖如下:

 

在局域網測試50000連接可以正常使用,外網暫時還未測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM