最近在學習SignalR服務器實時推技術,寫了個Demo,普通的Asp.netWeb應用程序,IIS訪問地址為http://localhost/SignalR_Test/Paint.html,用VS自帶的IISExpress測試沒有任何問題,在部署到IIS之后就出問題了。
加載頁面時彈出JS報錯:無法獲取未定義或 null 引用的屬性“client”,$.connection訪問
Hub-Proxy返回一個null對象。

IIS版本為IIS8,檢查應用程序池,Framework4.0,集成模式。IIS部署沒有問題。
使用IE自帶的抓包工具發現在獲取signalr/Hubs時,返回404:

發現請求地址中應用程序名稱SignalR_Test不見了,直接在IE中訪問http://localhost/SignalR_Test/signalr/hubs能得到hubs返回的js文件

檢查代碼,將hubs的引用路徑前部的“/”去掉后,SignalR正常運行!

最后說一下這個Demo,是個類似以前人人網的一個你畫我猜的社交類游戲。
CSS渣,各位自重。。。
畫畫者頁面:

答題者頁面:

代碼:
Paint.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>你畫我猜網頁版</title>
<style>
.left, .center, .right {
float: left;
height: 600px;
}
.left, .right {
background-color: lightgrey;
width: 230px;
font-family: 'Microsoft YaHei';
color: brown;
}
.center {
width: 804px;
}
.left .ctop {
height: 50px;
}
.left .cbottom {
height: 550px;
}
.left .cbottom .subanswer {
padding-top: 15px;
text-align: center;
}
.control-ops {
background-color: burlywood;
padding-top: 69px;
text-align: center;
}
.btnCss {
background-color: yellow;
color: red;
}
#ans {
width: 150px;
}
#user {
color: coral;
}
#cntusers {
color: darkorchid;
text-align: center;
}
</style>
</head>
<body>
<div class="left">
<div class="ctop">
畫題:<label id="subject"></label>
</div>
<div class="cbottom">
<div>
答案:<input id="ans" />
</div>
<div class="subanswer">
<input type="button" id="subAnswer" class="btnCss" value="提交" />
</div>
</div>
</div>
<div class="center">
<div>
<canvas id="myCanvas" width="800" height="500" style="border:2px solid #6699cc"></canvas>
<img id="img1" width="800" height="500" style="display:none" />
</div>
<div class="control-ops">
<button type="button" class="btnCss" onclick="javascript:clearArea();return false;">清空畫板</button>
畫筆直徑 : <select id="selWidth">
<option value="1">1</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="7">7</option>
<option value="9" selected="selected">9</option>
<option value="11">11</option>
</select>
顏色 : <select id="selColor">
<option value="black">black</option>
<option value="blue" selected="selected">blue</option>
<option value="red">red</option>
<option value="green">green</option>
<option value="yellow">yellow</option>
<option value="gray">gray</option>
</select>
<input type="button" id="sendmessage" class="btnCss" value="完成畫畫" />
</div>
</div>
<div class="right">
<div>
歡迎你,<label id="user"></label>!
</div>
<div>用戶列表:<label id="cntusers"></label></div>
</div>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery-ui-1.11.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.1.2.js"></script>
<script src="signalr/hubs"></script>
<script>
//窗口最大化
self.moveTo(0, 0);
self.resizeTo(screen.availWidth, screen.availHeight);
var mousePressed = false;
var lastX, lastY;
var ctx;
var uName;
$(function () {
while (uName == "" || uName == null) {
uName = prompt("Enter your name:", "");
}
$("#user").text(uName);
var tname = $("#user").text();
//--------------------提供服務器調用--------------------//
// Declare a proxy to reference the hub.
var chat = $.connection.paintHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastAnswer = function (data) {
$("#subject").text(data);
};
chat.client.broadcastHostName = function (data) {
if (tname != data) {
//猜的人
$("#subject").text('****(' + $("#subject").text().length + '個字)');
$('#myCanvas').css("display", "none");
$('#img1').css("display", "");
}
else {
//畫的人
$('#ans').css("display", "none");
$('#subAnswer').css("display", "none");
}
};
chat.client.getAllUser = function (data) {
$("#cntusers").text('');
var parsedJson = jQuery.parseJSON(data);
$.each(parsedJson, function (cnt, item) {
$("#cntusers").append("<div>" + item.Name + "</div>");
});
};
chat.client.broadcastMessage = function (imgData) {
// Add the message to the page.
$("#img1").attr("src", imgData);
$("#img1").css("display", "");
$("#myCanvas").css("display", "none");
};
chat.client.checkAnswer = function (data, name) {
if (data != "") {
alert('恭喜【' + name + '】猜中答案!');
location.reload()
}
else {
if (tname == name)
alert('很遺憾,你沒有猜中!');
}
};
//--------------------主動發送服務器---------------------//
// Start the connection.
$.connection.hub.start().done(function () {
//新增用戶
chat.server.addPeople(uName);
//獲取謎底
chat.server.getAnswer();
//獲取畫畫者
chat.server.getPeopleName();
//發送圖片
$('#sendmessage').click(function () {
// Call the Send method on the hub.
var c = document.getElementById("myCanvas");
var imgURI = c.toDataURL("image/jpg");
chat.server.send(imgURI);
});
//提交答案
$('#subAnswer').click(function () {
// Call the Send method on the hub.
var answer = $("#ans").val();
chat.server.checkAnswer(uName, answer);
});
});
ctx = document.getElementById('myCanvas').getContext("2d");
$('#myCanvas').mousedown(function (e) {
mousePressed = true;
Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false);
});
$('#myCanvas').mousemove(function (e) {
if (mousePressed) {
Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
}
});
$('#myCanvas').mouseup(function (e) {
mousePressed = false;
});
$('#myCanvas').mouseleave(function (e) {
mousePressed = false;
});
});
function Draw(x, y, isDown) {
if (isDown) {
ctx.beginPath();
ctx.strokeStyle = $('#selColor').val();
ctx.lineWidth = $('#selWidth').val();
ctx.lineJoin = "round";
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
lastX = x; lastY = y;
}
function clearArea() {
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
</script>
</body>
</html>
PaintHub.cs:
using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace SignalRTest
{
public class PaintHub : Hub
{
static List<User> users; //用戶集合
static string subjectName; //答案
static string hostName; //當前畫畫者
public PaintHub()
{
#region " 初始化 "
if (users == null)
{
users = new List<User>();
}
if (string.IsNullOrEmpty(subjectName))
{
subjectName = GetSubjectName();
}
if (string.IsNullOrEmpty(hostName) && users.Count > 0)
{
hostName = GetHostName();
}
#endregion
}
public void GetAnswer()
{
if (string.IsNullOrEmpty(subjectName))
{
subjectName = GetSubjectName();
}
Clients.All.broadcastAnswer(subjectName);
}
public void GetPeopleName()
{
var people = users.FirstOrDefault((p) => p.IsHost == true);
if (people != null)
{
Clients.All.broadcastHostName(people.Name);
}
}
public void Send(string message)
{
Clients.All.broadcastMessage(message);
}
public void AddPeople(string uname)
{
var user = users.FirstOrDefault((p) => p.Name == uname);
if (user == null)
{
User u = new User();
u.Name = uname;
u.IsHost = false;
users.Add(u);
}
string data = Newtonsoft.Json.JsonConvert.SerializeObject(users);
//int data = users.Count;
Clients.All.getAllUser(data);
}
public void CheckAnswer(string uname, string answer)
{
string data;
if (answer == subjectName)
{
data = "uname";
User host_new = users.FirstOrDefault((p) => p.Name == uname);
if (host_new != null)
{
//上次畫畫的人下次猜
User host_old = users.FirstOrDefault((p) => p.IsHost == true);
if (host_old != null)
{
host_old.IsHost = false;
}
//猜對的人下次畫
host_new.IsHost = true;
//重新獲取題目
subjectName = GetSubjectName();
}
}
else
{
data = "";
}
Clients.All.checkAnswer(data, uname);
}
private string GetSubjectName()
{
string[] arrSubject = new string[] { "鳥", "魚", "飛機", "熊貓", "老虎", "鱷魚", "馬" };
int index = new Random().Next(arrSubject.Length);
return arrSubject[index];
}
private string GetHostName()
{
int index = new Random().Next(users.Count);
users[index].IsHost = true;
return users[index].Name;
}
}
public class User
{
//名稱
public string Name
{
get; set;
}
//性別
public bool IsHost
{
get; set;
}
}
}
