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