ASP.NET SingalR不多介紹。讓我介紹不如看官網,我這里就是直接上源代碼,當然代碼還是寫的比較簡單的,考慮的也少,希望各位技友多多提意見。
先簡單介紹聊天室功能:
- 用戶加入聊天室,自動給用戶名和頭像。(可擴展用戶自定義昵稱和頭像,未做)
- 聊天信息發送,群聊。(可擴展1對1聊天,群組聊天,1對多聊天,擴展多種消息格式,未做)
- 本地存儲用戶信息
- 后台結合mongodb存儲聊天信息,用戶下次進入可以看到聊天記錄(MongoDB .NET客戶端的使用,可以用SQL或者緩存存儲,不作為重點闡述)
寫了這么多文字,是不是激不起興趣來,好直接上一張圖,然后搭建基本框架。
ok,我們開始搭建界面。
新建asp.net mvc 項目,然后添加一個SingalR集線器類。(不用手動引用singalR.dll,當然可以從nuget上安裝)
其實hub代碼比較簡單,這里只為了實現簡單聊天室功能,就不多寫其他代碼。因為未完善代碼,所以暫時不公開。較為復雜點的代碼,有興趣的同學可以郵箱留言,我發給你們。
編寫后台代碼之前呢,先分析頁面結構。首先,聊天基本內容包含:聊天內容,用戶昵稱,用戶頭像,用戶發表時間,ok,那么新建一個model吧。

1 public class ZjMessage : MongoBaseModel 2 { 3 public ZjMessage(){ 4 createTime = DateTime.Now.ToString("MM-dd hh:mm:ss"); 5 } 6 public ZjMessage(string connectionId) 7 { 8 this.connectionId = connectionId; 9 } 10 public string connectionId { get; set; } 11 12 /// <summary> 13 /// 頭像 14 /// </summary> 15 public string photo { get; set; } 16 /// <summary> 17 /// 消息內容 18 /// </summary> 19 public string msg { get; set; } 20 /// <summary> 21 /// 用戶名 22 /// </summary> 23 public string username { get; set; } 24 /// <summary> 25 /// 用戶ID 這個用戶ID,是為了區分是誰發的,(判斷消息展示在左邊或者右邊) 26 /// </summary> 27 public string userid { get; set; } 28 /// <summary> 29 /// 創建時間 30 /// </summary> 31 public string createTime { get; set; } 32 }
Model不多說,下面上zjHub代碼(至於這個命名嗎,你們隨便),里面的各個方法已經注明,后面文章也會對各個方法做詳細介紹。

1 public class ZjHub : Hub 2 { 3 private readonly IBaseQuery<ZjMessage> query = MongoDBFactory<ZjMessage>.CreateInstance("zj"); 4 /// <summary> 5 /// 連接服務器的方法,自動調用客戶端,客戶端需要定義receiveMessage方法 6 /// </summary> 7 /// <returns></returns> 8 public override async Task OnConnected() 9 { 10 try 11 { 12 //用戶第一次進來,讀取歷史記錄 13 var result = await query.GetListAsync(x => x.userid.Length > 0); 14 Clients.Caller.receiveHistoryMessage(new { type = "system", msg = "您已經進入聊天室", oldlist = result.ToList() }); 15 } 16 catch (TimeoutException ex) 17 { 18 19 } 20 } 21 22 /// <summary> 23 /// 重新連接服務器,自動調用客戶端 24 /// </summary> 25 /// <returns></returns> 26 public override Task OnReconnected() 27 { 28 return Clients.Caller.receiveMessage(new { type = "system", msg = "您已經重新進入聊天室。" }); 29 } 30 31 public override Task OnDisconnected(bool stopCalled) 32 { 33 ZjMessage message = new ZjMessage(Context.ConnectionId); 34 //用戶離開 35 return Clients.All.receiveMessage(new { type = "left", msg = message }); 36 } 37 38 public Task Join(ZjMessage message) 39 { 40 message.connectionId = Context.ConnectionId; 41 //就是用戶加入的時候 42 return Clients.All.receiveMessage(new { type = "join", msg = message }); 43 } 44 /// <summary> 45 /// 主要看這個方法,這個就是往服務器發送數據 46 /// </summary> 47 /// <param name="message">消息體是一個zjMessage </param> 48 /// <returns></returns> 49 public async Task Send(ZjMessage message) 50 { 51 message.connectionId = Context.ConnectionId; 52 //存到數據庫 53 await query.InsertAsync(new List<ZjMessage> { message }); 54 //定義客戶端接收方法 ,這里是receiveMessage 55 //這里寫成消息類型為msg new { type = "msg", msg = message } 56 Clients.All.receiveMessage(new { type = "msg", msg = message }); 57 } 58 }
至此,后台代碼基本已經結束了,其實好多業務功能就是前端的,后端主要負責的是服務器穩定性,性能優化等方面。這里暫且不提,看前端之前,在做一下服務地址的配置,在startup類里面編寫如下代碼。
public partial class Startup { public void Configuration(IAppBuilder app) { app.Map("/push/im", map => { var hubConfiguration = new HubConfiguration() { EnableJSONP = true }; map.RunSignalR(hubConfiguration); }); } }
好了,讓我們運行一下,看看這個hub類有沒有起作用,本機地址是:http://localhost:40716/push/im/hubs (如果不加上述配置,地址默認為:http://localhost:40716/singalr/hubs),如果你看到這個地址是js文件,那么前台就能調用了。先看一下推送效果:
第一篇到此先告一段落。下篇預告:
- 實現用戶加入聊天室,推送用戶加入信息
- 實現用戶加入聊天室,自動生成頭像和對應昵稱,並且保存到本地
- 實現歷史記錄讀取。(簡單介紹)
就到這里啦,謝謝各位大牛捧場。