因?yàn)轫?xiàng)目需要,需要在網(wǎng)頁(yè)上實(shí)現(xiàn)消息的推送。在百度上搜索了一下,發(fā)現(xiàn)實(shí)現(xiàn)網(wǎng)頁(yè)上的消息推送,可以使用asp.net 中的SignalR類(lèi)庫(kù),當(dāng)然也可以使用H5的WebSocket Ajax的輪回。當(dāng)然此處我們使用asp.net 中的SignalR類(lèi)庫(kù)。因?yàn)樗梢詫?shí)現(xiàn)網(wǎng)頁(yè)上消息的實(shí)時(shí)推送。什么是實(shí)時(shí)推送呢,我簡(jiǎn)單的說(shuō)一下我個(gè)人的理解吧。實(shí)時(shí):在同一時(shí)間類(lèi)發(fā)生的事情,當(dāng)然在計(jì)算機(jī)中并不是絕對(duì)的實(shí)時(shí),因?yàn)镃PU在同一時(shí)間片只能處理一個(gè)任務(wù),那么這個(gè)時(shí)候疑問(wèn)又來(lái)了?
我們平時(shí)使用電腦又上網(wǎng),又聽(tīng)音樂(lè)是如何實(shí)現(xiàn)的呢,因?yàn)楝F(xiàn)在的CPU的計(jì)算速度很快。CPU會(huì)把處理不同的任務(wù)的時(shí)間片,CPU會(huì)把時(shí)間片劃到很小,很小,小到我們?nèi)祟?lèi)感知不到。比如在現(xiàn)在這個(gè)時(shí)間片上,CPU正在處理音樂(lè)任務(wù),在下一個(gè)時(shí)間片的時(shí)候,CPU又在處理上網(wǎng)任務(wù)。所以我認(rèn)為在計(jì)算機(jī)并沒(méi)有絕對(duì)的實(shí)時(shí),只是我們?nèi)祟?lèi)感知不到罷了。
推送:在此處的推送是指在網(wǎng)頁(yè)消息推送。例如:用戶(hù)A和B分別在各自的電腦打開(kāi)打開(kāi)一個(gè)相同的消息推送網(wǎng)頁(yè)。假設(shè)用戶(hù)A現(xiàn)在向用戶(hù)B發(fā)送消息。就要經(jīng)歷一個(gè)這樣的過(guò)程 用戶(hù)A->Server->用戶(hù)B。當(dāng)然具體的底層實(shí)現(xiàn)過(guò)程,我就不在些探討了哈。因?yàn)檫@個(gè)不是現(xiàn)在所要探討的主題。因?yàn)镾erver有地址一般是固定不變的。所以客戶(hù)端向服務(wù)器發(fā)送消息比較容易,因?yàn)槟康牡刂饭潭?。那服?wù)器如何向客戶(hù)端發(fā)送消息呢,這個(gè)就有點(diǎn)難道了因?yàn)榭蛻?hù)端的地址不固定的,并且http是無(wú)狀態(tài)的是不能記住用戶(hù)的地址的。
所以為了解決這一個(gè)問(wèn)題,計(jì)算機(jī)的先輩們用到了幾個(gè)方法:
1、客戶(hù)端"心跳"。每隔一段時(shí)間去訪(fǎng)問(wèn)服務(wù)器,看看服務(wù)器有沒(méi)有任務(wù)給其客戶(hù)端。Ajax的輪回就是使用的這個(gè)方法。缺點(diǎn)就是實(shí)時(shí)性不太高。
2、服務(wù)端和客戶(hù)端的長(zhǎng)連接,本文所要談到的SignalR就是用的這種思想。缺點(diǎn):服務(wù)器的壓力大。
好了,現(xiàn)在就說(shuō)一下什么是SignalR吧。SignalR 是為 ASP.NET 開(kāi)發(fā)人員提供的一個(gè)庫(kù),可以簡(jiǎn)化開(kāi)發(fā)人員將實(shí)時(shí) Web 功能添加到應(yīng)用程序的過(guò)程。實(shí)時(shí) Web 功能是指這樣一種功能:當(dāng)所連接的客戶(hù)端變得可用時(shí)服務(wù)器代碼可以立即向其推送內(nèi)容,而不是讓服務(wù)器等待客戶(hù)端請(qǐng)求新的數(shù)據(jù)。這個(gè)也就實(shí)現(xiàn)消息的實(shí)時(shí)推送。我個(gè)人理解的實(shí)現(xiàn)原理是首先由服務(wù)器定制一個(gè)函數(shù)用于一個(gè)客戶(hù)端調(diào)用將消息發(fā)送給另一個(gè)客戶(hù)端。當(dāng)然客戶(hù)端也需要定抽一個(gè)函數(shù)。因?yàn)榉?wù)器需要調(diào)用客戶(hù)端的這個(gè)函數(shù)。
下面就說(shuō)下具體的操作方法吧。
1、環(huán)境:win 10+VS2015 社區(qū)版
我使用asp.net mvc。首先打開(kāi)VS 2015|文件|新建|項(xiàng)目(SignalRMvc)|asp.net Web應(yīng)用程序|空模板,MVC,平臺(tái)大概就是這樣了。
現(xiàn)在說(shuō)下具體需要包含的文件吧。
1)、SignalR集線(xiàn)器類(lèi)。用于寫(xiě)一個(gè)訪(fǎng)求調(diào)用客戶(hù)段的函數(shù)。
2)、OWIN類(lèi)。用于注冊(cè)服務(wù)器的函數(shù)。
3)、前臺(tái)的頁(yè)面(包括前臺(tái)的消息框的編寫(xiě),函數(shù)的編寫(xiě))當(dāng)然前臺(tái)需要一些文件。
一般VS沒(méi)有自帶SignalR類(lèi),需要我們?cè)陂_(kāi)始任務(wù)之前去添加這個(gè)功能。選擇VS的工具|Nuget包管理器|Nuget包管理器控制臺(tái)|Install-Package Microsoft.Aspnet.SignalR去安裝SignalR。安裝完成后,1、我們?cè)诟捻?xiàng)目中新建一個(gè)文件夾為ChatHubs|新建一個(gè)SignalR集線(xiàn)器類(lèi),并寫(xiě)上如下代碼:
using Microsoft.AspNet.SignalR;
namespace SignalRMvc.ChatHubs
{
public class ChatHub : Hub
{
public void SendMessage(string name,string message)
{
// Clients.All.hello();
Clients.All.receiveMessage(name, message);
//用戶(hù)調(diào)用客戶(hù)端的函數(shù)
}
}
}
2、在ChatHubs文件夾下新建一個(gè)OWIN類(lèi)。并寫(xiě)上如下代碼:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRMvc.ChatHubs.Startup))]
namespace SignalRMvc.ChatHubs
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
//服務(wù)器的hub注冊(cè)
}
}
}
3、在Controllers新建一個(gè)Home控制器。并寫(xiě)上如下代碼:
using System.Web.Mvc;
namespace SignalRMvc.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult ClientChat()
{
return View();
}
}
}
4、在控制器的方法上右擊添加視圖(不使用模板,也不使用布局頁(yè))后。并寫(xiě)上如下代碼:
@{
Layout = null;
}
!DOCTYPE html>
html>
head>
meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
title>/title>
meta charset="utf-8" />
link href="~/Content/bootstrap.min.css" rel="stylesheet" />
@* BootStarp的引入*@
style>
#message_box {
height: 400px;
overflow-y: scroll;
}
/style>
@* 呈現(xiàn)消息 *@
/head>
body>
div class="container">
div class="row">
div class="jumbotron">
ul id="message_box">/ul>
/div>
發(fā)送者名稱(chēng):input id="text_name" class="form-control" />br />
消息內(nèi)容:
textarea id="text_message" class="form-control" rows="3">/textarea>
br />
button id="btn_send" class="btn btn-block btn-success">Send/button>
/div>
/div>
script src="~/scripts/jquery-3.1.0.min.js">/script>
script src="~/scripts/jquery.signalR-2.2.1.min.js">/script>
@* 上述引入的兩個(gè)文件的順序不以交換,因?yàn)橄旅孢@個(gè)文件依賴(lài)于上面那個(gè)文件 *@
script src="~/signalr/hubs">/script>
!-- 本地沒(méi)有,動(dòng)態(tài)生成 -->
script>
$(function () {
var $messageBox = $('#message_box');
var $textMessage = $('#text_message');
var $textName = $('#text_name');
//客戶(hù)端先與服務(wù)器連接起來(lái),拿到服務(wù)器的代理操作對(duì)象
var hubConnection = $.connection.chatHub;
//注冊(cè)客戶(hù)端函數(shù)
hubConnection.client.receiveMessage = function (name, message) {
$messageBox.append('li>b>' + name + '/b> say:' + message + '/li>')
}
//啟動(dòng)連接到服務(wù)器
$.connection.hub.start().done(function () {
$('#btn_send').bind('click', function () {
//調(diào)用服務(wù)端的函數(shù)
hubConnection.server.sendMessage($textName.val(), $textMessage.val());
});
});
});
/script>
/body>
/html>
如果直接復(fù)制使用。要注意前臺(tái)的代碼引入的文件的目錄及版本。前臺(tái)代碼的命名的首字母最好使用小寫(xiě),后臺(tái)代碼的首字母最好使用大寫(xiě)。因?yàn)閖s默認(rèn)使用的是駝峰命名法,C Sharp使用帕斯卡命名方式。如果沒(méi)有注重這個(gè)細(xì)節(jié)就會(huì)很容易出錯(cuò)。因?yàn)楹笈_(tái)代碼在執(zhí)行的時(shí)候會(huì)動(dòng)態(tài)的生成一些JS代碼,JS代碼的默認(rèn)使用的駝峰命名法。如果你在前臺(tái)的代碼用了帕斯卡命名方式就很容易出錯(cuò)了。并且還不好找。我是有過(guò)親身經(jīng)歷的。
下面我們?cè)诒镜販y(cè)試下:分別使用FireFox和Chrome來(lái)模擬兩個(gè)客戶(hù)端,當(dāng)然自身的電腦也就服務(wù)端。效果圖如下:
![](http://img.jbzj.com/file_images/article/201607/201672884900004.jpg?201662884911)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- 基于SignalR的消息推送與二維碼掃描登錄實(shí)現(xiàn)代碼
- Asp.NET MVC中使用SignalR實(shí)現(xiàn)推送功能
- 使用SignalR推送服務(wù)在A(yíng)ndroid的實(shí)現(xiàn) SignalA
- ASP.NET實(shí)現(xiàn)推送文件到瀏覽器的方法
- .net平臺(tái)推送ios消息的實(shí)現(xiàn)方法
- .net 通過(guò)URL推送POST數(shù)據(jù)具體實(shí)現(xiàn)
- SignalR Self Host+MVC等多端消息推送服務(wù)(二)
- SignalR Self Host+MVC等多端消息推送服務(wù)(一)
- SignalR Self Host+MVC等多端消息推送服務(wù)(三)