亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#制作簡單的多人在線即時交流聊天室

2020-01-24 01:22:34
字體:
來源:轉載
供稿:網友

實現網頁版的在線聊天室的方法有很多,在沒有來到HTML5之前,常見的有:定時輪詢、長連接+長輪詢、基于第三方插件(如FLASH的Socket),而如果是HTML5,則比較簡單,可以直接使用WebSocket,當然HTML5目前在PC端并沒有被所有瀏覽器支持,所以我的這個聊天室仍是基于長連接+長輪詢+原生的JS及AJAX實現的多人在線即時交流聊天室,這個聊天室其實是我上周周末完成的,功能簡單,可能有些不足,但可以滿足在線即時聊天需求,分享也是給大家提供一個思路,大家可以基于此來實現更好的在線即時聊天工具。

聊天室功能簡介:

1。支持多人進入同一個聊天室聊天;

2。進入即離線均會自動生成通知信息顯示在聊天室中,這樣聊天的人們就知道誰進來了誰離開了;

3。實時顯示在線人員表列;

4。無需數據庫支持,全部存在內存中,當然有條件的可以采用分布式緩存或加一個數據庫來存,這里演示就是用內存來存了。

下面就開始分享我的代碼,由于采用原生的JS及AJAX,所以簡單易懂,代碼分別WEB前端及服務端(有點廢話了)

