SignalR示例demo


本demo是通過mvc 實現

(1)首先在App_Start下添加Startup.cs文件定義管線的啟動:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalRTest.App_Start.Startup))]

namespace SignalRTest.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 有關如何配置應用程序的詳細信息,請訪問 https://go.microsoft.com/fwlink/?LinkID=316888
            //app.MapSignalR<MyConnection>("echo/{*operation}");
            app.MapSignalR();
        }
    }
}

 

(2)定義Hub的客戶端中包括的方法

    public interface IPlatHubClient
    {
        void ReceiveMsg(string message);//定義前台客戶端上注冊的方法
    }

 

(3)實現Hub服務器端

首先定義Hub的注冊綁定類,該類可以實現hub的clientid與sessionID、userid的綁定(按需修改使用)

    public class PlatHubRegisteInfo
    {
        public string Id { get; set; }
        public string SessionId { get; set; }
        public string UserId { get; set; }
    }

 

PlatHub實現接口如下:(這是真正的通信管線,直接放到項目中即可,無需其他地方注冊)
[HubName("PlatHub")]
    public class PlatHub : Hub<IPlatHubClient>
    {
        private static readonly object ClientMapLock = new object();
        public static readonly Dictionary<PlatHubRegisteInfo, string> ClientMap = new Dictionary<PlatHubRegisteInfo, string>();
        /// <summary>
        /// 客戶端注冊連接信息
        /// </summary>
        /// <param name="id"></param>
        [HubMethodName("Registe")]
        public void Registe(string id)
        {
            lock (ClientMapLock)
            {
                ClientMap.Add(new PlatHubRegisteInfo { Id = id }, this.Context.ConnectionId);
            }
            Log.Write("", "Registe:ConnectionId=" + Context.ConnectionId + Environment.NewLine +"id="+ id);
        }
        public void BroadcastToAll(string message)
        {
            Clients.All.ReceiveMsg(Newtonsoft.Json.JsonConvert.SerializeObject(new { id = Context.ConnectionId, msg = message }));
        }
        public void BroadcastToSome(string[] ids, string message)
        {
            Clients.Clients(ids.ToList()).ReceiveMsg(Newtonsoft.Json.JsonConvert.SerializeObject(new { id = Context.ConnectionId, msg = message }));
        }
        //
        // 摘要:
        //     Called when the connection connects to this hub instance.
        //
        // 返回結果:
        //     A System.Threading.Tasks.Task
        public override async Task OnConnected()
        {
            var t = this;
            base.OnConnected();
            return;
        }
        //
        // 摘要:
        //     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
        public override async Task OnDisconnected(bool stopCalled)
        {
            var t = this;
            var infos = ClientMap.Where(a => a.Value == this.Context.ConnectionId);
            if (infos.Any())
            {
                var info = infos.First();
                lock (ClientMapLock)
                {
                    ClientMap.Remove(info.Key);
                }
                Log.Write("", "Disconnected:ConnectionId=" + Context.ConnectionId + Environment.NewLine + "id=" + info.Key.Id);
            }
            base.OnDisconnected(stopCalled);
            return;
        }
        //
        // 摘要:
        //     Called when the connection reconnects to this hub instance.
        //
        // 返回結果:
        //     A System.Threading.Tasks.Task
        public override async Task OnReconnected()
        {
            var t = this;
            base.OnReconnected();
            return;
        }
        protected override async void Dispose(bool disposing)
        {
            var t = this;
            base.Dispose(disposing);
            return;
        }
    }

 

(3)添加控制器HomeController,並添加試圖方法:

        public ActionResult Index()
        {
            Guid id = Guid.NewGuid();
            Response.Cookies.Add(new HttpCookie("id", id.ToString()));//cookie將通過客戶端的Registe實現與服務器的關聯
            return View();
        }

 

(4)前台Index試圖如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home Page - 我的 ASP.NET 應用程序</title>
    
</head>
<body>
    

