ASP.NET SingalR + MongoDB 实现简单聊天室(一):搭建基本框架
ASP.NET SingalR不多介绍。让我介绍不如看官网,我这里就是直接上源代码,当然代码还是写的比较简单的,考虑的也少,希望各位技友多多提意见。
先简单介绍聊天室功能:
- 用户加入聊天室,自动给用户名和头像。(可扩展用户自定义昵称和头像,未做)
- 聊天信息发送,群聊。(可扩展1对1聊天,群组聊天,1对多聊天,扩展多种消息格式,未做)
- 本地存储用户信息
- 后台结合mongodb存储聊天信息,用户下次进入可以看到聊天记录(MongoDB .NET客户端的使用,可以用SQL或者缓存存储,不作为重点阐述)
写了这么多文字,是不是激不起兴趣来,好直接上一张图,然后搭建基本框架。
ok,我们开始搭建界面。
新建asp.net mvc 项目,然后添加一个SingalR集线器类。(不用手动引用singalR.dll,当然可以从nuget上安装)
其实hub代码比较简单,这里只为了实现简单聊天室功能,就不多写其他代码。因为未完善代码,所以暂时不公开。较为复杂点的代码,有兴趣的同学可以邮箱留言,我发给你们。
编写后台代码之前呢,先分析页面结构。首先,聊天基本内容包含:聊天内容,用户昵称,用户头像,用户发表时间,ok,那么新建一个model吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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代码(至于这个命名吗,你们随便),里面的各个方法已经注明,后面文章也会对各个方法做详细介绍。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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文件,那么前台就能调用了。先看一下推送效果:
第一篇到此先告一段落。下篇预告:
- 实现用户加入聊天室,推送用户加入信息
- 实现用户加入聊天室,自动生成头像和对应昵称,并且保存到本地
- 实现历史记录读取。(简单介绍)
就到这里啦,谢谢各位大牛捧场。
多学点,总不会吃亏的。