在園子里潛水幾年了,工作以來算是有些積累,突然想寫點東西方便以后溫故而知新,希望自己能夠堅持下去。
關於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>
服務端代碼:

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); } }
最后效果圖如下:
在局域網測試50000連接可以正常使用,外網暫時還未測試。