<div>home</div>
<div><input type="text" id="msg" /><input type="button" id="sendmsg" value="廣播" /></div>
<div id="divStatus"></div>
<div>msgs:</div>
<div id="msgContainer"></div>

    <script src="/Scripts/jquery-1.10.2.js"></script>

    <script src="/Scripts/jquery.cookie-1.4.1.min.js"></script>
    <script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>

    
    <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="/Scripts/jquery.signalR-2.2.2.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="/signalr/hubs"></script>
    <!--SignalR script to update the chat page and send messages.-->
    <script>
        $(function () {
            // hub名稱(如若類名用特性重命名了,則是特性重命名的名稱,否則就是類名的首字母小寫;).
            var chat = $.connection.PlatHub;
            //啟用瀏覽器端輸出日志
            $.connection.hub.logging = true;
            // 客戶端定義一個函數,服務器上可以調用.
            chat.client.ReceiveMsg = function (message) {
                //var ob = $.parseJSON(message);
                //                $("#msgContainer").append("<div>id:" + ob.code + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg:" + ob.content + "</div>");
                $("#msgContainer").append("<div>" + message+"</div>");
            };
            // Start the connection.
            $.connection.hub.starting(function () {
                console.log('starting.')
            });
            $.connection.hub.received(function (e) {
                console.log('received.'+e)
            });
            $.connection.hub.connectionSlow(function () {
                console.log('connectionSlow.')
            });
            $.connection.hub.reconnecting(function () {
                console.log('reconnecting.')
            });
            $.connection.hub.reconnected(function () {
                console.log('reconnected.')
            });
            $.connection.hub.stateChanged(function (o, n) {
                console.log('stateChanged.' + o + "," + n)
            });
            $.connection.hub.disconnected(function () {
                console.log('disconnected.');
                setTimeout(function () {
                    $.connection.hub.start();
                }, 1000); // Restart connection after 1 seconds.
            });
            $.connection.hub.error(function (error) {
                console.log('SignalR error: ' + error)
            });
            $.connection.hub.start().done(function () {
                chat.server.Registe($.cookie('id'));//定義id,與管線clientid關聯
                $("#sendmsg").click(function () {
                    $.ajax({
                        url: 'GuangBo',
                        type: 'POST', //GET
                        async: true,    //或false,是否異步
                        data: {
                            msg: $("#msg").val()
                        },
                        timeout: 5000,    //超時時間
                        dataType: 'json',    //返回的數據格式:json/xml/html/script/jsonp/text
                        beforeSend: function (xhr) {
                            console.log(xhr)
                            console.log('發送前')
                        },
                        success: function (data, textStatus, jqXHR) {
                            if (data.code == 1) {
                                $("#divStatus").val(new Date().toString() + ":成功");
                            }
                            else
                                $("#divStatus").val(new Date().toString() + ":失敗");
                        },
                        error: function (xhr, textStatus) {
                            console.log('錯誤')
                            console.log(xhr)
                            console.log(textStatus)
                        },
                        complete: function () {
                            console.log('結束')
                        }
                    });
                });
            }).fail(function (error) {
                console.log('fail Error: ' + error);
            });
        });
        // This optional function html-encodes messages for display in the page.
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>

</body>
</html>

在前端代碼中,如下代碼是定義客戶端的方法:

chat.client.ReceiveMsg = function (message) {
                //var ob = $.parseJSON(message);
                //                $("#msgContainer").append("<div>id:" + ob.code + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg:" + ob.content + "</div>");
                $("#msgContainer").append("<div>" + message+"</div>");
            };

前端如下代碼是訪問服務器:

chat.server.Registe($.cookie('id'));//Registe是PlatHub上通過特性HubMethodName定義的

前端代碼調用的后端控制器GuangBo實現如下:

        [HttpPost]
        public JsonResult GuangBo(string msg)
        {
            var chatHub = GlobalHost.ConnectionManager.GetHubContext<PlatHub>();
            chatHub.Clients.All.ReceiveMsg(msg);//給所有人
            return Json(new { code = 1 });
        }

若希望給單獨一個ID發送,可以采用如下:

        [HttpPost]
        public JsonResult ToSingle(string client,string msg)
        {
            var chatHub = GlobalHost.ConnectionManager.GetHubContext<PlatHub>();
            chatHub.Clients.Client(client).ReceiveMsg(msg);
            return Json(new { code = 1 });
        }

 可以通過

HubName、HubMethodName

兩個特性重命名管線名稱、服務器端注冊的管線實現名稱


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM