你的位置:首页 > ASP.net教程

[ASP.net教程]SignalR简单示例教程入门版


上周五最后一天在公司上班,无聊之余就想做点什么.介于之前有人让我做个简易版的在线聊天的,于是乎就打算花一天时间来弄下关于SignalR的简单教程制作一个在线的聊天的。

1:前端用了国产的一个MVVM框架 avalon 的早期版本和 layer  插件(具体怎么用这里就不介绍了,需要了解的自行百度)

2:MVC项目里面新增一个Hub 的继承类 ChatHub , 标签HubName 类似于一个重命名的效果

3:OnlineCache 类的作用是定义了一个KEY和VALUE主要用于记录用户名称和Signalr自动生成的KEY关系

4 : Startup.cs   里记得注册下 app.MapSignalR();

 

[HubName("customhub")]  public class ChatHub : Hub  {    /// <summary> /// 发送信息/// </summary> /// <param name=""></param> /// <returns></returns>    public void Send(string name, string message)    {      Clients.All.addNewMessageToPage(name, message);    }    /// <summary> /// 页面打开创建Signalr对象时由客户端调用,然后服务端将已经存在的用户列表,推送回客户端用于刷新在线用户列表/// </summary> /// <param name=""></param> /// <returns></returns>    public void Push(string name)    {      if (!OnlineCache.dicSignalrs.ContainsKey(base.Context.ConnectionId))        OnlineCache.dicSignalrs.Add(base.Context.ConnectionId, name);      else      {        OnlineCache.dicSignalrs.Remove(base.Context.ConnectionId);        OnlineCache.dicSignalrs.Add(base.Context.ConnectionId, name);      }      Clients.All.subscribeUsers(name,OnlineCache.OnlineToList());    }    //    // 摘要:    //   Called when the connection connects to this hub instance.    //    // 返回结果:    //   A System.Threading.Tasks.Task    public override Task OnConnected()    {return base.OnConnected();    }    //    // 摘要:    //   Called when a connection disconnects from this hub gracefully or due to a timeout.    //    // 参数:    //  stopCalled:    //   true, if stop was called on the client closing the connection gracefully; false,    //   if the connection has been lost for longer than the Microsoft.AspNet.SignalR.Configuration.IConfigurationManager.DisconnectTimeout.    //   Timeouts can be caused by clients reconnecting to another SignalR server in scaleout.    //    // 返回结果:    //   A System.Threading.Tasks.Task    /// <summary>    /// 离线触发    /// </summary>    /// <param name="stopCalled"></param>    /// <returns></returns>    public override Task OnDisconnected(bool stopCalled)    {      if (OnlineCache.dicSignalrs.ContainsKey(base.Context.ConnectionId))      {        var name = OnlineCache.dicSignalrs[base.Context.ConnectionId];        OnlineCache.dicSignalrs.Remove(base.Context.ConnectionId);        Clients.All.removeUser(name, OnlineCache.OnlineToList());      }      return base.OnDisconnected(stopCalled);    }    //    // 摘要:    //   Called when the connection reconnects to this hub instance.    //    // 返回结果:    //   A System.Threading.Tasks.Task    public override Task OnReconnected()    {      return base.OnReconnected();    }  }  public class OnlineCache  {    public OnlineCache() {         }    public string Key { set; get; }    public string Value { set; get; }    static OnlineCache()    {      if (dicSignalrs == null)        dicSignalrs = new Dictionary<string, string>();    }    public static Dictionary<string, string> dicSignalrs;    /// <summary>    /// 提取list    /// </summary>    /// <returns></returns>    public static List<OnlineCache> OnlineToList() => dicSignalrs.Select(o => new OnlineCache() { Key = o.Key, Value = o.Value }).ToList();  }


前端JS脚本

@{  Layout = null;}<!DOCTYPE html><html><head>  <meta name="viewport" content="width=device-width" />  <title>Index</title>  <link href="~/Content/bootstrap.min.css" rel="stylesheet" />  <link href="~/Content/Site.css" rel="stylesheet" />  <link href="~/Scripts/layer-v2.4/layer/skin/layer.css" rel="stylesheet" />  <script src="~/Scripts/jquery-1.10.2.min.js"></script>  <script src="~/Scripts/Avalon/json2.js"></script>  <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>  <script src="~/Scripts/layer-v2.4/layer/layer.js"></script>  <script src="~/Scripts/Avalon/avalon.js"></script>  <script src="http://www.cnblogs.com//signalr/hubs"></script>  <script>    var onlines = [];    var chat;    $(function () {      vm.init();    });    var vm =      avalon.define({        $id: "online",        sendname: "所有在线用户",        customname: "",        onlines: [],        logs: [],        authorize: false,        sendText: "",        firstload: false,        init: function () {          layer.prompt({            title: '输入聊天昵称,并确认',            formType: 0          }, function (name) {            layer.msg('聊天室内容加载中', {              time: 1000            });            vm.customname = name;            vm.authorize = true;            vm.callbackmessage();          });        },        connection: function () {          $.connection.hub.start().done(function () {            ///首次页面加载注册完毕后直接把用户名发到后台建立用户列表            if (!vm.firstload) {              vm.firstload = true;              chat.server.push(vm.customname);            }            $('#btnSend').click(function () {              if (!vm.authorize) {                layer.msg("没有通过授权不能进行聊天");                return;              }              chat.server.send(vm.customname, $('#message').val());              $('#message').val('').focus();            });          });          vm.getOnlineUser();        },        callbackmessage: function () {          chat = $.connection.customhub;          chat.client.subscribeUsers = function (name,users) {            layer.tips(name + " 上线", '#btnSend', {              tips: [1, '#3595CC']            });            vm.onlines = users;          };          chat.client.removeUser = function (name, users) {            layer.tips(name + " 离线", '#btnSend', {              tips: [1, 'red']            });            vm.onlines = users;          };          chat.client.addNewMessageToPage = function (name, message) {            vm.logs.push({ name: name, message: message });          };          vm.connection();        }      });  </script></head><body ms-controller="online">  <div class="col-sm-2 col-md-2 col-lg-2">    <label>在线用户列表</label>    <br />    <div class="list-group">      <a href="#" ms-repeat="onlines" class="list-group-item">        {{el.Value}}      </a>    </div>  </div>  <div class="col-sm-5 col-md-5 col-lg-5">    <textarea id="message" placeholder="输入发送内容" class="form-control" style="width:100%;" ms-duplex="sendText"></textarea>    <br />    <br />    <div class="row col-sm-12 col-md-12 col-lg-12">      <div class="table-scrollable" style="max-height: 400px; overflow:auto; ">        <table class="table table-bordered table-hover text-center">          <thead>            <tr>              <th class="col-sm-4">发送人</th>              <th class="col-sm-8">内容</th>            </tr>            <tr href="#" ms-repeat="logs">              <th class="col-sm-4">{{el.name}}</th>              <th class="col-sm-8">{{el.message}}</th>            </tr>          </thead>        </table>      </div>    </div>  </div>  <div class="col-sm-3 col-md-3 col-lg-3">    <br />    <div class="row">      <input class="btn btn-primary col-sm-5 col-md-5 col-lg-5" value="发送消息" id="btnSend" type="button" />    </div>    <br />    <br />    <div class="row">      <label>账号昵称:</label><label>{{customname}}</label>    </div>    <br />    <br />    <div class="row">      <label>发送对象:</label><label>{{sendname}}</label>    </div>  </div>  <div class="row">     <div class="col-sm-offset-11 col-sm-1 pull-right" style="margin-bottom:0px;" id="tip">           </div>  </div></body></html>