最近比较累,也没时间写博客,今天索性来一篇,很多时候,网站即时通讯,推送必不可少。但是这部分大家都觉得是那么陌生,不敢尝试,今天我就给大家讲讲SignalR的简单使用。
首先我们打开VS,创建一个web应用程序。然后Nuget安装SignalR,如下。
安装好之后,我们在项目的引用中发现程序给我们自动引用了相关的dll以及js文件。
接着我们创建两个类,一个是ChatHub,继承自Hub,如下
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace Chart.SignalR
{
[HubName("ChatRoomHub")]
public class ChatHub : Hub
{
static List<UserEntity> users = new List<UserEntity>();
public async Task UserEnter(string nickName)
{
UserEntity userEntity = new UserEntity
{
NickName = nickName,
ConnectionId = Context.ConnectionId
};
users.Add(userEntity);
await Clients.All.NotifyUserEnter(nickName, users);
}
public async Task SendMessage(string nickName, string message)
{
await Clients.All.NotifySendMessage(nickName, message);
}
public override Task OnDisconnected(bool isStop)
{
var currentUser = users.FirstOrDefault(u => u.ConnectionId == Context.ConnectionId);
if (currentUser != null)
{
users.Remove(currentUser);
Clients.Others.NotifyUserLeft(currentUser.NickName, users);
}
return base.OnDisconnected(isStop);
}
}
public class UserEntity
{
public string NickName { get; set; }
public string ConnectionId { get; set; }
}
}在这里我们给ChatHub起了别名ChatRoomHub。大家从代码上看就知道我写的将是一个聊天室的代码。这里users用来存储在线人员,NickName存放用户进聊天室之前输入的昵称,ConnectionId则是Hub上下文给每个连接分配的唯一标识,这样方便我们判断用户离线的情况。
在这个Hub子类中,
UserEnter方法用来记录加入聊天的用户,并通知到其他客户端浏览器更新UI。
SendMessage方法用来将客户端发送的消息推送到所有的客户端浏览器。
OnDisconnected顾名思义就是客户端离线,离线后将离线用户从用户数组中删除掉,并通知其他用户浏览器更新UI,注意这里的Clients.Others
接着我们再看一下StartUp类
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(Chart.SignalR.StartUp))]
namespace Chart.SignalR
{
public class StartUp
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}这里OwinStartup标识了哪个类是自动启动,app.MapSignalR()则是将app builder 管道映射到一个路径上,待会我们会看到这个路径。
OK,接下来我们看下客户端的代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="StyleSheet/bootstrap/css/bootstrap.min.css" />
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="signalr/hubs"></script>
<style type="text/css">
.demo {
margin-bottom: 20px;
padding-left: 50px;
position: relative;
}
.triangle {
position: absolute;
top: 50%;
margin-top: -8px;
left: 42px;
display: inline;
width: 0;
height: 0;
overflow: hidden;
line-height: 0;
font-size: 0;
border-bottom: 8px solid #FFF;
border-top: 8px solid #FFF;
border-left: none;
border-right: 8px solid #3079ED;
}
.demo .article {
float: left;
color: #FFF;
display: inline;
zoom: 1;
padding: 5px 10px;
border: 1px solid #3079ED;
background: #eee;
border-radius: 5px;
background-color: #4D90FE;
background-image: -webkit-gradient(linear,left top,left bottom,from(#4D90FE),to(#4787ED));
background-image: -webkit-linear-gradient(top,#4D90FE,#4787ED);
background-image: -moz-linear-gradient(center top, #4D90FE, #4787ED);
background-image: linear-gradient(top,#4D90FE,#4787ED);
}
.fr {
padding-left: 0px;
padding-right: 50px;
}
.fr .triangle {
left: auto;
right: 42px;
border-bottom: 8px solid #FFF;
border-top: 8px solid #FFF;
border-right: none;
border-left: 8px solid #3079ED;
}
.fr .article {
float: right;
}
.round-img-list {
border-radius: 50%;
border: solid;
border-width: 1px;
border-color: #FFCC00;
width: 45px;
height: 45px;
}
.clear-float {
clear: both;
}
</style>
</head>
<body>
<div class="container" style="margin-top: 10px">
<div class="row">
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">
聊天室
</div>
<div id="div_msgbody" class="panel-body" style=‘min-height: 500px; max-height: 500px; overflow: auto; max-width: 850px;‘>
<div id="div_msg" style=‘word-wrap: break-word; word-break: break-word;‘></div>
</div>
<div class="panel-footer">
<div class="row">
<div class="col-md-11">
<div class="input-group">
<span class="input-group-addon">内容:</span>
<input id="message" type="text" class="form-control" maxlength="500" placeholder=‘在此输入聊天内容‘ />
</div>
</div>
<div class="col-md-1">
<button id="btn_Send" type="button" class="btn btn-info">发送</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="panel panel-primary">
<div class="panel-heading">
用户列表
</div>
<div class="panel-body" style=‘min-height: 500px; max-height: 500px; overflow: auto;‘>
<div id="div_member"></div>
</div>
<div class="panel-footer">
<div style="height: 34px; height: 34px; line-height: 34px">
人员总数:<label id="lab_total">0</label>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var userNickName;
jQuery(document).ready(function () {
while (!userNickName) {
userNickName = window.prompt("请输入昵称!");
}
var chatHub = $.connection.ChatRoomHub;
chatHub.client.NotifyUserEnter = function (nickName, users) {
buildUserTemplate(users);
}
chatHub.client.NotifyUserLeft = function (nickName, users) {
buildUserTemplate(users);
}
chatHub.client.NotifySendMessage = function (nickName, message) {
var userAvatar = ‘http://www.wed114.cn/jiehun/uploads/allimg/160426/39_160426110624_1.jpg‘;
if (nickName == userNickName) {
$("#div_msg").append("<div style=‘text-align:right;float:right‘>"
+ "<span style=‘margin-right:10px‘>" + nickName + "</span>"
+ "<img src=‘" + userAvatar + "‘ style=‘height:40px;width:40px;position:relative‘/>"
+ "<div class=‘demo clearfix fr‘>"
+ "<span class=‘triangle‘></span>"
+ "<div class=‘article‘ style=‘word‘>" + message
+ "</div></div></div><div class=‘clear-float‘/>");
}
else {
$("#div_msg").append("<div>"
+ "<img src=‘" + userAvatar + "‘ style=‘height:40px;width:40px;position:relative‘/>"
+ "<span style=‘left:10px;position:relative‘>" + nickName + "</span>"
+ "<div class=‘demo clearfix‘>"
+ "<span class=‘triangle‘></span>"
+ "<div class=‘article‘>" + message
+ "</div></div></div>");
}
var objDiv = document.getElementById("div_msgbody");
objDiv.scrollTop = objDiv.scrollHeight;
}
$.connection.hub.start().done(function () {
chatHub.server.userEnter(userNickName);
});
$("#message").keydown(function (event) {
if (event.keyCode == 13) {
if ($("#message").val() != "") {
chatHub.server.sendMessage(userNickName, $("#message").val());
$("#message").val("");
}
}
});
$("#btn_Send").click(function () {
if ($("#message").text != "") {
chatHub.server.sendMessage(userNickName, $("#message").val());
$("#message").val("");
}
})
function buildUserTemplate(users) {
$("#lab_total").text(users.length);
var userTemplate = "<ul style=‘list-style:none;‘>"
$.each(users, function (e, v) {
var userAvatar = ‘http://www.wed114.cn/jiehun/uploads/allimg/160426/39_160426110624_1.jpg‘;
userTemplate += "<li style=‘padding-top:5px;‘>"
+ "<img class=‘round-img-list‘ src=‘" + userAvatar + "‘/>"
+ "<label style=‘color:#666666;margin-left:10px‘>" + v.NickName + "</label>"
+ "</li>";
});
userTemplate += "</ul>";
$("#div_member").html(userTemplate);
}
});
</script>
</body>
</html>布局我就不说了,BootStrap布局。这里需要注意这个路径
<script src="signalr/hubs"></script>
这个路径就是上面说的管道map的路径,在这个路径下会生成hubs.js文件,在这个文件中有注册hub代码,生成hub代理等方法。
然后在js中,先让用户输入昵称,输入后,得到chatHub对象,然后
实现NotifyUserEnter,NotifyUserLeft以及NotifySendMessage方法。NotifyUserEnter和NotifyUserLeft方法主要是更新右边panel显示的人员信息。而NotifySendMessage方法则是将服务器推送出的聊天信息展示在span中。在这里我们为了区分自己和别人,自己的聊天信息显示在右边,别人的显示在左边。
var objDiv = document.getElementById("div_msgbody");
objDiv.scrollTop = objDiv.scrollHeight;这句的意思是如果聊天记录太多出现了滚动条,则将滚动条自动滚动到最底部。
$.connection.hub.start().done(function () {
chatHub.server.userEnter(userNickName);
});这句意思是当有新用户时,就会和服务端建立连接,连接完成后,调用Server端的UserEnter方法,在客户端这里写小写开头,记住。最后发送消息,调用server端的SendMessage方法。
OK,至此程序大概就讲完了,很简单的一个demo,大家看了的也评价评价。俗话说无图无真相,看图
好了今天就到这里,后面我会继续写nodejs相关的博客。
本文出自 “技术创造价值” 博客,请务必保留此出处http://leelei.blog.51cto.com/856755/1787479
原文地址:http://leelei.blog.51cto.com/856755/1787479