WEB前端源代碼如下:(ChatPage.html)

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title></title>  <style type="text/css">    html, body {      margin: 0px;      padding: 0px;      width: 100%;      height: 100%;      background-color: #f8f7f7;      font-family: arial,sans-serif;    }     #layouttable {      margin:0px;      padding:0px;      width:100%;      height:100%;      border:2px solid green;      border-collapse:collapse;      min-width:800px;    }       #layouttable td {        border: 1px solid green;      }     .h100p {      height:100%;    }     .midtr{height:auto;}      .midtr tr td {        height: 100%;      }     #chatmsgbox, #chatonlinebox {      background-color:white;      overflow-x: hidden;      overflow-y: auto;      overflow-wrap: break-word;      height: 100%;    }     #chatonlinebox {      background-color:#f5d0a8;    }     .rc, .sd {      overflow:hidden;    }      .rc p {      float: left;      color: green;    }      .sd p {        float: right;        color: orange;      }  </style> </head><body>  <table id="layouttable">    <colgroup>      <col style="width:auto" />      <col style="width: 200px;" />    </colgroup>    <tr style="height:30px; background-color:lightblue;color:yellow;">      <td>        歡迎進入夢在旅途的網頁即時在線大眾聊天室 - www.zuowenjun.cn:      </td>      <td>        當前在線人員      </td>    </tr>    <tr style="height:auto;" id="midtr">      <td>        <div id="chatmsgbox">        </div>      </td>      <td>        <div id="chatonlinebox">          <ul id="chatnames"></ul>        </div>      </td>    </tr>    <tr style="height:50px;">      <td colspan="2">        <label for="name">聊天妮稱:</label>        <input type="text" id="name" style="width:80px;" />        <input type="button" id="btnsavename" value="確認進入" />        <label for="msg">輸入內容:</label>        <input type="text" id="msg" style="width:400px;" />        <input type="button" id="btnSend" value="發送消息" disabled="disabled" />      </td>    </tr>  </table>  <script type="text/javascript">    var chatName = null;    var oChatmsgbox, oMsg, oChatnames;    var ajaxforSend, ajaxforRecv;     //頁面加載初始化    window.onload = function () {      document.getElementById("btnsavename").onclick = function () {        this.disabled = true;        var oName = document.getElementById("name");        oName.readOnly = true;        document.getElementById("btnSend").disabled = false;        //receiveMsg();        setChatStatus(oName.value,"on");      }       document.getElementById("btnSend").onclick = function () {        sendMsg(oMsg.value);      };       //init      oChatmsgbox = document.getElementById("chatmsgbox");      oMsg = document.getElementById("msg");      oChatnames = document.getElementById("chatnames");      ajaxforSend = getAjaxObject();      ajaxforRecv = getAjaxObject();    }     //離開時提醒    window.onbeforeunload = function () {      event.returnValue = "您確定要退出聊天室嗎?";    }     //關閉時離線    window.onunload = function () {      setChatStatus(chatName, "off");    }     //設置聊天狀態:在線 OR 離線    function setChatStatus(name, status) {      callAjax(getAjaxObject(), "action=" + status + "&name=" + name, function (rs) {        if (!rs.success) {          alert(rs.info);          return;        }        if (status == "on") {          chatName = document.getElementById("name").value;          setTimeout("receiveMsg()",500);        }        loadOnlineChatNames();      });    }     //加載在線人員名稱列表    function loadOnlineChatNames(){      callAjax(getAjaxObject(), "action=onlines", function (rs) {        var lis = "";        for(var i=0;i<rs.length;i++)        {          lis += "<li>"+ rs[i] +"</li>";        }        oChatnames.innerHTML = lis;      });    }     //接收消息列表    function receiveMsg() {      callAjax(ajaxforRecv, "action=receive&name=" + chatName, function (rs) {        if (rs.success) {          showChatMsgs(rs.msgs, "rc");        }        setTimeout("receiveMsg()", 500);      });    }    //發送消息    function sendMsg(msg) {      callAjax(ajaxforSend, "action=send&name=" + chatName + "&msg=" + escape(msg), function (rs) {        if (rs.success) {          showChatMsgs(rs.msgs, "sd");          oMsg.value = null;          //alert("發送成功!");        }      });    }     //顯示消息    function showChatMsgs(msgs, cssClass) {      var loadonline = false;      for (var i = 0; i < msgs.length; i++) {        var msg = msgs[i];        oChatmsgbox.innerHTML += "<div class='" + cssClass + "'><p>[" + msg.name + "] - " + msg.sendtime + " 說:<br/>" + msg.content + "</p></div>";        if (msg.type == "on" || msg.type == "off")        {          loadonline = true;        }      }      if (loadonline)      {        loadOnlineChatNames();      }    }     //調用AJAX    function callAjax(ajax, param, callback) {       ajax.open("post", "ChatHandler.ashx", true);      ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");      ajax.onreadystatechange = function () {        if (ajax.readyState == 4 && ajax.status == 200) {          var json = eval("(" + ajax.responseText + ")");          callback(json);        }      };      ajax.send(param);    }     //獲取AJAX對象(XMLHttpRequest)    function getAjaxObject() {      var xmlhttp;      if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari        xmlhttp = new XMLHttpRequest();      }      else {// code for IE6, IE5        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");      }      return xmlhttp;    }   </script></body></html>

代碼很簡單,并都有注釋,在此就不作說明了,如果有疑問歡迎在下方評論。

服務端(ChatHandler.ashx) 

<%@ WebHandler Language="C#" Class="ChatHandler" %> using System;using System.Web;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Web.Script.Serialization;using System.Threading;using System.Collections.Concurrent; public class ChatHandler : IHttpHandler{   private class Msg  {    public string name { get; set; }    public string sendtime { get; set; }    public string content { get; set; }    public string readednams { get; set; }    public int readedCount { get; set; }    public string type { get; set; }  }   private static List<Msg> msgs = new List<Msg>();  private static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();  private static object syncObject = new object(),syncObject1 = new object();  private static List<string> onLineNames = new List<string>();   public void ProcessRequest(HttpContext context)  {    string chatName = context.Request.Form["name"];    string msg = context.Request.Form["msg"];    string actionName = context.Request.Form["action"];    JavaScriptSerializer jsSerializer = new JavaScriptSerializer();     object responseObject = null;     switch (actionName)    {      case "receive":        {          responseObject = GetNewMessages(chatName);          break;        }      case "send":        {          responseObject = SendMessage(chatName, msg, "normal");          break;        }      case "on":      case "off":        {          responseObject = SetChatStatus(chatName, actionName);          break;        }      case "onlines":        {          responseObject = onLineNames;          break;        }    }     context.Response.ContentType = "text/json";    context.Response.Write(jsSerializer.Serialize(responseObject));   }   private object SetChatStatus(string chatName, string status)  {    if (status == "on")    {      if (onLineNames.Exists(s => s == chatName))      {        return new { success = false, info = "該聊天妮稱已經存在,請更換一個名稱吧!" };      }      lock (syncObject1)      {        onLineNames.Add(chatName);      }      SendMessage(chatName, "大家好,我進入聊天室了!", status);      return new { success = true, info = string.Empty };    }    else    {      lock (syncObject1)      {        onLineNames.Remove(chatName);      }      SendMessage(chatName, "再見,我離開聊天室了!", status);      return new { success = true, info = string.Empty };    }  }   /// <summary>  /// 獲取未讀的新消息  /// </summary>  /// <param name="chatName"></param>  /// <returns></returns>  private object GetNewMessages(string chatName)  {    //第一種:循環處理    while (true)    {       var newMsgs = msgs.Where(m => m.name != chatName && !(m.readednams ?? "").Contains(chatName)).OrderBy(m => m.sendtime).ToList();      if (newMsgs != null && newMsgs.Count() > 0)      {        lock (syncObject)        {          newMsgs.ForEach((m) =>          {            m.readednams += chatName + ",";            m.readedCount++;          });          int chatNameCount = onLineNames.Count();          msgs.RemoveAll(m => m.readedCount >= chatNameCount);        }         return new { success = true, msgs = newMsgs };      }       Thread.Sleep(1000);    }      //第二種方法,采用自旋鎖    //List<Msg> newMsgs = null;    //SpinWait.SpinUntil(() =>    //{    //  newMsgs = msgs.Where(m => m.name != chatName && !(m.readednams ?? "").Contains(chatName)).OrderBy(m => m.sendtime).ToList();    //  return newMsgs.Count() > 0;    //}, -1);     //rwLock.EnterWriteLock();    //newMsgs.ForEach(m =>    //{    //  m.readednams += chatName + ",";    //  m.readedCount++;    //});    //rwLock.ExitWriteLock();    //return new { success = true, msgs = newMsgs };  }   /// <summary>  ///  /// </summary>  /// <param name="chatName"></param>  /// <param name="msg"></param>  /// <returns></returns>  private object SendMessage(string chatName, string msg, string type)  {    var newMsg = new Msg() { name = chatName, sendtime = DateTime.Now.ToString("yyyy/MM/dd HH:mm"), content =HttpContext.Current.Server.HtmlEncode(msg), readednams = null, type = type };    //rwLock.EnterWriteLock();    lock (syncObject)    {      msgs.Add(newMsg);    }    //rwLock.ExitWriteLock();    return new { success = true, msgs = new[] { newMsg } };  }     public bool IsReusable  {    get    {      return false;    }  } }

代碼也相對簡單,實現原理主要是:

1。聊天消息:循環獲取未讀的消息,在取出讀的消息同時,將其標識為已讀,全部已讀的消息則刪除;--我這里采用了兩種方法,第二種方法被注釋掉了,大家可以取消注釋試試,也是不錯的,比第一種更直觀,建議使用;

2。發送消息:實例化一個消息實例并加入到聊天消息集合中;

3。狀態切換:上線則加入到在線人員集合中,并生成一條上線消息放入到聊天消息集合中,離線則從在線人員集合中移除該人員信息,并生成一條離線消息放入聊天消息集合中;

注意事項,由于采用了全局靜態集合,所以線程同步比較重要。

最終的實現效果展示如下:

 張三:

李四:

小美:

如果覺得不錯的話,給個推薦吧,你的支持是推動我不斷前進的動力及寫作的源泉,我一直堅持:知識在于分享,分享的同時自己也在成長,希望與大家共同成長,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成+人+综合+亚洲欧洲| 国产日韩av在线播放| 国产精品jvid在线观看蜜臀| 欧美亚洲国产视频小说| 亚洲欧美在线第一页| 久久99亚洲热视| 亚洲一区二区自拍| 国产午夜精品美女视频明星a级| 91免费视频国产| 国产视频久久久久| 欧美日韩精品在线| 91av中文字幕| 第一福利永久视频精品| 日韩欧美精品免费在线| 永久免费精品影视网站| 欧美在线免费看| 国产有码在线一区二区视频| 日韩精品在线视频观看| 91久久久久久久久久久久久| 久久亚洲欧美日韩精品专区| 欧美日韩一区二区在线| 中文字幕综合在线| 色香阁99久久精品久久久| 精品成人国产在线观看男人呻吟| 午夜精品免费视频| 性色av一区二区三区| 日本精品久久久久影院| 在线中文字幕日韩| 国内精品一区二区三区| 成人av.网址在线网站| 亚洲综合国产精品| www日韩欧美| 最近中文字幕2019免费| 91亚洲永久免费精品| 最好看的2019的中文字幕视频| 亚洲精品wwwww| 亚洲精品电影久久久| 国产精品黄页免费高清在线观看| 欧美亚洲日本网站| 激情成人中文字幕| 久久不射电影网| 国产精品免费小视频| 国产一区二区三区在线观看网站| 国产视频欧美视频| 久久免费视频观看| 中文字幕亚洲激情| 久久成人精品电影| 亚洲欧美国产一区二区三区| 国内精品久久久久久影视8| 国产97在线播放| 欧美午夜精品久久久久久浪潮| 91人成网站www| 欧美国产日韩一区二区| 欧美性高潮床叫视频| 欧美性猛交xxxxx免费看| 97精品国产97久久久久久免费| 奇门遁甲1982国语版免费观看高清| 国模吧一区二区| 欧美午夜性色大片在线观看| 久久精品亚洲94久久精品| 欧美日韩国产一区在线| 国产日韩欧美黄色| 欧美性生活大片免费观看网址| 久久国产精品偷| 日韩在线观看免费全集电视剧网站| 国产欧美在线视频| 国产国语刺激对白av不卡| 午夜精品99久久免费| 中文字幕九色91在线| 日韩欧美高清视频| 国产成人鲁鲁免费视频a| 国产精品极品美女粉嫩高清在线| 亚洲电影免费观看高清| 欧美精品久久久久久久| 国产成人av在线| 91色在线观看| 欧美洲成人男女午夜视频| 深夜成人在线观看| 免费成人高清视频| 欧美成人午夜免费视在线看片| 国产视频精品在线| 国产精品88a∨| 欧美国产一区二区三区| 色婷婷综合成人av| 久久91精品国产| 精品国产91久久久久久老师| 91亚洲国产成人久久精品网站| 国产丝袜一区二区三区| 不卡av在线网站| 91国内在线视频| 亚洲精品v天堂中文字幕| 69久久夜色精品国产7777| 欧美激情在线有限公司| 国产一区二区激情| 精品福利免费观看| 久久久精品电影| 欧美一级视频在线观看| 欧美亚洲国产视频| 久久久天堂国产精品女人| 亚洲成年人在线播放| 国产主播精品在线| 国产精品99久久99久久久二8| 日韩av手机在线| 日韩精品免费在线视频| 成人国产精品色哟哟| 一区二区三区日韩在线| 亚洲成人av在线播放| 亚洲国产成人久久综合| 77777亚洲午夜久久多人| 成人黄色在线免费| 亚洲一级黄色av| 国产在线视频2019最新视频| 国产精品免费久久久久久| 欧美日韩中文字幕在线视频| 欧美最顶级丰满的aⅴ艳星| 国产精品中文久久久久久久| 亚洲欧美国产日韩中文字幕| 亚洲精品女av网站| 97激碰免费视频| 91av在线视频观看| 国产91在线播放九色快色| 午夜精品久久久久久久久久久久| 欧美在线精品免播放器视频| 91av视频导航| 91精品国产91久久久| 日韩中文字幕在线视频播放| 亚洲欧美日韩精品久久奇米色影视| 热99精品只有里视频精品| 日韩在线高清视频| 最新国产精品亚洲| 青青久久av北条麻妃黑人| 国产日本欧美在线观看| 国产精品亚洲一区二区三区| 亚洲国产高清自拍| 国产成人一区二| 国产一区二区久久精品| 久热在线中文字幕色999舞| 91精品国产高清久久久久久久久| 亚洲春色另类小说| 亚洲视频在线播放| 一区二区三区四区精品| 亚洲网址你懂得| 欧洲永久精品大片ww免费漫画| 国产ts一区二区| 欧美日韩第一视频| 欧美日韩一区二区在线播放| 在线观看中文字幕亚洲| 91久久在线播放| 久久久久久999| 成人免费在线视频网址| 中文字幕一区电影| 亚洲伊人久久大香线蕉av| 97免费视频在线播放| 欧美国产视频一区二区| 欧美日韩中文字幕日韩欧美| 国产一区二区三区视频免费| 精品国偷自产在线视频| 91免费精品视频| 最近2019年日本中文免费字幕| 中文字幕一区日韩电影| 成人中心免费视频| 日韩中文理论片| 欧美黑人一区二区三区| 国产精品吹潮在线观看|